题目:给定两个长度相同且不超过100的字符串,判断是否能把其中一个字符串的各个字母重排,然后对26个字母做一个一一映射,使得两个字符串相同。例如,JWPUDJSTVP重排后可以得到WJDUPSJPVT,然后把每个字母映射到它前一个字母(B->A, C->B, ..., Z->Y, A->Z),得到VICTORIOUS。输入两个字符串,输出YES或者NO。
分析:(这里只考虑str1作为待转换字符串和str2目标字符串(也可以两者角色不同),数组分为cnt1和cnt2)由于字母可以排序,我们就可以不用考虑字母的顺序。直接比较两个字符串各个字母出现的个数。将两个字符串进行排序后,用数组保存每个字母出现的次数。然后对两个数组进行比较。由于str1映射到str2,所以,在cnt1[1]与cnt2[0]比较,后面依次比较。
代码如下:
#include <stdio.h> #include <string.h> // 对字符串进行排序 void sortStr(char str[]) { int i, j; char ch; for (i=0; i<strlen(str)-1; i++) { for (j=0; j<strlen(str)-i-1; j++) { if (str[j]>str[j+1]) { ch = str[j]; str[j] = str[j+1]; str[j+1] = ch; } } } } // 计算字母出现的次数 void calculate(int cnt[], char str[]) { int i; for (i=0; i<strlen(str); i++) cnt[str[i]-65]++; } // 判断是否可以转换 int judge(int cnt1[], int cnt2[]) { int i, j, flag = 0; // cnt1[1]与cnt2[0]比较,后面依次比较 for (i=0, j=1; i<26; i++, j++) { if (j == 26) j = 0; if (cnt1[j] == cnt2[i]) flag++; } if (flag == 26) return 1; // 当flag=26,代表可以转换 return 0; } int main() { char str1[100], str2[100]; int cnt1[26] = {0}, cnt2[26] = {0}; gets(str1); gets(str2); sortStr(str1); sortStr(str2); calculate(cnt1, str1); calculate(cnt2, str2); if (judge(cnt1, cnt2)) printf("Yes\n"); else printf("No\n"); return 0; }