簡體   English   中英

我如何制作一個遞歸 function,它只使用加法和 2 個變量進行除法

[英]How can I make one recursive function which does division using only addition and only 2 variables

我最近被要求做一個遞歸的 function 作業,它只使用加法(不允許減法)進行除法並且只有 2 個變量。

編輯:基於評論的一些注釋:

  • n1 除以 n2。 (n1:n2)

  • 答案應該是您可以將 n2 放入 n1 的次數的整數 (int)(8:3 應該得到 2,8:4 也應該得到 2)。

  • 您可以假設輸入只是整數正數。

正如評論中所要求的,我會盡力將作業翻譯成英文並盡可能准確:

編寫一個名為“PDiv”的遞歸 function 獲取兩個整數正數並返回它們的整數商,僅使用加法運算。

我試圖用 2 個遞歸函數來實現它,如下所示:(賦值只需要一個 function,所以這不是正確的答案)

public static int PDiv(int n1, int n2)
{
    if (n1 < n2)
        return 0;
    else if (n1 == n2)
        return 1;
    else
        return PDiv(n1, n2 + n2, n2) + 1;
}

public static int PDiv(int n1, int n2, int con)
{
    if (n1 < n2)
        return 0;
    else if (n1 == n2)
        return 1;
    else
        return PDiv(n1, n2 + n2, con) + 1;
}

除此之外,我還嘗試過那個確實有效的方法,但它假裝很聰明,但實際上並沒有加法,而是加了一個減號(基本上是減法)。 例子:

public static int PDiv(int n1, int n2)
{
    if (n1 < n2)
        return 0;
    else if (n1 == n2)
        return 1;
    else
        return PDiv(n1 + -n2, n2) + 1;
}

如果有人知道我如何讓它發揮作用,我很樂意聽到! 提前致謝!

這是我們可以實現此目的的一種方法,前提是我們可以使用模運算符和局部變量。

這個想法是,如果我們知道PDiv(n, m + m) ,我們只需要知道我們是否仍然可以再添加一個m

C# 代碼:

using System;

public class Test
{
    public static int PDiv(int n, int m)
    {
        if (n < m)
            return 0;
        if (n == m)
            return 1;
  
        int k = PDiv(n, m + m);

        return k + k + (n % (m + m) < m ? 0 : 1);
    }

    public static void Main()
    {
        Console.WriteLine(PDiv(21, 3));
    }
}

如果我們允許元組返回值,那么我們可以根據要求使用純加法、比較和賦值操作以及兩個參數來完成此操作。 C# 代碼:

using System;

public class Test
{
    // Returns (floor(n / m) * m, floor(n / m))
    public static (int, int) f(int n, int m){
        if (n < m)
            return (0, 0);
        if (n == m)
            return (n, 1);
  
        (int _n, int k) = f(n, m + m);

        if (_n + m > n)
            return (_n, k + k);
    
        return (_n + m, k + k + 1);
    }

    public static void Main()
    {
        for (int n=1; n<200; n++){
            for (int m=1; m<n; m++){
                (int _n, int nm) = f(n, m);
                if (nm != n / m)
                    Console.WriteLine($"Mismatch: { n }, { m }") ;
            }
        }

        Console.WriteLine("Test done.");
    }
}

你唯一的問題是,當你使用 n2 = n2 + con 時,你仍然在第二種方法中比較 n1 和 n2,而 con 仍然是你的凝視 n2 它應該工作。

    private int div(int n1, int n2)
    {
        if (n1 == n2) return 1;
        if (n1 < n2) return 0;
        return div(n1, n2, n2+n2) + 1;  
    }
    private int div(int n1, int n2, int runner)
    {
        if (n1 == runner) return 1;
        if (n1 < runner) return 0;
        return div(n1, n2, runner+n2) + 1;
    }
d = a/b 
d * b + r = a

第二行給出了如何以遞歸方式解決這個問題的想法。 忽略余數 (r),求和 b 直到d*b > a 有了這個,剩下要做的就是跟蹤我們必須將 b 加在一起的次數,直到它大於a

int div_loop(int dividend, int divisor, int x, int n) {
  if (x > dividend)
     return (n-1);
  return div_loop(dividend, divisor, (x + divisor), (n+1));
}
int div(int dividend, int divisor) {
  return div_loop(dividend, divisor, 0, 0);
}

這個應該是符合要求的,因為要求沒有禁止寫helper function。而main function只有2個arguments,而且是遞歸求解,只用加法。

如果 C# 嵌套了 function(不確定現在是否有,但我上次在 C# 中編程時沒有), div_loop()可以嵌套在div() function 內部,內部 function 可以被視為實現細節(和少了 2 個參數)。 例如,在 F# 中,它可能如下所示:

let div dividend divisor =
  let rec operate x n =
    if x > dividend
    then (n - 1)
    else operate (x + divisor) (n + 1)
  operate 0 0

Microsoft c# 文檔來看,C# 現在支持嵌套函數,稱為“本地函數”。

因此,您可以滿足所有要求:

int pdiv(int dividend, int divisor) {
  return div_loop(0, 0);
  int div_loop(int x, int n) {
    if (x > dividend) return (n-1);
    return div_loop(x+divisor, n + 1);
  }
}
 

你也可以把它寫成一種方法:

public int recursive_div(int a, int b)
    {
        if (a < b)
        {
            return 0;
        }
        else if (b == 0)
        {
            return -1;
        }
        else if (a == b)
        {
            return 1;
        }
        else
        {
            return  recursive_div(a-b,b) +1 ;
        }
    }

return -1 只是 dived by 0 錯誤的捕獲值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM