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++,但我没有去系统学习过一些关于类的知识,导致有些理解欠缺,因此找个时间补一下。