字符串字谜C程序

字符串字谜C程序,c,string,C,String,可能重复: 我编写了下面的C代码来检查两个给定的字符串是否是彼此的字谜。 我知道这在复杂性/效率方面是最糟糕的,而且有很多更好的方法 #include "stdio.h" main() { char s1[]="mist"; char s2[]="mitt"; int i,j,isanag=0; if(strlen(s1)!=strlen(s2)) printf("Not anagrams\n"); for(i=0;i<strlen(s1);i++) { isan

可能重复:

我编写了下面的C代码来检查两个给定的字符串是否是彼此的字谜。 我知道这在复杂性/效率方面是最糟糕的,而且有很多更好的方法

#include "stdio.h"

main()
{
char s1[]="mist";
char s2[]="mitt";
int i,j,isanag=0;

if(strlen(s1)!=strlen(s2))
    printf("Not anagrams\n");

for(i=0;i<strlen(s1);i++)
{
    isanag=0;
    for(j=0;j<strlen(s2);j++)
    {
        if(s1[i]==s2[j])
        {
            isanag = 1;
            break;
        }
    }
    if(isanag == 0)
    {
        printf("Not anagrams\n");
        getch();
        exit(0);
    }

}

printf("Yes Anagrams\n");
getch();
}
我知道2 for循环的编码方式,这是显而易见的


我能做些什么来改进这个代码并解决这个怪癖?

您还没有针对重复字母的可能性进行编码

以这两个字符串为例:

char s1[]="mitt";
char s2[]="mist";
对于第一个字符串中的每个字母,代码将检查第二个字符串中的每个字母,以查看在任何位置是否有相同的字母。因此,让我们检查第一个字符串,并检查第二个字符串中的第一个相同字母(代码就是这样做的):

如您所见,代码认为这两个字符串是字谜,因为它将第一个字符串中的两个字母匹配到第二个字符串中的一个字母

解决方法是在继续下一个字母之前,将你已经匹配的字母“剪掉”;我将把它留给你去编码!祝你好运


编辑:当然,我忘了:如果代码成功地通过字符串1,从字符串2中删除字母,并且在字符串2中还有字母,那就意味着它们不是字谜!(在上面的例子中,'s'将保留在字符串2中。)

考虑到只有小写字母,您可以创建两个长度分别为26的向量

将两个位置中的所有位置都设置为0,在第一个字符串(s1)中循环,并增加向量中的位置:

   int v1[26], v2[26], i;
   for( i = 0; i < 26; i++)
        v1[i] = v2[i] = 0;
   for(i = 0; i < strlen(s1); i++)
        v1[s1[i] - 'a']++; // 'a' would be on position 0, 'b' on position 1 and so on
   for(i = 0; i < strlen(s2); i++)
        v2[s2[i] - 'a']++; 
intv1[26],v2[26],i;
对于(i=0;i<26;i++)
v1[i]=v2[i]=0;
对于(i=0;i
之后,你只需在向量中循环,看看字母的数量是否不同

   for(i = 0; i < 26; i++)
        if(v1[i] != v2[i])
        {
            printf("Not anagrams");
            exit(0);
        }
    printf("Anagrams");
(i=0;i<26;i++)的

如果(v1[i]!=v2[i])
{
printf(“非字谜”);
出口(0);
}
printf(“字谜”);

但是如果你使用大写,你可以生成4个向量,对于新的向量,用A减去,或者生成一个更大的向量,然后在你的代码中加入一些if。。。我让你试试那个;)

基于vmp的解决方案,您可以使用一个字符数组来实现这一点[26]

  • 迭代第一个字符串,增加 一封接一封
  • 迭代第二个字符串,递减数组 一个接一个
  • 迭代字母表数组并断言所有元素都是 零
  • 编辑:添加了一些代码(手边没有编译器,但概念应该可以)

    //仅小写
    int isAnagram(字符*左,字符*右)
    {
    char theAlphabet[26];
    memset(alphabet,0,alphabet的大小);
    int length=strlen(左);
    对于(int i=0;++i;i
    很抱歉,您的实现存在缺陷。此代码:

    for(j=0;j<strlen(s2);j++)
    {
        if(s1[i]==s2[j])
        {
            isanag = 1;
            break;
        }
    
    似乎是字谜,因为它们的长度相同,并且都是由集合{m,i,t,s,o,n}生成的

    您不仅必须检查字符是否相等,还必须检查它们在字符串中出现的次数

    这是一种(效率低下,因为它计算重复的字母)变化:

    for (i = 0; i < strlen(s1); i++)
    {
        int c = 0;
        // How many times does character s1[i] occur in s1?
        for (j = 0; j < strlen(s1); j++)
        {
            if (s1[i] = s1[j])
            {
                // Improvement: if j < i, it means we already checked this letter.
                // so we might break here...
                c++;
            }
        }
        // improvement: if c is 0 here, it means we can 'continue' for this letter
        // has been already checked before.
    
        // Subtract how many times it occurs in s2.
        for (j = 0; j < strlen(s2); j++)
        {
            if (s1[i] = s2[j])
                c--;
        }
        // If occurrences are the same we expect difference to be 0.
        if (c)
        {
            printf("Not anagrams\n");
            break;
        }
    }
    
    for(i=0;i

    更新:最好的解决方案是根据vmp或(甚至更好的)Mario the Spoon的方法完全更改算法。

    @Goldenmean,下面是另一个解决方案,它对两个字符串进行排序,然后比较它们。正如其他人所讨论的那样,字符计数将更有效,但这更有趣:-)

    qsort
    是一个标准的库排序函数,它将函数
    comp
    作为参数,并在对列表重新排序时使用它来比较列表的元素(在本例中为字符串)

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    static int comp(const void *a, const void *b)
    {
        const char *pa = a;
        const char *pb = b;
    
        return
            (*pa > *pb) ?  1 :
            (*pa < *pb) ? -1 :
            0;
    }
    
    int main(int argc, char ** argv)
    {
        char s1[]="mits";
        char s2[]="mist";
    
        qsort(s1, strlen(s1), 1, comp);
        qsort(s2, strlen(s2), 1, comp);
    
        printf("%s : %s  - %s\n", s1, s2, strcmp(s1, s2) ? "No" : "Yes");
        return 0;
    }
    
    #包括
    #包括
    #包括
    静态整数比较(常数无效*a,常数无效*b)
    {
    常数char*pa=a;
    常量字符*pb=b;
    返回
    (*pa>*pb)?1:
    (*pa<*pb)?-1:
    0;
    }
    int main(int argc,字符**argv)
    {
    字符s1[]=“mits”;
    字符s2[]=“雾”;
    qsort(s1,斯特伦(s1),1,康普);
    qsort(s2,strlen(s2),1,comp);
    printf(“%s:%s-%s\n”、s1、s2、strcmp(s1、s2)?“否”:“是”);
    返回0;
    }
    
    poor
    main()
    的返回类型您住在哪里?您的算法是错误的,因为它只检查
    s1
    的所有不同字符是否都出现在
    s2
    中,而不检查
    s2
    中是否有不在
    s1
    中的字符。这就是为什么
    “mitt”
    被报告为
    “mist”
    的一个字谜;
    s2
    中的
    's'
    被忽略。您的程序也无法检测不同数量的重复字母,即,
    “mistmt”
    “mist”for(j=0;j<strlen(s2);j++)
    {
        if(s1[i]==s2[j])
        {
            isanag = 1;
            break;
        }
    
    mitttsson
    
    missstton
    
    for (i = 0; i < strlen(s1); i++)
    {
        int c = 0;
        // How many times does character s1[i] occur in s1?
        for (j = 0; j < strlen(s1); j++)
        {
            if (s1[i] = s1[j])
            {
                // Improvement: if j < i, it means we already checked this letter.
                // so we might break here...
                c++;
            }
        }
        // improvement: if c is 0 here, it means we can 'continue' for this letter
        // has been already checked before.
    
        // Subtract how many times it occurs in s2.
        for (j = 0; j < strlen(s2); j++)
        {
            if (s1[i] = s2[j])
                c--;
        }
        // If occurrences are the same we expect difference to be 0.
        if (c)
        {
            printf("Not anagrams\n");
            break;
        }
    }
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    static int comp(const void *a, const void *b)
    {
        const char *pa = a;
        const char *pb = b;
    
        return
            (*pa > *pb) ?  1 :
            (*pa < *pb) ? -1 :
            0;
    }
    
    int main(int argc, char ** argv)
    {
        char s1[]="mits";
        char s2[]="mist";
    
        qsort(s1, strlen(s1), 1, comp);
        qsort(s2, strlen(s2), 1, comp);
    
        printf("%s : %s  - %s\n", s1, s2, strcmp(s1, s2) ? "No" : "Yes");
        return 0;
    }