整体思路是用链表来做的。
数据结构用下图表示。
注意事项:
在递归插入的时候,传递地址过去时要加上引用,否则遇到 } 无法将next指针设置成null,也就无法判断那一层的链表的结束位置,会产生错误。问题虽然很简单,但是在排查的时候不容易看见,浪费了几个小时。
具体实现请见代码。
# include<stdio.h>
# include<algorithm>
# include<string>
# include<sstream>
# include<iostream>
using namespace std;
typedef struct NODE {
string key;
string value;
struct NODE * next;
struct NODE * child;
}node, *pNode;
pNode init_p(void) {//初始化结点,并返回指针
pNode p = new node;
p->child = NULL;
p->key = "";
p->next = NULL;
p->value = "";
return p;
}
void miss(string &p) {
int pos = p.find("\\\\");
while (pos != string::npos) {
p.erase(p.begin() + pos);
pos = p.find("\\\\", pos + 1);
}
pos = p.find("\\\"");
while (pos != string::npos) {
p.erase(p.begin() + pos);
pos = p.find("\\\"", pos + 1);
}
}
void insert(stringstream &ss, pNode &p)
{//用来向链表中插入数据;
string key;
string value;
ss >> key;
if (key == "{") {
p->value = "OBJECT";
p->child = init_p();
insert(ss, p->child);
}
else if (key == "}") {
free(p);
p = NULL;
return;
}
else {
key.erase(key.begin());
key.erase(key.end() - 1);
miss(key);//清除//和/"前的/
p->key = key;
ss >> value;
if (value == "{") {
p->value = "OBJECT";
p->child = init_p();
insert(ss, p->child);
p->next = init_p();
insert(ss, p->next);
}
else {
value.erase(value.begin());
value.erase(value.end() - 1);
miss(value);
p->value = value;
p->next = init_p();
insert(ss, p->next);
}
}
}
string find(stringstream &ss, string &t, pNode p) {
string ans = "NOTEXIST";
for (; p != NULL; p = p->next) {
if (p->key == t) {
if (ss >> t)
ans = find(ss, t, p->child);
else
ans = p->value;
break;
}
}
return ans;
}
int main()
{
//freopen("data.txt", "r", stdin);
int n, m;
//建造链表头指针
pNode pHead = init_p();
cin >> n;
cin >> m;
getchar();
string str = "";
string temp;
for (int i = 0; i < n; i++) {//将所有字符读入一行中
getline(cin, temp);
str += temp + " ";
}
//将:和,变成空格 在{}前后加空格,保证输入字符串正确
str.erase(str.end() - 1);
int len = str.size();
for (int i = 0; i < len; i++) {
if (str[i] == ':' || str[i] == ',')
str[i] = ' ';
}
int pos_s = str.find("{");
while (pos_s != string::npos) {
str.replace(pos_s, 1, " { ");
pos_s = str.find("{", pos_s + 2);
}
pos_s = str.find("}");
while (pos_s != string::npos) {
str.replace(pos_s, 1, " } ");
pos_s = str.find("}", pos_s + 2);
}
//开始递归插入
stringstream ss;
ss.str(str);
insert(ss, pHead);
//将pHead指向第一个元素,并释放多余空间
ss.clear();
pNode temp_p = pHead;
pHead = pHead->child;
free(temp_p);
for (int i = 0; i < m; i++) {
getline(cin, temp);
int pos = temp.find(".");
while (pos != string::npos) {
temp[pos] = ' ';
pos = temp.find(".");
}
ss.str(temp);
string ans;
ss >> temp;
ans = find(ss, temp, pHead);
if (ans == "OBJECT" || ans == "NOTEXIST")
cout << ans << endl;
else
cout << "STRING " << ans << endl;
ss.clear();
}
return 0;
}