2011-02-08 58 views
-1

我能夠在大約5分鐘內使用Java解決Collat​​z猜想算法(不,我沒有試圖證明它)。如何解決C#中的Collat​​z猜想算法?

既然我正在學習C#來製作網絡應用程序,那麼我也會遇到同樣的問題。 我只是想讓用戶輸入一個號碼,點擊一個按鈕,並打印輸出到一個文本框。

這裏是按鈕Click事件處理方法我用:

protected void Button3_Click(object sender, EventArgs e) 
{ 
    string x = TextBox1.Text; //user entered a number 
    string y =collatz(x);  //this function is below and returns a string 
    chatbox.Text = y;   //output 
} 

這裏是在Collat​​z方法:

public static string collatz(string y) 
{ 
    if (y == null) 
     return null; 

    double x = double.Parse(y); //x is my "n" 
    y = x.ToString(); //output string 

    double large = x; //keep track of biggest number 

    // the algorithm 
    // the redundancies (like x==1.. x!= 1) are part of troubleshooting :/ 

    while (x > 1) 
    { 
     if (x % 2 == 0) 
     { 
      x = x/2; 
      if (x > large) 
       large = x; 
      if (x != 1) 
       y = y+" "+ x.ToString(); 
      if (x == 1) 
      { 
       y = y + " " + x.ToString(); 
       y = y + " largest number was " + large; 

      } 
     } 

     if (x % 2 != 0) 
     { 
      if (x == 1) 
      { 
       y = y+" "+ x.ToString(); 
       y = y + " largest number was " + large; 

      } 

      x = (3 * x) + 1; 
      if (x > large) 
       large = x; 
      y = y+" "+ x.ToString(); 

     } 
    } 

    return y; 
} 

編輯 當我使用VS.net的調試器並輸入數字2,我得到沒有輸出和沒有錯誤。我只是一直等到永遠。如果它是一個無限循環,我最終會得到一個錯誤,對吧?

不,這不是一個家庭作業問題(這是2年前,當我在JAVA中做到這一點:)雖然我獨立學習C#。

+1

有什麼麻煩? – harpo 2011-02-08 06:35:41

+1

您忘了提及您當前的代碼究竟出了什麼問題。你有運行時異常嗎?編譯器錯誤?那個錯誤信息的內容是什麼? – 2011-02-08 06:38:59

回答

0
public static string collatz(string y) 
{ 
    if (y == null) 
     return null; 
    double x = double.Parse(y); 
    y = x.ToString(); 
    double large = x; 
    while (x > 1) { 
     if (x % 2 == 0) { 
      x = x/2;  // x reassigned 
      if (x > large) 
       large = x; 
      if (x != 1) 
       y = y + " " + x.ToString(); 
      if (x == 1) { 
       y = y + " " + x.ToString(); 
       y = y + " largest number was " + large; 

      } 
     } 
     // Infinite loop goes because of that 
     if (x % 2 != 0) { // double check on reassigned variable, use 「else」 instead 
      if (x == 1) { 
       y = y + " " + x.ToString(); 
       y = y + " largest number was " + large; 

      } 
      x = (3 * x) + 1; 
      if (x > large) 
       large = x; 
      y = y + " " + x.ToString(); 
     } 
    } 
    return y; 
} 

我試着用固定代碼(使用else),它工作正常。

此外,您不需要double類型,因爲Collat​​z使用自然數。以下是爲您的代碼添加更多.NET-ty的快速重構:

public static string collatz(string input) 
{ 
    int current = 0; 
    if (string.IsNullOrEmpty(input) || !int.TryParse(input, out current) || current < 1) { 
     return "Empty, not a number or less then 1"; 
    } 
    int max = current; 
    while (current > 1) { 
     if (current % 2 == 0) { 
      current = current/2;   // current reassigned 
      if (current > max) 
       max = current; 
      if (current != 1) 
       input = input + " " + current.ToString(); 
      if (current == 1) { 
       input = input + " " + current.ToString(); 
       input = input + " largest number was " + max; 

      } 
     } else { 
      if (current == 1) { 
       input = input + " " + current.ToString(); 
       input = input + " largest number was " + max; 
      } 
      current = (3 * current) + 1; 
      if (current > max) 
       max = current; 
      input = input + " " + current.ToString(); 
     } 
    } 
    return input; 
} 
2

您有一個無限循環。試試這個:

public static string collatz(string y) 
{ 
    if (y == null) 
    { 
     return null; 
    } 

    int x = int.Parse(y); //x is my "n" 
    var results = new StringBuilder(); 
    results.Append(x.ToString()); 
    int largest = x; //keep track of biggest number 

    // the algorithm 
    // the redundancies (like x==1.. x!= 1) are part of troubleshooting :/ 
    while (x > 1) 
    { 
     if (x % 2 == 0) 
     { 
      x = x/2; 
      if (x > largest) 
      { 
       largest = x; 
      } 
      if (x != 1) 
      { 
       results.Append(" " + x.ToString()); 
      } 
      if (x == 1) 
      { 
       results.Append(" " + x.ToString()); 
       results.Append(" largest number was " + largest.ToString()); 
       return results.ToString(); 
      } 
     } 

     if (x % 2 != 0) 
     { 
      if (x == 1) 
      { 
       results.Append(" " + x.ToString()); 
       results.Append(" largest number was " + largest.ToString()); 
       return results.ToString(); 
      } 
      x = (3 * x) + 1; 
      if (x > largest) 
      { 
       largest = x; 
      } 
      results.Append(" " + x.ToString()); 
     } 
    } 
    return results.ToString(); 
} 

有兩點需要注意:

  1. 當你在一個循環做字符串連接,它是使用StringBuilder,而不是s = s + t一個良好的習慣。很多,內存分配少得多。

  2. 很多時候你不能依靠==來談雙值。它似乎在這種情況下工作,但它可能不會在精度較低的情況下達到較高數字。由於所有的數字都將是int,所以不妨使用它們。

1
if (x == 1) 
{ 
    y = y+" "+ x.ToString(); 
    y = y + " largest number was " + large; 
} 

這裏該零件(奇數x)是多餘的。因爲如果x是1,它將永遠不會進入while循環。你的代碼似乎是邏輯上的。也許嘗試使用整數來代替。

x = x/2; 
if (x > large) 
    large = x; 

冗餘代碼再次爲偶數x部分。除了2之後,你如何期望x大於大?只需在3n + 1部分檢查即可。

if (x == 1) 
{ 
    y = y + " " + x.ToString(); 
    y = y + " largest number was " + large; 
} 

你可以把這部分留出來,讓while循環來處理這個檢查。

相關問題