UVA 156 Ananagrams 關於二維數組表示的字符串排序的問題

題目鏈接:UVA 156 Ananagrams

 Ananagrams 

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

題意

    一個單詞,任意調換字母的次序,即字母重新排列後,能夠在字典裏面找到相同的形式(不區分大小寫),說明它是可以調換的。現在你要找到那些調換之後找不到相同相同形式的那些單詞,然後按字典序排列輸出來。

分析

    題目不難,但主要的問題是字符串的處理。其實也不用找每個單詞的重排列,只要將每個的單詞中的字母先都轉化爲大小寫一致的形式然後按升序或降序排列,再一個一個比較是否相等,如果相等,則說明能找到,這兩個都標記爲true,若都不相等,說明找不到,那麼這個就是false,也就是我們要找的單詞,注意輸出的是單詞的原來形式。其實關鍵的問題在於字符串排序,如果用string來處理的話是很簡單的,但是如果用二維字符數組加sort函數的話,就會出現問題,如果單純的用dic[][]來存儲並排序則會報錯,但是用*dic[]來存儲的話卻沒有問題,這可能跟sort函數的原型有關。

代碼

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

bool cmp1(char a, char b)
{
    return a < b;
}
bool judge(char a[], char b[])
{
    if(strlen(a) != strlen(b)) return false;
    int len = strlen(a);
    char aa[1010], bb[1010];
    strcpy(aa, a);
    strcpy(bb, b);
    for(int i = 0; i < len; i++)
    {
        if(aa[i] >= 'A' && a[i] <= 'Z')
            aa[i] += 'a'-'A';
        if(b[i] >= 'A' && b[i] <= 'Z')
            bb[i] += 'a'-'A';
    }
    sort(aa, aa+len, cmp1);
    sort(bb, bb+len, cmp1);
    if(strcmp(aa, bb) == 0) return true;
    return false;
}
bool cmp2(char* a, char* b)
{
    return strcmp(a, b) < 0;
}
int main()
{
    int n = 0, cnt;
    char str[1010][30];
    char *dic2[30];
    bool vis[1010];
    while(scanf("%s", str[n++]))
        if(str[n-1][0] == '#') break;
    n--;
    memset(vis, false, sizeof(vis));
    cnt = 0;
    for(int i = 0; i < n; i++)
    {
        if(!vis[i])
            for(int j = i+1; j < n; j++)
                if(judge(str[i], str[j]))
                    vis[i] = vis[j] = true;
        if(!vis[i])
            dic2[cnt++] = str[i];
    }
    sort(dic2, dic2+cnt, cmp2);
    for(int i = 0; i < cnt; i++)
        printf("%s\n", dic2[i]);
    return 0;
}




發佈了67 篇原創文章 · 獲贊 27 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章