Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 如何证明两个字符串是彼此的置换?_String_Algorithm_Char_Ascii_Permutation - Fatal编程技术网

String 如何证明两个字符串是彼此的置换?

String 如何证明两个字符串是彼此的置换?,string,algorithm,char,ascii,permutation,String,Algorithm,Char,Ascii,Permutation,我正在破解代码采访书,在数组和字符串一章中遇到了一个问题,他们要求编写一个方法,证明作为输入的两个字符串是彼此的排列 书中的答案非常清晰明了。一个是排序,然后比较它们是否相同,另一个是检查两个字符串是否具有相同的字符计数 然而,对于这个问题,我有一个不同的方法,我想和你们分享一下,看看你们的意见 我假设这些字符是ASCII字符。 所以我想首先检查两个字符串的长度是否相等,如果不是,我们直接返回false,因为它显然反对排列的定义 如果是这样的话,我们继续使用算法。首先,我们初始化: int su

我正在破解代码采访书,在数组和字符串一章中遇到了一个问题,他们要求编写一个方法,证明作为输入的两个字符串是彼此的排列

书中的答案非常清晰明了。一个是排序,然后比较它们是否相同,另一个是检查两个字符串是否具有相同的字符计数

然而,对于这个问题,我有一个不同的方法,我想和你们分享一下,看看你们的意见

我假设这些字符是ASCII字符。 所以我想首先检查两个字符串的长度是否相等,如果不是,我们直接返回false,因为它显然反对排列的定义

如果是这样的话,我们继续使用算法。首先,我们初始化:

int sum = 0;
int sum1 = 0;
然后我们遍历每个字符串的字符,将每个字符的ASCII值添加到和中,最后比较和。如果它们相等,我们就得到了一个排列


这种方法有效吗?

不,它无效,因为
12
既是
2
10
之和,也是
3
9
之和

在您的算法中,
“ad”
将是
“bc”
的排列

在一般情况下,如果允许字符和字符串长度的合理范围,就没有真正的快捷方式。在你提到的两种方法中,最好的解决方案取决于语言

dystroy是对的

要使其以99.999%的正确率工作(按照您的方法),您需要计算:

sum1 = sum (ASCII(i))
sum2 = sum (ASCII(i)^2)
sum3 = sum (ASCII(i)^3)
  • 对于两个字符串,如果所有相同的幂和相同
  • 然后你有了最有可能的置换字符串

要确保比较直方图(如您在问题中提到的),但这需要更多的内存…

这无法使用总和来实现,因为数字没有唯一的总和因子(如前面的答案所述)

这可以通过比较字符直方图来实现

代码Java

类字符\u直方图
{
公共地图直方图;
公共字符直方图()
{
直方图=新树形图();
}
公共作废计数(字符c)
{
if(柱状图,包含(c))
直方图.put(c,直方图.get(c)+1);
其他的
直方图。put(c,1);
}
公共无效计数(字符串str)
{
for(字符c:str.toCharArray())
计数(新字符(c));
}
}

你的方法行不通,因为求和会有很多冲突,基本上你假设的是5+3=8,没有其他组合会产生8,但你错了示例4+4也是8

有很多特别的方法可以解决这个问题,我将描述其中的两种。 您可以使用质数来解决问题,方法类似于您的方法,或者只需分配2个数组并记录字符

1。您可以初始化2个大小为27的整数数组,每个数组都称为list1[27]和list2[27],初始化为0,逐个字符读取这两个字符串,如果从字符串1中读取“c”,则,递增列表1的第三个元素,因为“c”是第三个字符,依此类推,当您读取完两个字符串时,扫描两个数组是否不匹配,如果存在任何不匹配,它们不是彼此的排列

可能的实现是

char str1[50]="permutation";
char str2[50]="importunate";

int list1[27]={0},list2[27]={0};


for(int i=0;i<11;i++){
    list1[(int)str1[i]-(int)'a'+1]++;
    list2[(int)str2[i]-(int)'a'+1]++;
}

for(int i=0;i<=27;i++){
    if(i==27){
        return true;
    }
    if(list1[i]!=list2[i])
    {
        return false;
    }
}

那太快了,谢谢,还有13分钟我给你一张绿色支票,还有其他的方法。您可以简单地按字典顺序对字符串排序,并按字符进行比较。另一种方法是找到两个字符串的每个字符的频率,然后比较它们。问题是是否可以使用sum进行比较。没有找到另一种方法来比较,顺便说一句,他已经声明他知道如何计算(直方图=唯一字符数)
char str1[50]="permutation";
char str2[50]="importunate";

int list1[27]={0},list2[27]={0};


for(int i=0;i<11;i++){
    list1[(int)str1[i]-(int)'a'+1]++;
    list2[(int)str2[i]-(int)'a'+1]++;
}

for(int i=0;i<=27;i++){
    if(i==27){
        return true;
    }
    if(list1[i]!=list2[i])
    {
        return false;
    }
}
int arr[27]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103};
char str1[50]="permutation";
char str2[50]="importunate";

int prd1=1,prd2=1;


for(int i=0;i<11;i++){
    prd1=prd1*arr[(int)str1[i]-(int)'a'];
    prd2=prd2*arr[(int)str2[i]-(int)'a'];
}

if(prd1==prd2)
    return true;

else
    return false;
prd1=prd1*arr[(int)str1[i]-(int)'a']%1000000009;
prd2=prd2*arr[(int)str2[i]-(int)'a']%1000000009;//or some other large prime number