紫书刷题进行中,题解系列【GitHub|CSDN】
习题5-11 UVA12504 Updating a Dictionary(37行AC代码)
题目大意
给新旧字典(键值对形式),按字典序输出增加,删除,修改的键值
思路分析
定义如下数据结构,分别表示旧,新字典,因为值可能非常大,所以也用string存储
map<string,string> mpa, mpb; // 旧新字典
接着定义set<string> del, chg, inc;
分别表示删除,改变,增加的集合,其自动按字典序排列,因此结束后可直接输出,其伪代码如下:
for 枚举mpa中的每个元素p{
if p.key不存在于mpb{
将p.key加入删除集合
}
else {
if p.value 不同于mpb中的value {
将p.ley加入改变集合
}
删除mpb中的p.key // 剩余的即为增加的
}
}
注意点
- 每一个测试用例后均输出空行,包括最后一个
AC代码(C++11,map)
#include<bits/stdc++.h>
using namespace std;
int T;
string sa, sb;
void getDict(map<string,string>& mp, string s) { // 分割得到字典
for (auto& ch : s) // 将{},:替换为空格
if (ch == '{' || ch == '}' || ch == ',' || ch == ':') ch = ' ';
stringstream input(s);
string sk, sv;
while (input >>sk >>sv ) mp[sk] = sv; // stringstream以空格分割
}
void print(char mess, const set<string>& _set) { // 打印结果
if (_set.empty()) return; // 空立刻返回
cout <<mess;
for (auto p : _set) printf("%s%s", p.c_str(), p == *_set.rbegin() ? "\n" : ",");
}
int main() {
cin >>T;
for (int i = 0; i < T; i ++) {
cin >>sa >>sb;
map<string,string> mpa, mpb; // 旧新字典
getDict(mpa, sa); getDict(mpb, sb);
set<string> del, chg, inc; // 删除,改变,增加
for (auto p : mpa) { // 遍历旧字典
if (mpb.find(p.first) == mpb.end()) del.insert(p.first); // 删除
else { // 存在
if (mpa[p.first] != mpb[p.first]) chg.insert(p.first); // 改变
mpb.erase(p.first); // 删除mpa中存在的
}
}
for (auto p : mpb) inc.insert(p.first); // 未被删除的就是增加的
print('+', inc); print('-', del); print('*', chg); // 输出结果
if (inc.empty() && del.empty() && chg.empty()) puts("No changes");
puts(""); // 空行
}
return 0;
}