2011-02-08 1 views
-1

Я смог решить алгоритм гипотезы Collatz (нет, я не пытался его доказать) примерно через 5 минут с использованием Java.Как я могу решить алгоритм гипотезы Collatz в C#?

Теперь, когда я изучаю 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 
} 

А вот метод Коллатца:

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; 
} 

EDIT , когда я использую vs.net отладчик и введите число, подобное 2, я получаю NO output и NO error. Я просто остаюсь ждать навсегда. Если бы это был бесконечный цикл, в конечном итоге я получил бы ошибку, верно?

и нет, это не проблема домашних заданий (это было 2 года назад, когда я сделал это в JAVA, хотя :).) Я изучаю C# самостоятельно.

+1

В чем проблема? – harpo

+1

Вы забыли упомянуть, что именно не так с вашим текущим кодом. Вы получаете исключение во время выполнения? Ошибка компилятора? Какой текст сообщения об ошибке? –

+0

Это звучит как домашнее задание для меня, не так ли? Если да, пожалуйста, отметьте соответствующим образом. =) –

ответ

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, так как Collatz работает с натуральными числами. Ниже приведен быстрый рефакторинг для добавления большего количества .NET-кода в код:

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; 
} 
+0

WoooooooooooooooW так сильно. – tmp

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 равно 1, он никогда не войдет в цикл while. Ваш код кажется логичным. Возможно, попробуйте использовать целое число.

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

Резервный код еще раз для части x. Как вы ожидаете, что x будет больше, чем большой после деления на 2? Просто проверьте это в части 3n + 1.

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

Вы можете просто оставить эту деталь и разрешить цикл while обрабатывать эту проверку.

Смежные вопросы