2016-03-03 72 views
0

我有以下函数,并且我想测试两个字符串是否是anagrams。我认为这样做的一种方式是对字符串中每个字符的值进行求和,然后比较它们的值。C - 从char字符串中传递一个int值

但是,当我尝试运行我的程序时,在for循环中出现分段错误。我没有正确理解这一点,是否有任何我在我的代码中做错了?

int anagram(char *a, char *b) 
{ 
    int sum1 = 0; 
    int sum2 = 0; 
    char *p, *q; 

    for (p=a; p != '\0'; p++) { 
     sum1 += *p - 'a'; 
    } 

    for (q=b; q != '\0'; q++) { 
     sum2 += *q - 'a'; 
    } 

    if (sum1 == sum2) 
     return 1; 
    else 
     return 0; 
} 
+1

应该是'* p!='\ 0''和'* q!='\ 0''。由于'p'和'q'不是NULL指针,你的循环是无限循环。 – user3386109

+0

@Barmar我的意思是,如果我为字符串a输入hello并为字符串b输入loleh,我会返回1 – lodam

+0

如何合并字符告诉你它们是否为字符?你会得到和“abc”和“bc”相同的总和。 – Barmar

回答

3

在你for循环必须检查

*p != '\0'

*q != '\0'

这是赛格故障的原因。


此外,即使是固定的,该代码会给你误报:

“BC” 的 “广告” 字谜

我建议你采用不同的方法:

使两个数组int s大小256,零初始化。

让每个数组的每个项目保持每个字符串的每个字母(字符)的计数。

最后比较两个数组是否相同。

我离开了向你写代码的任务。

+1

@chqrlie他用数字测试字符串的想法是错误的,但这并不是问题所在。 – Barmar

+0

好的,谢谢,我想找一个新的方法,谢谢! – lodam

+1

他的问题很混乱......但我更喜欢解决大多数问题的答案。 – chqrlie

1

“p!= 0”应该是“* p!= 0”,因为现在您正在等待指针变为空值。

1

这里是你的问题的完整解决方案:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int cmp(const void *str1, const void *str2) { 
    return (*((char*)str1) - *((char*)str2));  
} 

bool areAnagram(char *str1, char *str2) { 
    int n1 = strlen(str1); 
    int n2 = strlen(str2); 

    if (n1 != n2) 
     return false; 

    qsort(str1, n1, 1, &cmp); 
    qsort(str2, n2, 1, &cmp); 

    for (int i = 0; i < n1; i++) 
     if (str1[i] != str2[i]) 
     return false; 

    return true; 
} 

int main() 
{ 
    char str1[] = "test"; 
    char str2[] = "tset"; 
    if (areAnagram(str1, str2)) 
     printf("The two strings are anagram of each other"); 
    else 
     printf("The two strings are not anagram of each other"); 

    return 0; 
} 
+0

@chux:Thanx,我没有运行它。只是从记忆中写下来的。根据您的建议更换了该行。 – cwschmidt

1

既然我们已经给大约更好的方法的答案,这里是我的:

获取(最好是较小的)素数的列表。你需要输入字符串的每一个可能的字符,因此当你想检查只包含数字0到9的字符串时,你需要10个素数。让我们把这些:

static unsigned const primes[10] = { 
    2, 3, 5, 7, 11, 13, 17, 19, 23, 29}; 

现在,由于每个号码都有一个确切的质因数分解,并且由于乘法是可交换的,你可以建立素数的乘积为您的字符串的每个字符。如果它们是相同的,那么对于每个字符都认为它在两个字符串中的次数相同。因此,这两个字符串都是彼此的字形。

unsigned long prime_product(char const * str) { 
    assert(str != NULL); 
    unsigned long product = 1; 
    for (; *str != '\0'; ++str) { 
    assert(*str >= '0'); 
    assert(*str <= '9'); 
    product *= primes[*str - '0']; 
    } 
    return product; 
} 

char is_anagram(char const * one, char const * two) { 
    return prime_product(one) == prime_product(two); 
} 

这甚至应该工作在一定程度上,当产品溢出,虽然然后误报是可能的(尽管它们的似然性可以大大地时也比较两个字符串的长度减小)。

可以看出这个版本有O(n)时间和恒定的空间复杂度。

+0

不错,但需要'uint128_t'来处理26个不同的符号。 – chux