-1

Java を使用して約 5 分で Collat​​z 予想アルゴリズムを解くことができました (いいえ、証明しようとしませんでした)。

Web アプリを作成するために 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;
}

VS.net デバッガーを使用して 2 のような数値を入力すると編集すると、出力もエラーも発生しません。私は永遠に待っているだけです。無限ループだったらそのうちエラーになるよね?

いいえ、これは宿題の問題ではありません (JAVA でやったのは 2 年前のことですが :)) 私は独学で C# を学んでいます。

4

4 に答える 4

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

2 つの注意事項:

  1. ループ内で文字列連結を行う場合、 .StringBuilderではなくa を使用することをお勧めしますs = s + t。はるかに少ないメモリ割り当て。

  2. ==double 値に関しては、信頼できないことがよくあります。この場合は機能しているように見えますが、精度が低い高い数値になると機能しない場合があります。とにかくすべての数値がintになるので、それらを使用することもできます。

于 2011-02-08T06:56:43.750 に答える
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 が large よりも大きいとはどのように予想しますか? 3n+1 の部分をチェックするだけです。

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

この部分を省略して、while ループにこのチェックを処理させることができます。

于 2011-02-08T07:30:56.757 に答える
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;
}
于 2011-02-08T06:49:50.067 に答える