-1

我能够在大约 5 分钟内使用 Java 解决 Collat​​z 猜想算法(不,我没有试图证明它)。

现在我正在学习 C# 来制作 Web 应用程序,但我在做同样的事情时遇到了麻烦。我只是想让用户输入一个数字,单击一个按钮,然后将输出打印到一个文本框中。

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 这样的数字时,我得到 NO 输出和 NO 错误。我只能永远等待。如果它是一个无限循环,我最终会得到一个错误,对吧?

不,这不是一个家庭作业问题(虽然是 2 年前我在 JAVA 中做的 :)。)我正在独立学习 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();
}

两个注意事项:

  1. 当您在循环中进行字符串连接时,使用 aStringBuilder而不是. 是一个好习惯s = s + t。很多,更少的内存分配。

  2. ==很多时候,当涉及到双重价值时,你不能依赖。在这种情况下它似乎有效,但是当您获得精度较低的更高数字时,它可能不起作用。由于无论如何所有数字都将是整数,因此不妨使用它们。

于 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 部分再次出现冗余代码。您如何期望 x 除以 2 后大于 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 回答
0

查看方程式

  • 如果数字是偶数:n/2

  • 如果数字是奇数:3n+1

第一步:

添加一个调用的方法Collazt,该方法返回类的 int 类型的对象集合List<?>

public static List<int> Collazt(int n) {
            List<int> data = new List<int>();
            data.Add(n);

            int resul = 0;

            while (true) {

                if (n == 1) {
                    break;
                }
                if ((n % 2) == 0)
                {
                    resul = n / 2;
                    n = resul;

                }
                else {
                    resul = (n * 3) + 1;                    
                    n = resul;
                }

                data.Add(n);                
            }

            return data;
        }

第二步:

我们在主类中调用该方法。

static void Main(string[] args)
        {
            
            Console.Write("N: ");
            int r = int.Parse(Console.ReadLine());
            List<int> result = Collazt(r);
            Console.WriteLine("Lista:");
            Console.WriteLine("[");
            for (int i= 0; i<result.Count; i++) {
                Console.Write(result[i]+"\n");
            }
            Console.WriteLine("]");
        }
于 2021-12-08T05:40:19.587 回答