Ananagrams(STL模板:map,set,vector的使用)

Most crossword puzzle fans are used to anagrams--groups of words with the same letters in different orders--for example OPTS, SPOT, STOP, POTS and POST. Some words however do not have this attribute, no matter how you rearrange their letters, you cannot form another word. Such words are called ananagrams, an example is QUIZ.

Obviously such definitions depend on the domain within which we are working; you might think that ATHENE is an ananagram, whereas any chemist would quickly produce ETHANE. One possible domain would be the entire English language, but this could lead to some problems. One could restrict the domain to, say, Music, in which case SCALE becomes a relative ananagram (LACES is not in the same domain) but NOTE is not since it can produce TONE.

Write a program that will read in the dictionary of a restricted domain and determine the relative ananagrams. Note that single letter words are, ipso facto, relative ananagrams since they cannot be ``rearranged'' at all. The dictionary will contain no more than 1000 words.

Input

Input will consist of a series of lines. No line will be more than 80 characters long, but may contain any number of words. Words consist of up to 20 upper and/or lower case letters, and will not be broken across lines. Spaces may appear freely around words, and at least one space separates multiple words on the same line. Note that words that contain the same letters but of differing case are considered to be anagrams of each other, thus tIeD and EdiT are anagrams. The file will be terminated by a line consisting of a single #.

Output

Output will consist of a series of lines. Each line will consist of a single word that is a relative ananagram in the input dictionary. Words must be output in lexicographic (case-sensitive) order. There will always be at least one relative ananagram.

Sample Input

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
#

Sample Output

Disk
NotE
derail
drIed
eye
ladder
soon

题意:对于指定的一段话(有多个单词组成),定义Ananagrams为那些将单词中每个字母重新排列后得到的所有新单词在指定的这段话中也没有出现的(不区分大小写:大写和小写字母视为相同字母),将符合该要求的所有单词按字典序(大写优先)依次输出。

思路:这个题主要是STL模板中map,set,vector的综合使用,首先要处理所有单词,将其标准化(每个字母用tolower函数转化为小写后按字典序排序),因为对于可以经过重新排列可以转化为相同单词的两个单词这样处理后得到的结果是一样的,也就是说判断一个串是不是另一个串重新排列后的结果之一,只需要将两个串都排一下序,然后看结果是否相同就行了,这样只需要用一个map来保存原单词到标准化后的单词的一个映射,另一个map来保存标准化后得到的单词到其出现的次数的映射,就可以知道当前单词标准化后出现的次数了,只出现一次的则满足要求,就把其放入set中,用set自动排序,因为STL中默认的排序就是按字典序(大写优先),所以最后依次将set中的串输出即可。

完整代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
map<string,string>mp;//mp保存原单词到标准化后的单词的一个映射
map<string,int>mm;//mm保存标准化后得到的单词到其出现的次数的映射
set<string>st;//利用set对找出的所有符合要求的串自动按要求排序
vector<string>v;//用vector来保存初始的所有单词,以便后续查找
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    string s;
    while(cin>>s&&s!="#")
    {
        v.push_back(s);//用vector来保存初始的所有单词,以便后续查找
        string ss=s;
        for(int i=0;i<s.size();i++)
        {
            s[i]=tolower(s[i]);//将每个字母转化为小写,!注意这里等号左右的s[i]应该是相同的,就是说tolower只能在原串本自身操作!(一开始转换到别的串中,结果发生了错误)
        }
        sort(s.begin(),s.end());//排序
        mp[ss]=s;
        mm[s]++;
    }
    vector<string>::iterator it;
    for(it=v.begin();it!=v.end();it++)
    {
        int num=mm[mp[*it]];//用num来得到原单词(*it)对应的标准化后的单词(mp[*it])出现的次数mm[mp[*it]]
        if(num==1){
            st.insert(*it);//只出现一次的则满足要求,就把其放入set中
        }
    }
    set<string>::iterator t;//注意这里迭代器不能再用it了,对一个新的容器遍历要用新的名称的迭代器
    for(t=st.begin();t!=st.end();t++)
        cout<<*t<<endl;
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值