本题只需要用map创建新旧字典,用set保存新增、删除和修改的元素后输出就好了。易错点是需要在每一个测试用例之后输出一个空行。
比较疑惑的地方是在创建map时,如果采用substr截取key和value就会报WA,采用符号换空格再用字符串流输入的话就会AC,看了半天没弄清楚原因。。。
题目链接:UVa 12504
AC代码:
#include <iostream>
#include <sstream>
#include <map>
#include <set>
using namespace std;
set<string> inc, del, cha;
void create(string s, map<string, string>& k_v) { //创建新旧字典的键集合以及键值对的映射
for (auto& p : s)
if (p == '{' || p == '}' || p == ',' || p == ':')
p = ' ';
stringstream ss(s);
string key, value;
while (ss >> key >> value)
k_v[key] = value;
}
void is_change(map<string, string>& a, map<string, string>& b) {
map<string, string>::iterator it;
for (it = b.begin(); it != b.end(); it++) {
if (!a.count((*it).first))
inc.insert((*it).first); //若在新字典中出现但旧字典没有,说明是新增的内容
else if (a[(*it).first] != b[(*it).first])
cha.insert((*it).first); //若新旧字典中都出现但值不同,说明是被修改的内容
}
for (it = a.begin(); it != a.end(); it++)
if (!b.count((*it).first))
del.insert((*it).first); //若在旧字典中出现但新字典没有,说明是被删除的内容
}
void print(char ch, set<string>& s) {
set<string>::iterator it;
if (s.empty())
return;
for (it = s.begin(); it != s.end(); it++) {
if (it == s.begin())
cout << ch << *it;
else
cout << "," << *it;
}
cout << endl;
}
int main() {
int T;
cin >> T;
while (T--) {
string olddic, newdic;
map<string, string> mpo, mpn;
inc.clear(); del.clear(); cha.clear();
cin >> olddic >> newdic;
create(olddic, mpo);
create(newdic, mpn);
is_change(mpo,mpn);
print('+',inc);
print('-',del);
print('*',cha);
if (inc.empty() && del.empty() && cha.empty())
cout << "No changes" << endl;
cout << endl;
}
return 0;
}
另一份代码的WA部分(其余部分和AC代码相同):
void create(string s, map<string, string>& k_v) { //创建新旧字典的键集合以及键值对的映射
int end = s.find('}', 0);
int m = 0, n = 0;
string key, value;
while (true) {
m = s.find(':', n);
key = s.substr(n + 1, m - n - 1);
n = s.find(',', m);
if (n == string::npos) {
value = s.substr(m + 1, end - m - 1);
k_v[key] = value;
break;
}
value = s.substr(m + 1, n - m - 1);
k_v[key] = value;
}
}
emmmm,真的感觉没差
uDebug过后发现问题了。。
问题在于空字典进入此函数后会把后半部分的括号"}"存进去,修改为以下代码后成功AC:
void create(string s, map<string, string>& k_v) { //创建新旧字典的键集合以及键值对的映射
int end = s.find('}', 0);
int m = 0, n = 0;
string key, value;
m = s.find(':', n);
while (m!=string::npos) {
m = s.find(':', n);
key = s.substr(n + 1, m - n - 1);
n = s.find(',', m);
if (n == string::npos) {
value = s.substr(m + 1, end - m - 1);
k_v[key] = value;
break;
}
value = s.substr(m + 1, n - m - 1);
k_v[key] = value;
}
}