0
点赞
收藏
分享

微信扫一扫

算法刷题记录(DAY 19)

大南瓜鸭 2022-03-12 阅读 64

JSON查询(csp 201709-3)

原题链接
解题思路:使用json结构式进行存储,每次只要一遇到{就调用read_json来处理,从而实现了object类型的自动识别与切换
使用map的时候
在这里插入图片描述

#include<iostream>
#include<map>
#include<string>
using namespace std;
int n, m;
//typedef struct json json;
struct json {
	string s;
	map<string, struct json> xj;
};

map<string, struct json> J;

void read_json(map<string, struct json>& j) {
	char c = getchar();
	while (c != '}') {
		if (c == '\"') {//注意转义
			string key;
			while ((c = getchar()) != '\"') {
				//处理题目给出的转义
				if (c == '\\') {
					c = getchar();
					if (c == '\\') key += '\\';
					else if (c == '\"') key += '\"';
				}
				else key += c;
			}

			while ((c = getchar()) != '{' && c != '\"');
			if (c == '{') read_json(j[key].xj);
			else {
				string value;
				while ((c = getchar()) != '\"') {
					//处理题目给出的转义
					if (c == '\\') {
						c = getchar();
						if (c == '\\') value += '\\';
						else if (c == '\"') value += '\"';
					}
					else value += c;
				}
				j[key].s = value;
				c = getchar();//读取下面的字符
			}
		}
		else c = getchar();
	}

}
int main() {
	int x;
	cin >> n >> m;
	getchar();
	getchar();//读左括号
	read_json(J);
	getchar();//读掉换行符
	for (int i = 0; i < m; i++) {
		char c;
		string q;
		map<string, struct json> cj = J;
		while ((c = getchar()) != '\n') {
			if (c == '.') {
				if (cj.find(q) == cj.end()) {
					cout << "NOTEXIST" << endl;
					while ((c = getchar()) != '\n'); //读掉剩余的内容
					goto WA;
				}
				else {
					//cj = cj[q].xj; //注意这里不能随意赋值
					map<string, json> yj = cj[q].xj;
					cj = yj;
					q.clear();
				}
			}
			else q += c;
		}
		if (cj.find(q) == cj.end()) cout << "NOTEXIST" << endl;
		else {
			if ((cj[q].xj).size() != 0) cout << "OBJECT" << endl;
			else cout << "STRING " << cj[q].s << endl;
		}
	WA: x = 0;
	}
}

以下记录一件怪事:
当使用unordered_map的时候,会报错,而使用map没有
在这里插入图片描述
在这里插入图片描述
由此,我继续深入地去查forward declaration,以为是因为结构体中自己调用自己的原因。于是我将结构体进行如下的修改
在这里插入图片描述
那么每次我都需要malloc一个新的结构体,但是我发现若使用.size得到的大小巨大,与sizeof得到的结果完全不同。
在这里插入图片描述
更一般地,进行了如下的试验
在这里插入图片描述
但是当我直接进行如下使用时,却是正确的。
在这里插入图片描述
由此,得到下面的两个结论:
1.map和unordered_map在结构体的使用中,存在差异,具体体现在编译是否通过方面(本地VS2019都可以使用,但是在OJ上后者不可以)
2.在指针方面,两者都不可以!!!(why)map和unordered_map的实现机制是什么,malloc的时候分配的内存的大小是多少
3.struct结构体中,我们都知道不可以包括自身(标红的地方),但是为什么在map中却可以呢?

在这里插入图片描述

//调试代码

#include<iostream>
#include<unordered_map>
#include<string>
#include<map>
using namespace std;
int n, m;
//typedef struct json json;
struct json {
	char s[100];
	unordered_map<string, struct json*>  xj;
};
struct test {
	map<int, int > t1;
};
unordered_map<string, struct json*> J;

void read_json(unordered_map<string, struct json*>& j) {
	//cout << j.size() << endl;
	char c = getchar();
	while (c != '}') {
		if (c == '\"') {//注意转义
			string key;
			while ((c = getchar()) != '\"') {
				//处理题目给出的转义
				if (c == '\\') {
					c = getchar();
					if (c == '\\') key += '\\';
					else if (c == '\"') key += '\"';
				}
				else key += c;
			}
			cout << sizeof(struct json) << endl;
			j[key] = (struct json*)malloc(sizeof(struct json));
			cout << sizeof(j[key]) << endl;
			cout << ((j[key])->xj).size() << endl;
			cout << sizeof((j[key])->xj) << endl;
			if (j[key] == NULL) {
				cout << "WA" << endl;
			}
			while ((c = getchar()) != '{' && c != '\"');
			if (c == '{') read_json((j[key])->xj);
			else {
				string value;
				while ((c = getchar()) != '\"') {
					//处理题目给出的转义
					if (c == '\\') {
						c = getchar();
						if (c == '\\') value += '\\';
						else if (c == '\"') value += '\"';
					}
					else value += c;
				}

				//j[key]->s = value;
				for (int i = 0; i < value.size(); i++) j[key]->s[i] = value[i];

				c = getchar();//读取下面的字符
			}
		}
		else c = getchar();
	}

}
int main() {
	struct test {
		map<int, int > t1;
	};
	struct test* a = (struct test*)malloc(sizeof(struct test));
	struct test b;
	b.t1[1] = 2;
	if (a != NULL) {
		a->t1[1] = 2;
	}
	int x;
	cin >> n >> m;
	getchar();
	getchar();//读左括号
	read_json(J);
	getchar();//读掉换行符
	for (int i = 0; i < m; i++) {
		char c;
		string q;
		unordered_map<string, struct json*> cj = J;
		while ((c = getchar()) != '\n') {
			if (c == '.') {
				if (cj.find(q) == cj.end()) {
					cout << "NOTEXIST" << endl;
					while ((c = getchar()) != '\n'); //读掉剩余的内容
					goto WA;
				}
				else {
					//cj = cj[q].xj; //注意这里不能随意赋值
					unordered_map<string, struct json*> yj = cj[q]->xj;
					cj = yj;
					q.clear();
				}
			}
			else q += c;
		}
		if (cj.find(q) == cj.end()) cout << "NOTEXIST" << endl;
		else {
			if ((cj[q]->xj).size() != 0) cout << "OBJECT" << endl;
			else cout << "STRING " << cj[q]->s << endl;
		}
	WA: x = 0;
	}
}

公共钥匙盒(csp 201709-3)

原题链接
题目类型:模拟

解题思路:使用set数组来将还和借的动作进行排序,以借动作为主线,在借之前,都需遍历还动作,还完后,借动作会产生一个还动作。

#include<iostream>
#include<set>
#include<cstring>
using namespace std;
#define NMAX 1010
set<pair<pair<int, int>, int> > a;
set<pair<int, int> > b;
set<int > e;
int c[NMAX];
int d[NMAX];
int N, K;
int main() {
	cin >> N >> K;
	//memset(status, 0, sizeof(status));
	for (int i = 1; i <= N; i++) c[i] = i, d[i] = i;
	for (int i = 0; i < K; i++) {
		int n, s, t;
		cin >> n >> s >> t;
		a.insert(make_pair(make_pair(s, n), t));
	}

	set<pair<pair<int, int>, int> >::iterator it1 = a.begin();
	for (; it1 != a.end(); it1++) {
		set<pair<int, int> >::iterator it2 = b.begin();
		for (; it2 != b.end() && (*it2).first<=(*it1).first.first; ) {
			set<int >::iterator it3 = e.begin();
			int pos = *it3;
			e.erase(it3);
			c[pos] = (*it2).second;
			d[(*it2).second] = pos;
			b.erase(it2++);
		}
		
		e.insert(d[(*it1).first.second]);
		b.insert(make_pair((*it1).first.first + (*it1).second, (*it1).first.second));
	}

	//处理完剩下的
	set<pair<int, int> >::iterator it2 = b.begin();
	for (; it2 != b.end() ; ) {
		set<int >::iterator it3 = e.begin();
		int pos = *it3;
		e.erase(it3);
		c[pos] = (*it2).second;
		d[(*it2).second] = pos;
		b.erase(it2++);
	}

	cout << c[1];
	for (int i = 2; i <= N; i++) cout << " " << c[i];
	cout << endl;
}

小结

今天最大的收获是发现自己对于常用的容器的实现原理等一无所知,甚至忘记了大一C语言课上关于变量与内存的理解;同时,由于一直在使用C++,但我没有去系统学习过一些关于类的知识,导致有些理解欠缺,因此找个时间补一下。

举报

相关推荐

0 条评论