为什么此字谜代码仅针对 ravi 和 vira 没有给出正确的结果?

Why this code for anagram is not giving correct result only for ravi & vira?

在这个程序中,我试图通过将字符串作为整数来按它们的 ASCII 值对字符串进行排序。然后将它们按升序排序并检查它们是否具有相同的元素集

#include<iostream>
#include<string.h>
using namespace std;

int len(int a[]){
    int l=0;
    for(int i=0; a[i]!='[=10=]'; i++)
        l++;
    return l;    
}
int len_str(string a){
    int l=0;
    for(int i=0; a[i]!='[=10=]'; i++)
        l++;
    return l;    
}
void asc_order(int a[]){
    int n=len(a), temp=0;
    for(int i=0; i<n ; i++)
        for(int j=0; j<n; j++)
            if(a[i]<a[j]){
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
}

int main(){
    system("cls");
    string str1, str2;
    cout<<"Enter the first string  : ";
    getline(cin, str1);
    cout<<"Enter the second string : ";
    getline(cin, str2);
    string res = "YES";
    if(len_str(str1)==len_str(str2)){
        int n = len_str(str1);
        int ch1[n], ch2[n];
        for(int i=0; i<n; i++){
            ch1[i] = str1[i];
            ch2[i] = str2[i];
        }
        asc_order(ch1);
        asc_order(ch2);
        for(int i=0; i<n; i++)
            if(ch1[i]!=ch2[i])
                res = "NO";
    }
    else
        res = "NO"; 
    cout<<res;
}

当str1和str2分别为ravivira时,结果为NO

问题真的出在这一行:

int ch1[n], ch2[n];

除了不是有效的 C++(g++ 允许动态大小的数组)之外,它正在创建 table 字符串的长度,而不是整个 ascii 范围。您的字符串可能只有 10 个字符长,但 'a' 的值为 97。因此它超出了范围,您进入了未定义的行为领域。此外,您不需要定义自己的长度函数。这已经内置到 C++ 字符串中 class.

更改此内容:

if(len_str(str1)==len_str(str2)){
    int n = len_str(str1);
    int ch1[n], ch2[n];
    for(int i=0; i<n; i++){
        ch1[i] = str1[i];
        ch2[i] = str2[i];
    }
    asc_order(ch1);
    asc_order(ch2);
    for(int i=0; i<n; i++)
        if(ch1[i]!=ch2[i])
            res = "NO";
}
else
    res = "NO"; 

变成这样:

char map1[256]={};  // you can use CHAR_BIT*sizeof(char) instead of a hardcoded 256
char map2[256]={};
for (char c : str1)
{
    map1[(unsigned char)c]++;
}
for (char c : str2)
{
    map2[(unsigned char)c]++;
}
int result = memcmp(map1, map2, sizeof(map1)); // returns 0 if the memory contents are the same. include <string.h> to get this function.
res = result ? "NO" : "YES";

你的排序有问题。

我删除了大部分不必要的代码并保留了您的排序逻辑 (working example):

#include <algorithm>
#include<iostream>
#include<string>
using namespace std;

void asc_order(string a){
    char temp=0;
    for(std::size_t i=0; i < a.length() ; i++)
        for(std::size_t j=0; j < a.length(); j++)
            if(a[i]<a[j]){
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
}

int main(){
    string str1, str2;
    cout<<"Enter the first string  : ";
    getline(cin, str1);
    cout<<"Enter the second string : ";
    getline(cin, str2);
    string res = "YES";
    if(str1.length() == str2.length()) {
        asc_order(str1);
        asc_order(str2);
        for(std::size_t i=0; i < str1.length(); i++)
            if(str1[i] != str2[i])
                res = "NO";
    }
    else
        res = "NO"; 
    cout<<res;
}

它returns错误的结果NO

然后我把你的排序替换成std::sort (working example):

#include<iostream>
#include<string>
using namespace std;

int main(){
    string str1, str2;
    cout<<"Enter the first string  : ";
    getline(cin, str1);
    cout<<"Enter the second string : ";
    getline(cin, str2);
    string res = "YES";
    if(str1.length() == str2.length()) {
        std::sort(str1.begin(), str1.end());
        std::sort(str2.begin(), str2.end());
        for(std::size_t i=0; i < str1.length(); i++)
            if(str1[i] != str2[i])
                res = "NO";
    }
    else
        res = "NO"; 
    cout<<res;
}

有效:YES

您的 asc_order 函数将交换两个条目,无论它们的顺序是正确的还是错误的。

for(int i=0; i<a.length() ; i++)
    for(int j=0; j<a.length(); j++)
        if(a[i]<a[j]){

因为 ij 运行 都是字符串长度的完整范围,测试 if a[i]<a[j] 有时会测试它们的顺序是否正确有时测试它们的顺序是否错误,因为 i 可能小于或大于 j.

也许你想要:

for(int i=0; i<a.length() ; i++)
    for(int j=i; j<a.length(); j++)
        if(a[i]<a[j]){