CCF CSP 201709-3 满分AC

整体思路是用链表来做的。
数据结构用下图表示。
注意事项:
在递归插入的时候,传递地址过去时要加上引用,否则遇到 } 无法将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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值