C语言 将数组复制到较低位置时,Anagrams函数不起作用

twh00eeo  于 2023-10-15  发布在  其他
关注(0)|答案(2)|浏览(86)

所以我有一个接受两个字符串值的变位函数。两个字符串都是用char[100]初始化的,输入是用户通过键盘输入的。

bool isAnagram(char* pattern, char* string) {
    
    int count[256] = {0};
    int count2[256] = {0};
    int i;
    
    for (i = 0; pattern[i] && string[i]; i++) {
        count[pattern[i]]++;
        count2[string[i]]++;
        
    }
    if (pattern[i] || string[i]) {
        return false;
        
    }
    
    for (i = 0; i < 256; i++) {
        if (count[i] != count2[i]) {
            return false;
        }
    }
    return true;
    
}

但是,这个函数有一个很大的问题:是区分大小写的。我要所有的字谜包括不区分大小写的。
我尝试了许多不同的方法将字符串复制到一个新的临时数组中。

bool isAnagram(char* pattern, char* string) {
    char tempstr[100];
    char tempstr2[100]; 
    int count[256] = {0};
    int count2[256] = {0};
    int i;
    for (i = 0; i < strlen(pattern); i++) {
        tempstr[i] = tolower(pattern[i]);
    }
    for (i = 0; i < strlen(string); i++) {
        tempstr2[i] = tolower(string[i]);
    }
    for (i = 0; tempstr[i] && tempstr2[i]; i++) {
        count[tempstr[i]]++;
        count2[tempstr2[i]]++;
        
    }
    if (tempstr[i] || tempstr2[i]) {
        return false;
        
    }
    
    for (i = 0; i < 256; i++) {
        if (count[i] != count2[i]) {
            return false;
        }
    }
    return true;
    
    
}

这只是我尝试的一种方式。我甚至尝试了完全不同的方法来做字谜。无论我做了什么,我都无法复制数组,同时也无法正确地检查与数组的字谜。
老实说,我感到恼火。我最近压力很大,我都不知道自己做错了什么。任何帮助都非常感谢。

btqmn9zl

btqmn9zl1#

别生气学习如何规划行动是学习的全部。
稍微修改你的(更简单的)第一个版本应该提供解决方案。

bool isAnagram( char *str1, char *str2 ) {
    unsigned char cnt1[256] = { 0 }; // 0-255 is sufficient range for tallying
    unsigned char cnt2[256] = { 0 };

    while( *str1 && *str2 ) {
        cnt1[ tolower( (unsigned char)*str1++ ) ]++;
        cnt2[ tolower( (unsigned char)*str2++ ) ]++;
    }

    if( *str1 || *str2 )
        return false;

    for( size_t i = 0; i < sizeof cnt1; i++ )
        if( cnt1[i] != cnt2[i] )
            return false;

    return true;
}

注意事项:
1.在这样的函数中,较短的变量名更容易阅读/扫描。

  1. str1str2是本地和消耗性的;用作指针简化了代码。
    1.大写字母字符将作为其对应的大写字母进行计数。
    1.转换为unsigned char可以防止b7被设置时出现的 sign extension
    1.你的“直方图”统计是精心策划的!干得漂亮!
    1.数组元素的索引应该是size_t i(永远不会为负)。

编辑

如果你真的想给人留下深刻印象,把for()循环和return true;替换为:

return memcmp( cnt1, cnt2, sizeof cnt1 ) == 0;

或者,更进一步:

return !*str1 && !*str2 && !memcmp( cnt1, cnt2, sizeof cnt1 );

五行代码用一行来表达。
字谜:“活”,“邪恶”,“卑鄙”,“面纱”...:-)

fdbelqdn

fdbelqdn2#

这里有一个解决方案给你。你已经很接近了--我只是稍微修改了你的代码。注意tolower()的用法及其在代码中的位置。这将导致计数数组按计划递增。这将产生一个不区分大小写的解决方案,如输出所示。编辑:还注意到@Aconcagua的评论中添加了“unsigned char”。可运行代码可在here上使用。

#include <stdio.h>
#include <ctype.h> /* tolower() */
#include <stdbool.h> /* bool, true, false */
    
bool isAnagram(char* pattern, char* string) 
{
    int count[256] = {0};
    int count2[256] = {0};
    int i;
    
    for (i = 0; pattern[i] && string[i]; i++) {
        count[tolower((unsigned char)pattern[i])]++;   /* added tolower() + cast */
        count2[tolower((unsigned char)string[i])]++;   /* added tolower() + cast */
    }
    if (pattern[i] || string[i]) {
        return false;
    }
    for (i = 0; i < 256; i++) {
        if (count[i] != count2[i]) {
            return false;
        }
    }
    return true;
    
}

int main () 
{
    printf("%s\n", isAnagram("Batman", "Manbat")?"TRUE":"FALSE");
    printf("%s\n", isAnagram("Batman", "Cat")?"TRUE":"FALSE");
    printf("%s\n", isAnagram("Strut", "Trust")?"TRUE":"FALSE");
  
    return(0);
}

输出量:

TRUE
FALSE
TRUE

相关问题