UVa12504 习题5-11 更新字典 (Updating a Dictionary)

原题链接:UVA-12504

题目大意:

 有两本字典,第一行是旧字典,第二行是新字典。每行不超过100个字符,没有空格,两本字典都可以是空的;对两个 

新增key:+ 
缺少key:- 
值变 :* 

无改变:No changes

感悟:

 本题的主要重点集中在提取字符串中的key和value,和新旧字典的比较以及输出。

 在提取字符串时使用了find定位':'和',',然后找相应的位置使用substr函数截取字符串。

 字典比较时使用了两个map和两个vector,map用来映射新旧字典的key和value,vector用来存储key。然后遍历vector中的key来判断是否增加或者减少,若新旧字典中都存在再比较value值是否相等。

 由于题目不是很复杂所以测试之后,一次就AC了。但是写完再看别人的代码时候发现自己有些地方弄得太过复杂,比如字符串的提取,和之后新旧字典对比(基本上就是全部的内容了 _(:3 」∠)_ )。代码量比人家的多一倍,很无奈啊(手动摊手)。不过刚入门,以后还有提高的机会,所以加油 <(▰˘◡˘▰)>

代码:

#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<algorithm> 

#define local

using namespace std;

void prer(string s, int is_old);
void judge();
void inti();
void print();
void show(string op,int num);

map<string, string> old_dic;
map<string, string> new_dic;
map<string, int> chgd_key;
map<int, int> chgd_num;
vector<string> old_key;
vector<string> new_key;
int ifchg;

int main()
{
#ifdef local
	//freopen("input.txt", "r", stdin);
	//freopen("output.tet","w",stdout);
#endif
	int n;
	cin >> n;
	getchar();
	while (n--)
	{
		inti();
		string s;
		getline(cin, s);
		prer(s, 1);
		getline(cin, s);
		prer(s, 0);
		sort(old_key.begin(), old_key.end());
		sort(new_key.begin(), new_key.end());
		judge();
		print();
		cout << endl;
	}
	return 0;
}

void print()
{
	if (chgd_num[1] > 0) show("+",1);
	if (chgd_num[2] > 0) show("-",2);
	if (chgd_num[3] > 0) show("*",3);
	if (!ifchg)
		cout << "No changes" << endl;
}

void show(string op,int num)
{
	cout << op;
	for (map<string, int>::iterator it = chgd_key.begin(); it != chgd_key.end(); it++)
	{
		if (it->second == num)
		{
			cout << it->first;
			chgd_num[num]--;
			ifchg = 1;
			if (chgd_num[num])
			cout << ",";
			else
			break;
		}
	}
	cout << endl;
}

void judge()
{
	int o = 0, n = 0;
	while (o<old_key.size() && n < new_key.size())
	{
		if (old_key[o] == new_key[n])
		{
			if (old_dic[old_key[o]] != new_dic[new_key[n]])
			{
				chgd_key[old_key[o]] = 3;
				chgd_num[3]++;
			}
			o++; n++;
		}
		else if (old_key[o] < new_key[n])
		{
			chgd_key[old_key[o]] = 2;
			chgd_num[2]++;
			o++;
		}
		else if (old_key[o] > new_key[n])
		{
			chgd_key[new_key[n]] = 1;
			chgd_num[1]++;
			n++;
		}
	}
	while (o<old_key.size())
	{
		chgd_key[old_key[o]] = 2;
		chgd_num[2]++;
		o++;
	}
	while (n < new_key.size())
	{
		chgd_key[new_key[n]] = 1;
		chgd_num[1]++;
		n++;
	}
}

void prer(string s, int is_old)
{
	int pos1 = 0, pos2 = 0;
	string key, value;
	while (s.find(':', pos1 + 1) != s.npos)//定位并获取字符串key和value 
	{
		pos1 = s.find(':', pos1 + 1);
		key = s.substr(pos2 + 1, pos1 - pos2 - 1);
		if (s.find(',', pos2 + 1) == s.npos)
			pos2 = s.length()-1;
		else
			pos2 = s.find(',', pos2 + 1);
		value = s.substr(pos1 + 1, pos2 - pos1 - 1);
		if (is_old)
		{
			old_key.push_back(key);
			old_dic[key] = value;
		}
		else
		{
			new_key.push_back(key);
			new_dic[key] = value;
		}
	}
}

void inti()
{
	ifchg = 0;
	old_dic.clear();
	new_dic.clear();
	chgd_key.clear();
	chgd_num.clear();
	old_key.clear();
	new_key.clear();
	for (int i = 0; i <= 3; i++)
	{
		chgd_num[i] = 0;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值