如何在 C# 中解决 Collat​​z 猜想算法?

发布于 2024-10-16 12:23:05 字数 1727 浏览 2 评论 0原文

我能够使用 Java 在大约 5 分钟内解决 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#。

I was able to solve the Collatz conjecture algorithm (no, i didn't try to prove it) in about 5 minutes using Java.

Now that I'm learning C# to make web apps, I'm running into trouble doing the same thing.
I simply want the user to enter a number, click a button, and print the output to a text box.

Here is the button Click event handler method I'm using:

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
}

And here is the Collatz method:

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
when I use the VS.net debugger and enter a number like 2, I get NO output and NO error. I'm just left waiting forever. If it were an infinite loop, I would get an error eventually, right?

and no, this is not a homework problem (it was 2 years ago when I did it in JAVA though :).) I'm learning C# independently.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

陪我终i 2024-10-23 12:23:05

你有一个无限循环。试试这个:

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,因此不妨使用它们。

You had an infinite loop. Try this:

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

Two notes:

  1. When you're doing string concatenation in a loop, it's a good habit to use a StringBuilder rather than s = s + t. Lots, lots less memory allocations.

  2. A lot of times you can't rely on == when it comes to double values. It seems to work in this case, but it might not when you get to higher numbers where there's less precision. Since all the numbers are going to be int's anyway, might as well use those.

探春 2024-10-23 12:23:05
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 循环处理此检查。

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

This part here (odd x) is redundant. For if x is 1, it will never enter the while loop. Your code seems logically. Maybe try using integer instead.

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

Redundant code again for even x part. How do you expect x to be bigger than large after division by 2? Just check it in the 3n+1 part will do.

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

You can just leave this part out and let the while loop handle this check.

无人问我粥可暖 2024-10-23 12:23:05
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 风格的快速重构:

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

I tried it with fixed code (using else) and it works fine.

Also, you don't need double type since Collatz works with natural numbers. The following is a quick refactoring to add more .NET-ty to your code:

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;
}
2024-10-23 12:23:05

查看方程

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


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

第一步:

添加一个名为 Collazt 的方法,该方法返回 List 类的 int 类型对象的集合

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

View Equation:

  • if the number is even: n/2

  • if the number is odd: 3n+1

Step One:

Add a method called Collazt which returns a collection of objects of type int of class 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;
        }

Step Two:

We call the method in our main class.

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("]");
        }
情话墙 2024-10-23 12:23:05
        string restart;
        do
        {
        Console.WriteLine("Type a Whole Number");
        double n = Convert.ToDouble(Console.ReadLine());

        do
        {double a = n;

    if (n % 2 == 0)
        {
            Console.WriteLine("Even");
            n = a / 2;
            Console.WriteLine(n);
        }
        else
        {
            Console.WriteLine("Odd");
            n = (3*a) + 1;
            Console.WriteLine(n);
        }
        }
        while (n != 1);
        Console.WriteLine("Yo Wanna Restart? Type y and press enter");
        restart = Console.ReadLine();
        Console.Clear();
        }
        while (restart == "y");



        Console.ReadKey(true);

(不是专业程序员,只是为了好玩,我知道有更好的方法)

        string restart;
        do
        {
        Console.WriteLine("Type a Whole Number");
        double n = Convert.ToDouble(Console.ReadLine());

        do
        {double a = n;

    if (n % 2 == 0)
        {
            Console.WriteLine("Even");
            n = a / 2;
            Console.WriteLine(n);
        }
        else
        {
            Console.WriteLine("Odd");
            n = (3*a) + 1;
            Console.WriteLine(n);
        }
        }
        while (n != 1);
        Console.WriteLine("Yo Wanna Restart? Type y and press enter");
        restart = Console.ReadLine();
        Console.Clear();
        }
        while (restart == "y");



        Console.ReadKey(true);

(not a professional programmer, made it for fun, i know there are better ways)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文