反片语

题目:《算法竞赛入门经典》刘汝佳    5-4   反片语  (ananagrams  ,UVa  156)P113

输入一些单词,找出满足如下条件的单词:该单词不能通过字母重排,得到文本中的另一个单词。在判断是否满足条件时,字母不分大小写,但在输出是应保留输入中的大小写,按字典序进行排序(所有大写字母在所有小写字母的前面)。

样例输入:

ladder came tape soon leader acme RIDE lone Dreis peat
ScAlE orb eye Rides dealer NotE derail LaCes drIed noel dire Disk mace Rob dries

样例输出:

Disk    NotE    derail    drIed    eye    ladder    soon

分析:

总体思想:将每个单词“标准化”,即全部转化成小写字母,再进行排序,然后放入map中进行统计。

具体步骤:1、读入一个单词的字符串,放入vector<string>words中;将单词的字符串按上述处理后放入map<string,int>cnt中。

                    2、将words数组中的单词取出,通过转化在map中查找,如果键值为1,说明这个单词为满足题目要求的单词。

                    3、将满足题目要求的单词放入两一个vector数组中,让其自动按照字典序进行升序排列。最后输出。

代码:

#include<iostream>
#include<string>
#include<cctype>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

map<string,int> cnt;
vector<string> words;

// 将单词s进行“标准化”
string repr(string s) {
  string ans = s;
  for(int i = 0; i < ans.length(); i++)
    ans[i] = tolower(ans[i]);
  sort(ans.begin(), ans.end());
  return ans;
}

int main() {
  int n = 0;
  string s;
  while(cin >> s) {
    if(s[0] == '#') break;
    words.push_back(s);
    string r = repr(s);
    if(!cnt.count(r)) cnt[r] = 0;
    cnt[r]++;
  }
  vector<string> ans;
  for(int i = 0; i < words.size(); i++)
    if(cnt[repr(words[i])] == 1) ans.push_back(words[i]);
  sort(ans.begin(), ans.end());
  for(int i = 0; i < ans.size(); i++)
    cout << ans[i] << "\n";
  return 0;
}

我嫌弃每次调试都需要输入,太麻烦,提前将字符串写好,然后进行处理。

逻辑和上面一样,但最后没有按照字典序输出。(字符串太长,输入换行用‘\’)

#include<iostream>
#include<string>
#include<sstream>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;

string trans(string *s)
{
	string ans=*s;
	int len=ans.length();
	int i;
	for(i=0;i<len;i++)
		ans[i]=tolower(ans[i]);
	sort(ans.begin(),ans.end());
	return ans;
}

int main()
{
	map<string,int>only;
	vector<string>words;
	//vector<int>flag;//用于标记words中独一无二的单词 
	string s="ladder came tape soon leader acme RIDE lone Dreis peat \
ScAlE orb eye Rides dealer NotE derail LaCes \
drIed noel dire Disk mace Rob dries";//太长换行输入 
	cout<<s<<endl<<endl;
	stringstream ss;
	ss<<s;
	string s1;
	while(ss>>s1)
	{
		words.push_back(s1);
		only[trans(&s1)]++;
	}
	int size=words.size();
	for(int i=0;i<size;i++)
	{
		if(only[trans(&words[i])]==1)
			cout<<words[i]<<"    ";
	}
} 

运行结果:

参考文章:

映射:map

向量Vector使用方法详解

ctype库的用法

sstream库函数用法详解

funny:1、map可以用来判断是否重复。

          2、为什么题目翻译成“反片语”?

                 anagrams:字谜游戏(由颠倒字母顺序而构成的字[短语]( anagram的名词复数 ))

猜你喜欢

转载自blog.csdn.net/sinat_38816924/article/details/82814145