我应该用C编程语言编写一个递归函数,该函数检查字符串1是否大于或等于或小于字符串2,并因此返回1
,0
,{{1 }} 分别。
下面是我编写的代码。该程序无法终止,我无法弄清原因。请给我一些建议。谢谢。
-1
答案 0 :(得分:2)
函数中的主要问题是您没有在递归调用revisedStrcmp
中传递更新的指针,从而导致无限循环和潜在的堆栈溢出。
以下是经过纠正和简化的版本:
int revisedStrcmp(const char *s1, const char *s2) {
if (*s1 < *s2)
return -1;
if (*s1 > *s2)
return +1;
// *s1 == *s2
if (*s1 == '\0')
return 0;
return revisedStrcmp(s1 + 1, s2 + 1);
}
因为较短的字符串不需要特殊情况,因为可以在比较中使用空终止符。
这种特殊的递归样式称为尾递归,它将由现代编译器编译成循环。
但是请注意,为了使revisedStrcmp()
返回与strcmp
相同的顺序,必须对unsigned char
的值执行比较,而不要对纯char
进行比较,后者可以由许多架构上的默认设置:
int revisedStrcmp(const char *s1, const char *s2) {
unsigned char c1 = *s1, c2 = *s2;
if (c1 < c2)
return -1;
if (c1 > c2)
return +1;
// c1 == c2
if (c1 == '\0')
return 0;
return revisedStrcmp(s1 + 1, s2 + 1);
}
答案 1 :(得分:1)
您没有将i, n, p
变量传递给该函数。这样,您的函数就不会结束,因为它每次都会在计数器变量为0时开始。
答案 2 :(得分:1)
在这一部分:
else if (s1[i] !='\0' && s2[i] !='\0') //both not equal to null
{
if (s1[i]>s2[i]) n+=1; //s1
else if (s1[i]<s2[i]) p+=1; //s2
else
{
n+=1; //s1
p+=1; //s2
}
i+=1;
return rStrcmp(s1,s2);
您用rStrcmp(s1,s2);
和s1
呼叫s2
,但是,您刚刚处理了一个字符。致电rStrcmp(s1+1,s2+1);
。
i
为字符串编制索引。除return语句之前外,它始终为0,因此从不使用其值:
int rStrcmp(char *s1, char *s2)
{
if (*s1 =='\0' && *s2 !='\0') //s1 shorter than s2
return -1;
else if (*s1 !='\0' && *s2 =='\0') //s1 longer than s2
return 1;
else if (*s1 !='\0' && *s2 !='\0') //both not equal to null
{
if (*s1>*s2) return 1; //s1
else if (*s1<*s2) return -1; //s2
else
return rStrcmp(s1+1,s2+1);
}
else //if s1[i] & s2[i] are null
{
// since both are null, they are the same length and each
// character was the same: equal
return 0;
}
}
答案 3 :(得分:1)
只需将return rStrcmp(s1, s2);
更改为return rStrcmp(s1+i, s2+i);
。这样,您就可以存储数组位置的增量。
答案 4 :(得分:1)
原因是s1
和s2
的递归相同。我的意思是:
如果您有char *s1 = "Hello";
和char *s2 == Elloh
,则递归调用是相同的。您总是从同一点开始,因此,您不会以任何方式(n, p)
传递增量,因此基本上每个递归调用都从同一点开始。您可以做的是增量指针,这是一个简短的解决方案:
int revisedStrcmp (char *s1, char *s2) {
if (*s1 == *s2)
return *s1 == '\0' ? 0 : revisedStrcmp(s1 + 1, s2 + 1);
return (*s1 > *s2) ? 1 : -1;
}
或者您可以执行以下操作:
return revisedStrcmp(s1+i, s2+i);