题目:给定两个长度相同且不超过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;
}