[英]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.