我的字符串比较函数有什么问题?

时间:2016-01-04 16:31:34

标签: c++ algorithm recursion

我的目标是递归地编写所有函数,以便我看起来更聪明。为了好玩,我想出了一个字符串比较函数

#include <iostream>

int string_compare ( char * s1, char * s2 ) 
{
    int retval;
    switch ( s1 ? 1 : 0 + s2 ? 2 : 0 )
    {
       case 0 : retval = 1; break; 
       case 1 :  
       case 2 : retval = 0; break; 
       case 3 : retval = *s1 == *s2 ? string_compare(++s1,++s2) : 0; break;
    }
    return retval;
}

int main ( )
{
    char str1 [] = "hey there",
         str2 [] = "hey there";
    std::cout << string_compare(str1,str2);
}

但是上面的代码正在打印0而不是期望1,这是错误的。有什么问题?

3 个答案:

答案 0 :(得分:7)

运营商+ has precedence优于运营商?:。使用括号。

switch ( (s1 ? 1 : 0) + (s2 ? 2 : 0) )

完全更正

对于一个完整的,有效的C字符串递归比较函数,这是一个实现:

/// @retval -1 iff sting s1 is before s2
/// @retval  0 iff sting s1 is equal to s2
/// @retval +1 iff sting s1 is afters2
int string_compare(const char* s1, const char* s2)
{
    if (*s1 > *s2) return 1;
    if (*s1 < *s2) return -1;

    if (*s1 == 0)
        return 0; // *s1 == *s2 == '\0'

    return string_compare(++s1, ++s2);
}

我们的想法是将结果定义为递归语句:

  • 空字符串小于任何非空字符串;
  • 如果s1s2都为空,s1 == s2;
  • 如果s1的第一个字符小于s2的{​​{1}},s1 < s2;
  • 如果s1的第一个字符大于s2的{​​{1}},s1 > s2;
  • 如果s1的第一个字符等于s2
    的第一个字符 S1s2的顺序与这些字符串的顺序相同,它们的第一个字符被取消。

示范

#include <iostream>
#include <algorithm>

namespace
{
    int string_compare(const char* s1, const char* s2)
    {
        if (*s1 > *s2) return 1;
        if (*s1 < *s2) return -1;

        if (*s1 == 0)
            return 0; // *s1 == *s2 == '\0'

        return string_compare(++s1, ++s2);
    }
}

int main()
{
    const char* words[] = {
        "recursive",
        "compare",
        "function",
        "for",
        "C",
        "string",
        "is",
        "really",
        "useless",
        "dont",
        "you",
        "think",
        " ",
        "recursive"
    };

    std::sort(std::begin(words), std::end(words), [](auto lhs, auto rhs){ return string_compare(lhs, rhs) < 0;});

    for (auto s : words)
        std::cout << s << std::endl;
}

输出

 
C
compare
dont
for
function
is
really
recursive
recursive
string
think
useless
you

Demo

答案 1 :(得分:6)

使用父母(和修复条件):

(*s1 ? 1 : 0) + (*s2 ? 2 : 0)

答案 2 :(得分:2)

+运算符优先于?:运算符。使用括号总是更好。

switch ((s1 ? 1:0) + (s2 ? 2:0))

您可以参考this