麻烦实施℃的递归调用 [英] Trouble implementing a recursive call in C

查看:213
本文介绍了麻烦实施℃的递归调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我,我一直用C工作的第一次,我想我使用递归遇到麻烦。例如,要在C#中的递归调用返回一个值,我可能会使用返回methodRecursiveCall(参数)。在C中,我有这样的说法,这是一个罗马数字转换器的一部分:

So I'm I've been working with C for the very first time, and I think I'm having trouble using recursion. For instance, to return a value for a recursive call in C#, I might use return methodRecursiveCall(parameter). In C, I have this statement, which is a part of a roman numeral converter:

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;
}

我的问题是专门关于转换(及(S [指数])); ,这意味着是一个递归调用。它的目的是将整个罗马数字转换为十进制,但它仅将第一字符。这通常是在那里我会放一个回归。我不知道如何在C然而,把这事办成。

My question specifically is about the convert(&(s[index]));, which is meant to be a recursive call. It is meant to convert an entire Roman numeral to decimal, however it only converts the first character. That is normally where I would put a 'return'. I'm not sure how to pull this off in C, however.

推荐答案

有关该片段从接近尾声:

For this fragment from near the end:

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

您可能想是这样的:

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

您知道 M 映射到1000元;总价值将是1000+的接下来的 M ,这是前任pression状态的价值。需要注意的是围绕 S中的括号[索引+ 1] 是没有必要的。

You know that the M maps to 1,000; the total value will be 1000 + the value of what follows the M, which is what the expression states. Note that the parentheses around s[index+1] are not necessary.

您将需要使整个code类似的变化。您还需要查看你为什么迭代混在递归;你应该使用一个或另一个。

You'll need to make similar changes throughout the code. You also need to review why you have iteration mixed in with recursion; you should use one or the other.

请注意,您的code似乎没有覆盖 50又名

Note that your code doesn't seem to cover L aka 50.

我个人认为这不是做转换的最佳途径。一切分开,这将是很难发现的 MXMC 是无效的。我的code使用包含字符串和相应的值( M 1000 结构的数组; CM 900)等,一旦已经用完的一个值( CM 只能使用一次; <$ C $ç> M 可多次使用; CD 可使用一次; C 可以多次使用 - 这是codeD时间),那么它便无法再出现。它使用迭代而不是递归。

Personally, I think this is not the best way to do the conversion. All else apart, it will be hard to spot that MXMC is invalid. My code uses an array of structures containing a string and the corresponding value (M and 1000; CM and 900) etc, and once one of the values has been used up (CM can only be used once; M can be used multiple times; CD can be used once; C can be used multiple times — that's coded too), then it can't appear again later. And it uses iteration rather than recursion.

下面是一个简单的适度调整和修复你的code。它的工作原理确定转换已知有效的罗马数字;它不用于验证它们很好地工作。

Here's a moderately simple adaptation and fix to your code. It works OK for converting 'known to be valid' Roman numbers; it doesn't work well for validating them.

#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;
}

示例输出:

== PASS ==                I =    1 vs    1
== PASS ==               II =    2 vs    2
== PASS ==              III =    3 vs    3
== PASS ==               IV =    4 vs    4
== PASS ==                V =    5 vs    5
== PASS ==               VI =    6 vs    6
== PASS ==              VII =    7 vs    7
== PASS ==             VIII =    8 vs    8
== PASS ==            VIIII =    9 vs    9
== PASS ==               IX =    9 vs    9
== PASS ==                X =   10 vs   10
== PASS ==               XI =   11 vs   11
== PASS ==              XII =   12 vs   12
== PASS ==             XIII =   13 vs   13
== PASS ==              XIV =   14 vs   14
== PASS ==               XV =   15 vs   15
== PASS ==              XVI =   16 vs   16
== PASS ==             XVII =   17 vs   17
== PASS ==            XVIII =   18 vs   18
== PASS ==              XIX =   19 vs   19
== PASS ==           XVIIII =   19 vs   19
== PASS ==               XX =   20 vs   20
== PASS ==              XXI =   21 vs   21
== PASS ==              XXX =   30 vs   30
== PASS ==               XL =   40 vs   40
== PASS ==                L =   50 vs   50
== PASS ==          LXXVIII =   78 vs   78
== PASS ==           XCVIII =   98 vs   98
== PASS ==               IC =   99 vs   99
== PASS ==             XCIX =   99 vs   99
== PASS ==                C =  100 vs  100
== PASS ==                D =  500 vs  500
== PASS ==                M = 1000 vs 1000
== PASS ==  MMMDCCCLXXXVIII = 3888 vs 3888
== PASS ==  MDCMMCCLXIIIIII = 3666 vs 3666

请注意,最后'数'是可怕的假(1000 + 500 + 900 + 1000 + 100 + 100 + 50 + 10 + 1 + 1 + 1 + 1 + 1 + 1)。

Note that the last 'number' is horribly bogus (1000 + 500 + 900 + 1000 + 100 + 100 + 50 + 10 + 1 + 1 + 1 + 1 + 1 + 1).

这篇关于麻烦实施℃的递归调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆