使用递归来添加奇数

时间:2009-08-15 23:45:24

标签: c# recursion

我正在尝试编写一种方法来计算所有小于给定数字的数字中奇数之和。所以,例如。 CalcOdd(7)将返回5 + 3 + 1 = 9.CaldOdd(10)将返回9 + 7 + 5 + 3 + 1 = 25等

该方法需要输入一个数字,减去1,然后递归地向后工作,添加所有奇数,直到它达到0.这就是我到目前为止所做的。

    private static int CalcOdd(int n)
    {            

        if (n <= 1)
            return 1;
        else
            if (n % 2 == 0)
                n--;

        return n + CalcOdd(n - 2);
    }

它不能很好地工作,它包括添加中传入的数字,这不是我想要的。谁能建议更好的方法呢?我也愿意能够将答案移植到偶数号码并添加选项以在答案中包含原始传递的数字。

非常感谢

15 个答案:

答案 0 :(得分:9)

为什么要在这里使用递归?只是循环;或者更好,用一个简单的等式计算数学...

事实上,C#并不能为数学这样的事物提供出色的深度递归;目前还没有真正的尾声。

循环方式:

private static int CalcOdd(int n)
{
    int sum = 0, i = 1;
    while (i < n)
    {
        sum += i;
        i += 2;
    }
    return sum;
}

答案 1 :(得分:5)

如你所说,你可以用递归来做到这一点,但如果你想更快地做,那么我可以告诉你n个第一个奇数的总和等于n * n。

private static int CalcOdd(int n) {
    if (n<=1)
        return 0;

    if (n%2 == 1)
        n--;

    int k = n/2;

    return k*k;
}

这有效的原因是:

每个偶数的形式为2k,而之前的奇数是2k-1。

因为2 * 1-1 = 1,所以kk奇数低于2k。

如果n是奇数,我们不想包含它,所以我们只需要下面的偶数,我们就会自动拥有我们想要的数据。

修改了损坏的代码。

答案 2 :(得分:4)

小于给定数字的奇数之和是一个完美的正方形。

得到(n / 2)的整个部分得到奇数的数量小于它自己。

正方形而且瞧!

private static int CalcSumOdd(int n)
{            
    int i;
    int.tryParse(n / 2, out i);
    return i*i;
}

对于偶数数字:

int i = n/2;
return i*(i+1);

校正。上述“偶数总和”包括原始数字“n”。即fn(12)= 42 = 2 + 4 + 6 + 8 + 10 + 12

如果你想要排除它,你应该单方面排除它,或者根据传入的参数用逻辑删除它。

答案 3 :(得分:2)

这是一个更正,

int CalcOdd(int n)
{ 
        n--; // <----

        if (n <= 1)
            return 0; // <----
        else
            if (n % 2 == 0)
                n--;

        return n + CalcOdd(n); // <----
}

答案 4 :(得分:1)

我是新来的,但这似乎是一个愚蠢的递归练习,因为它可以通过一个简单的等式来完成:

int sum(n,isEven,notFirst) {
    int c=1; //skip the else
    if (isEven) c=2;
    if (notFirst) n-=2;
    return ((n+c)*((n+c)/2))/2; }

经典离散数学和系列.. 总和从1到100(赔率和赔率)是((100 + 1)*(100/2))= 5050

编辑:在我的代码中,如果你计算的赔率总和与n是偶数,反之亦然,它不起作用,但我不打算把工作放到那里(并且代码)现在。我假设你的代码在它命中函数时会处理它。例如7/2不是int(显然)

答案 5 :(得分:0)


private static int CalcOdd(int n) {
    n -= 1;
    if ((n & 1) == 0) n--;
    if (n <= 1) return 1;
    return n + CalcOdd(n - 1);
}

但我会说做循环更好更清洁。


private static int CalcOdd(int n) {
    int i, r = 1;
    for (i = 3; i < n; i+=2)
        r += i;
    return r;
}

答案 6 :(得分:0)

为什么要使用递归?

private Int32 CalcOdd(Int32 value)
{
    Int32 r = 0;
    {
        while (value >= 1)
        {
            value--;
            if (value % 2 != 0)
            {
                r += value;
            }
        }               
    }
    return r;
}

答案 7 :(得分:0)

使用辅助功能。 CalcOdd包括测试n以查看它是偶数还是奇数;如果是偶数,则返回助手(n);如果是奇数,则返回助手(n-2)。

辅助函数必须处理三种情况: 1)n小于1;在这种情况下返回0。 2)n是偶数,在这种情况下是返回辅助(n-1)。 3)n是奇数,在这种情况下返回n +辅助(n-1)。

答案 8 :(得分:0)

int CalcOdd(int n)
{            
    n -= 1;

    if (n <= 0)
        return 0; 

    if (n % 2 == 0)
        n--;

    return n + CalcOdd(n);
}

这个函数也是递归的,它有一些参数可以让你决定做偶数还是奇数,而你想要包含第一个数字。如果你对它的工作原理感到困惑,请记住bool也可以看作1(真)和0(假)

int Calc(int n, bool even = false, bool includeFirst = false)
{           
    n -= !includeFirst;

    if (n <= 0)
        return 0; 

    if (n % 2 == even)
        n--;

    return n + Calc(n - includeFirst, even);
}

答案 9 :(得分:0)

public static int CalcOdd(int n) {
    // Find the highest even number. (Either n, or n-1.)
    // Divide that by 2, and the answer should be the square of that number.
    n = (n & 0x3FFFFFFE) >> 1;
    return (int)Math.Pow(n, 2);
}

答案 10 :(得分:0)

由于您希望选择包含或排除第一个答案(并且记住您的“递归”约束):

int calcOdd(int n, bool includeN)
{
    if( !includeN )
        return calcOdd(n-1, true);
    if(n<=1)
        return 1;
    else
        if(n%2 == 0)
            n--;
    return n+calcOdd(n-1, true);
}

includeFirst,如果传递为true,将在计算中包含n。否则,下一层将开始“包括N”。

当然,正如其他人所说,这是一种非常低效的递归使用方法,但是......如果你喜欢递归,请尝试Haskell。它是一种几乎完全基于这个概念构建的语言。

答案 11 :(得分:0)

Håkon,我已将您的代码移植到VS 2008中的c#,如下所示

        static int Calc(int n, bool bEven, bool bIncludeFirst)
    {
        int iEven = Bool2Int(bEven);
        int iIncludeFirst = Bool2Int(bIncludeFirst);

        n -= 1 - iIncludeFirst;

        if (n <= 0)
            return 0;

        if (n % 2 == iEven)
            n--;

        return n + Calc(n - iIncludeFirst, bEven, bIncludeFirst);
    }


    private static int Bool2Int(bool b)
    {
        return b ? 1 : 0;
    }

似乎工作正常。现在有什么我可以做的来进行无障碍吗?即我不想每次都要将这些bool解析为int?

答案 12 :(得分:0)

我将'make it odd'部分与'sum every other descending number'部分隔离开来:(原谅Python)

def sumEveryTwoRecursive(n):
    if n <= 0:
        return 0
    return n + sumEveryTwoRecursive(n - 2)

def calcOdd(n):
    return sumEveryTwoRecursive(n - (2 if n % 2 else 1))

答案 13 :(得分:0)

仅仅因为这里还没有人,我决定在这个钉子上使用LINQ锤子......

(借用Nick D和Jason的双方编程答案here

void Main()
{
    GetIterator(7, true, false).Sum().Dump();
    // Returns 9

    GetIterator(10, true, false).Sum().Dump();
    // Returns 25
}

public IEnumerable<int> GetIterator(int n, bool isOdd, bool includeOriginal)
{   
    if (includeOriginal)
        n++;

    if (isOdd)
        return GetIterator(n, 1);
    else
        return GetIterator(n, 0);
}

public IEnumerable<int> GetIterator(int n, int odd)
{
    n--;

    if (n < 0)
        yield break;

    if (n % 2 == odd)
        yield return n;

    foreach (int i in GetIterator(n, odd))
        yield return i;
}

答案 14 :(得分:0)

#include <iostream>

using namespace std;

int sumofodd(int num);

int main()
{
    int number,res;
    cin>>number;
    res=sumofodd(number);
    cout<<res;
    return 0;
}
int sumofodd(int num)
{    if(num<1) return 0;
    if (num%2==0) num--;
    return num+sumofodd(num-1);
}