2010-12-20 67 views
1

在下面的代碼中它應該乘以2個數字。它適用於3位和3位以下的數字,但當我給出4位數或更大的數字時,會產生運行時錯誤:stackoverflow exception was unhandled。我已經評論了問題出在哪裏。我認爲問題是在int中定義變量,並且長時間更改它們,但問題仍然存在。錯誤在哪裏?stackoverflow異常未處理

編輯: 現在,什麼你怎麼看待這個問題它沒有做任何事情

 public long Prod2(long u, long v) 
    { 
     var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray(); 
     int n = Math.Max((int)Math.Floor(Math.Log10(u) + 1),(int)Math.Floor(Math.Log10(v) + 1));   
     int threshold = 3; 

     if (u == 0 || v == 0) 
     { 
      return 0; 
     } 
     else if (n <= threshold) 
     { 
      return u * v; 
     } 
     else 
     { 
      int m = (int)Math.Ceiling(n/2.0); 

      int x = (int)(u/Math.Pow(10, m)); 
      int y = (int)(u % Math.Pow(10, m)); 
      int w = (int)(u/Math.Pow(10, m)); 
      int z = (int)(v % Math.Pow(10, m)); 

      long r = Prod2(x + y, w + z); 
      long p = Prod2(x, w); 
      long q = Prod2(y, z); 

      return p * (long)Math.Pow(10, 2 * m) + (r - p - q) * (long)Math.Pow(10, m) + q; 
      long result = Prod2(numbers[0], numbers[1]); 
      textBox1.Text = result.ToString(); 
     } 
    } 
+0

@arash - 如果你能解釋一下,我很樂意提供幫助*這種方法試圖做什麼*做*? – TheCloudlessSky 2010-12-20 13:35:16

+0

m是一個3位數字? – mingos 2010-12-20 13:35:57

+1

stackoverflow異常不是由算術運算引起的。這是因爲你的遞歸不會因爲某種原因而停止。 – nan 2010-12-20 13:39:22

回答

2

編輯:我已經完全翻譯成你的書描述的算法:

public long Prod2(long u, long v) 
{ 
    int n = Math.Max((int)Math.Floor(Math.Log10(u) + 1), (int)Math.Floor(Math.Log10(v) + 1)); 
    int threshold = 3; 

    if(u == 0 || v == 0) 
    { 
     return 0; 
    } 
    else if(n <= threshold) 
    { 
     return u * v; 
    } 
    else 
    { 
     int m = (int)Math.Ceiling(n/2.0); 

     int x = (int)(u/Math.Pow(10, m)); 
     int y = (int)(u % Math.Pow(10, m)); 
     int w = (int)(u/Math.Pow(10, m)); 
     int z = (int)(v % Math.Pow(10, m)); 

     long r = Prod2(x + y, w + z); 
     long p = Prod2(x, w); 
     long q = Prod2(y, z); 

     return p * (long)Math.Pow(10, 2 * m) + (r - p - q) * (long)Math.Pow(10, m) + q; 
    } 
} 

爲了得到正確的結果,你會調用這個方法從某些其他方法是這樣:

void Main() 
{ 

    // Call the method and store the result in variable 'r'. 
    long r = Prod2(1234, 5678); 
    Console.WriteLine(r); 

    ///////////////////////////////// 
    // 
    // OR - In your case read from textBox7 and then store the result in textBox1  
    // 
    ///////////////////////////////// 
    var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray(); 
    long result = prod2(numbers[0], numbers[1]); 
    textBox1.Text = result.ToString(); 
} 

因此,在你的事件處理程序,例如用於button1,你會做撥打電話:

public void button1_Click() 
{ 
    var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray(); 
    long result = prod2(numbers[0], numbers[1]); 
    textBox1.Text = result.ToString(); 
} 

不要修改Prod2我有,只是你的代碼粘貼。這樣,Prod2會進行計算,然後您的button1_Click控制輸入以及如何處理輸出

+0

的評論謝謝,但它與我輸入的每個數字,它說不到3位數:2 – Arash 2010-12-20 14:45:45

+0

@arash - 好吧 - 我把那些放在那裏,所以你可以看到遞歸發生。刪除或註釋掉任何'Console.WriteLine'或'MessageBox.Show'行,以便它*沒有輸出。 – TheCloudlessSky 2010-12-20 14:48:58

+0

好的,當它不提供輸出我能用這個代碼做什麼? – Arash 2010-12-20 15:06:25

2

簡單地說你有一個潛在的(不同的輸入)情況:

function bigzarb() 
{ 
    bigzarb() 
} 

只要textBox7中的數字> 3,即一個未關閉的遞歸循環,這將不可避免地成爲一個棧溢出。

在有問題的線路上設置斷點,您很快就會看到問題。不知道你的方法是幹什麼的(我不認識這個算法),我無法幫忙清理它,但是第一步可能是有條件的從條件返回。但是,我也看到你在輸入參數uv被使用之前覆蓋輸入參數,所以也許你在算法中犯了錯誤?

+0

++這是正確的答案,另請參閱我的答案爲具體行 – 2010-12-20 13:48:33

+0

謝謝先生,它乘以兩個數字,用戶在textbox7中寫入兩個數字,然後它乘以數字,爲3和少於3位數字,它做一般乘法,並且對於大於4位的數字,它獲得輸入數字(n)的最大位數,然後除以2並將其放入m中,然後將u除以10^myy和w並且z如此做。在bigzarb(x, w)它用x和v替換u用w和乘以10^m再次bigzarb(x,z)+ bigzarb(w,y)... – Arash 2010-12-20 14:00:41

+0

@arash哇,慢下來......第一件事,當你說「少於3位」請再看看這些行... int intn = Convert.ToInt32(n);如果(intn <= 3)...這不是「多少數字」,而是「這個數字小於或等於3」(數值不是長度) – 2010-12-20 14:04:51

0

Pow方法返回double,所以我認爲你的x,y,z,w和z應該聲明爲double。

3

您正在進入一個無限遞歸循環在這一點上

long result = bigzarb(x, w) * Math.Pow(10, m) + (bigzarb(x, w) + bigzarb(w, y)) * Math.Pow(10, m) + bigzarb(y, z);///here 
    textBox1.Text = result.ToString(); 

我注意到這條線只有當intn > 3執行,所以也許你有一個邏輯錯誤嗎?

更新:閱讀您的意見後,我可以看到這個測試的目的是說「如果這個字符串的長度爲< = 3,那麼......」的時候,其實書面它實際上是說「如果此轉換後的字符串的值爲< = 3,則...「

+0

我應該怎麼做才能在運行時停止循環1time – Arash 2010-12-20 13:49:07

+2

@Saeed報告的錯誤是StackoverflowException而不是OverflowException,請參閱http://msdn.microsoft.com/en-us/library/system.overflowexception.aspx和http://msdn.microsoft.com/en-us/library/system.stackoverflowception.aspx – 2010-12-20 13:51:20

+0

是的你是對的+ – 2010-12-20 13:56:36

0

您正在爲遞歸調用獲取」StackoverFlow「。它更好地模擬代碼中發現的洞。我建議你改變邏輯。

static int callStack = 0;

public double bigzarb(long u, long v) 
    { 
     callStack++; 
     ............ 
     ............