摘要:给定一个大写的字符串,如果该字符串能够通过某种置换以及排列成为另外一个字符串,则称第二个是第一个字符串的加密.比如第二个字符串会通过每一个单词变到字母表中的下一个单词(这种变换每个单词都不一样,不同的单词不能变到同一个单词)然后相互交换位置成为第一个字符串.
JWPUDJSTVP
VICTORIOUS
基本思路:本题思路不难,但是很容易做错,我足足调了两个多小时.一定要理解清楚题目的意思:J可以变成W(字母表中的下一个),但是不一定会变成W,可以是任何一个字母,也可以是本身.这是非常容易搞错的.想清楚这个就很简单了,相同的单词一定会变成另外相同的单词,经过排列只是位置变了,但是频率不变.因此两个字符串的频率一致就是关键.可以采用一个数组记录频率,然后将数组进行排序,在比较两个数组是否完全一致.这是常规做法.这是O(NLogN)的效率.
还有一种做法是再次记录频率,这次记录第一次频率出现的频率,比如第一次有5个不同的字母,表现在记录上就是由5个A[x] = 1;表现在第二次的记录上就是B[1] = 5;它表示有5个不同的字母.B[index] = m表示存在{index个字母}{index个字母}{index个字母}…{index个字母}一共m个集合.这样也可以判断频率的分布.这里需要注意的是由可能有同一个字母出现100次,所以第二个记录的数组要求空间很大,这种方法的算法效率是O(N),但是空间要求更多,而且在N较小时由于读入数据初始化等原因可能消耗远多于第一种的时间.
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int i = 0;
bool ispossible = true;//标记最后结果
char s1[101] = {'0'},s2[101] = {'0'};
int count1[26] = {0},count2[26] = {0};//用来作为统计两个字符串的字母数量
int count3[101] = {0},count4[101] = {0};
i = 0;
cin>>s1;
cin>>s2;
while(s2[i]!='\0'&&s1[i]!='\0')
{
count1[int(s1[i])-'A']++;
count2[int(s2[i])-'A']++;
i++;
}
if(s1[i]!=s2[i])
ispossible = false;
else
{
for(i = 0;i<=25;)
{
count3[count1[i]]++;
count4[count2[i]]++;
i++;
}
for(i = 1;i<=100;i++)
{
if(count3[i] != count4[i])
{
ispossible = false;
break;
}
}
}
if(ispossible)
cout<<"YES\n";
else
cout<<"NO\n";
return 0;
}