无法在C中实现递归调用

时间:2015-01-29 16:34:34

标签: c recursion roman-numerals

所以我第一次和C一起工作,我觉得我在使用递归时遇到了麻烦。例如,要在C#中返回递归调用的值,我可能会使用return methodRecursiveCall(parameter)。在C中,我有这个陈述,它是罗马数字转换器的一部分:

int convert(char *s)
{    
    int val = 0;
    int index = 0;
    int length = strlen(s);

    while (length >1)
    {

        if (s[index] == 'I')
        {
            if(s[index + 1] == 'V' || s[index + 1] == 'X' || s[index + 1] == 'C' || s[index + 1] == 'D' || s[index + 1] == 'M')
            {
                val--;
                index++;
                length--;
                convert(&(s[index]));
            }
            else
            {
                val++;
                index++;
                length--;
                convert(&(s[index]));
            }
        }

        if (s[index] == 'V')
        {
            if(s[index + 1] == 'X' || s[index + 1] == 'C' || s[index + 1] == 'D' || s[index + 1] == 'M')
            {
                val = val - 5;
                index++;
                length--;
                convert(&(s[index]));
            }
            else
            {
                val = val + 5;
                index++;
                length--;
                convert(&(s[index]));
            }
        }

        if (s[index] == 'X')
        {
            if(s[index + 1] == 'C' || s[index + 1] == 'D' || s[index + 1] == 'M')
            {
                val = val - 10;
                index++;
                length--;
                convert(&(s[index]));
            }
            else
            {
                val = val + 10;
                index++;
                length--;
                convert(&(s[index]));
            }
        }

        if (s[index] == 'C')
        {
            if((s[index + 1]) == 'D' || (s[index + 1]) == 'M')
            {
                val = val - 100;
                index++;
                length--;
                convert(&(s[index]));
            }
            else
            {
                val = val + 100;
                index++;
                length--;
                convert(&(s[index]));
            }
        }

        if (s[index] == 'D')
        {
            if(s[index + 1] == 'M')
            {
                val = val - 500;
                index++;
                length--;
                convert(&(s[index]));
            }
            else
            {
                val = val + 500;
                index++;
                length--;
                convert(&(s[index]));
            }
        }

        if (s[index] == 'M')
        {

            val = val + 500;
            index++;
            length--;
            convert(&(s[index]));

        }    
    }
    return val;
}

我的问题具体是关于convert(&(s[index]));,这是一个递归调用。它意味着将整个罗马数字转换为十进制,但它只转换第一个字符。这通常是我要“回归”的地方。但是,我不知道如何在C中取消它。

1 个答案:

答案 0 :(得分:0)

从接近结尾的这个片段:

if (s[index] == 'M')
{
    val = val + 500;
    index++;
    length--;
    convert(&(s[index]));
}

您可能需要以下内容:

if (s[index] == 'M')
    val = 1000 + convert(&s[index+1]);

您知道M映射到1,000;总值将是1000 + M之后的值,这是表达式所声明的。请注意,s[index+1]周围的括号不是必需的。

您需要在整个代码中进行类似的更改。您还需要查看为什么将迭代与递归混合在一起;你应该使用其中一个。

请注意,您的代码似乎不包括L又名50。

就个人而言,我认为这不是进行转换的最佳方式。除此之外,很难发现MXMC无效。我的代码使用包含字符串和相应值(M1000; CM和900)等的结构数组,并且一旦其中一个值用完({{ 1}}只能使用一次; CM可以多次使用; M可以使用一次; CD可以多次使用 - 也可以使用,但它可以' t稍后再出现。它使用迭代而不是递归。


这是一个适度简单的改编和修复你的代码。它适用于转换“已知有效”罗马数字;它不适用于验证它们。

C

示例输出:

#include <stdio.h>

int convert(const char *s);
int convert(const char *s)
{
    int val = 0;
    int i = 0;

    if (s[i] == '\0')
        return 0;

    if (s[i] == 'I')
    {
        if (s[i + 1] != 'I' && s[i + 1] != '\0')
            val = convert(&s[i + 1]) - 1;
        else
            val = 1 + convert(&s[i + 1]);
    }

    if (s[i] == 'V')
        val = 5 + convert(&s[i + 1]);

    if (s[i] == 'X')
    {
        if (s[i + 1] == 'L' || s[i + 1] == 'C' || s[i + 1] == 'D' || s[i + 1] == 'M')
            val = convert(&s[i + 1]) - 10;
        else
            val = 10 + convert(&s[i + 1]);
    }

    if (s[i] == 'L')
        val = 50 + convert(&s[i + 1]);

    if (s[i] == 'C')
    {
        if ((s[i + 1]) == 'D' || (s[i + 1]) == 'M')
            val = convert(&s[i + 1]) - 100;
        else
            val = 100 + convert(&s[i + 1]);
    }

    if (s[i] == 'D')
        val = 500 + convert(&s[i + 1]);

    if (s[i] == 'M')
        val = 1000 + convert(&s[i + 1]);

    return val;
}

int main(void)
{
    const struct roman
    {
        const char *str;
        int num;
    } test[] =
    {
        { "I",                  1 },
        { "II",                 2 },
        { "III",                3 },
        { "IV",                 4 },
        { "V",                  5 },
        { "VI",                 6 },
        { "VII",                7 },
        { "VIII",               8 },
        { "VIIII",              9 },
        { "IX",                 9 },
        { "X",                 10 },
        { "XI",                11 },
        { "XII",               12 },
        { "XIII",              13 },
        { "XIV",               14 },
        { "XV",                15 },
        { "XVI",               16 },
        { "XVII",              17 },
        { "XVIII",             18 },
        { "XIX",               19 },
        { "XVIIII",            19 },
        { "XX",                20 },
        { "XXI",               21 },
        { "XXX",               30 },
        { "XL",                40 },
        { "L",                 50 },
        { "LXXVIII",           78 },
        { "XCVIII",            98 },
        { "IC",                99 },
        { "XCIX",              99 },
        { "C",                100 },
        { "D",                500 },
        { "M",               1000 },
        { "MMMDCCCLXXXVIII", 3888 },
        { "MDCMMCCLXIIIIII", 3666 }, // Not good for validating!
    };
    enum { NUM_TEST = sizeof(test) / sizeof(test[0]) };

    for (int i = 0; i < NUM_TEST; i++)
    {
        int value = convert(test[i].str);
        printf("%s  %15s = %4d vs %4d\n", (value == test[i].num) ? "== PASS ==" : "!! FAIL !!",
               test[i].str, value, test[i].num);
    }
    return 0;
}

请注意,最后一个'数字'是可怕的伪造(1000 + 500 + 900 + 1000 + 100 + 100 + 50 + 10 + 1 + 1 + 1 + 1 + 1 + 1)。