显示从 4 位数字到 Kaprekar 常数的过程的程序进入无限循环

Program to show the process of getting from a 4-digit number to Kaprekar's constant goes on an infinite loop

我们被要求编写一些代码,将 4 位数字作为输入,并执行以下操作:

Take any four-digit number, using at least two different digits.
Arrange the digits in descending and then in ascending order to get two four-digit numbers
Subtract the smaller number from the bigger number.
Go back to step 2 and repeat.

最终结果将始终冻结在 kaprekar 常数 1674,我们必须每次都打印算法的结果数。最后,我们还必须打印我们必须 运行 算法到达那里的次数。

我将其计算为循环,将数字存储在 2 个数组中,并一遍又一遍地对第一个按升序排序,对第二个按降序排序,直到我到达 1674 但由于某种原因,“过程”循环赢了停下来。任何帮助将不胜感激。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    long int pow1(int x, int n)
    {
        int i, result = 1;
        for (i = 0; i < n; i++)
        { // Power Function //
            result *= x;
        }
        return (result);
    }

    int a, s;
    int val[] = {
        0,
        0,
        0,
        0};
    int value[] = {
        0,
        0,
        0,
        0};
    int ex = 0;
    scanf(" %d", &a);
    if (a / 1000 != 0 && a / 1000 < 10)
    {
        // Extracting the digits and storing them in the arrays .
        for (int i = 0; i <= 3; ++i)
        {
            value[i] = val[i] = (a % pow1(10, i + 1) - a % pow1(10, i)) / pow1(10, i);
            if (i > 0)
            {
                if (val[i] == val[i - 1])
                {
                    ex++;
                }
            }
        }
        if (ex == 3)
        {
            printf("Wrong input");
            exit(0);
        }
        int j = 0, k = a;
        
        // Start of process
        while (k != 6174)
        {
            while (1)
            {
                s = 0;
                for (int i = 0; i <= 3; i++)
                {
                    if (val[i] > val[i + 1])
                    {
                        int temp = val[i];
                        val[i] = val[i + 1];
                        val[i + 1] = temp;
                        s = 1;
                    }
                }
                if (s == 0)
                {
                    break;
                }
            }
            while (1)
            {
                s = 0;
                for (int i = 0; i <= 3; i++)
                {
                    if (value[i] < value[i + 1])
                    {
                        int temp = value[i];
                        value[i] = value[i + 1];
                        value[i + 1] = temp;
                        s = 1;
                    }
                }
                if (s == 0)
                {
                    break;
                }
            }
            j++;
            printf("max:%d min: %d ", value[0] * 1000 + value[1] * 100 + value[2] * 10 + value[3], val[0] * 1000 + val[1] * 100 + val[2] * 10 + val[3]);

            k = value[0] * 1000 + value[1] * 100 + value[2] * 10 + value[3] - (val[0] * 1000 + val[1] * 100 + val[2] * 10 + val[3]);
            printf("diff:%d\n", k);
            for (int i = 0; i <= 3; ++i)
            {
                value[i] = val[i] = (k % pow1(10, i + 1) - k % pow1(10, i)) / pow1(10, i);
            }
        }
        printf("Took %d turns", j);
    }
    else
    {
        printf("Wrong input");
    }

    return 0;
}

您已将 val 和 value 定义为 4 个元素 [0..3],但在您的 loops 中,您可以通过 [0..4] 访问和修改两者,例如:val[i+1] = 温度。 我适当调整了它们的大小(int val[5] = {0},value[5] = {0}),你的测试产生了:

max:2211 min: 112 diff:2099
max:9920 min: 229 diff:9691
max:9961 min: 1699 diff:8262
max:8622 min: 2268 diff:6354
max:6543 min: 3456 diff:3087
max:8730 min: 378 diff:8352
max:8532 min: 2358 diff:6174
Took 7 turns

因为你的类型不太对。 如果您将 sort 更改为:

for (int i = 1; i < 4; i++)
{
      if (val[i-1] > val[i])
      {
          int temp = val[i];
          val[i] = val[i - 1];
          val[i - 1] = temp;
          s = 1;
      }
}

它会尊重它的边界,并且是正确的;所以你可以回到 len 4 个向量。记得把另一个也换掉。

ps:对我来说,抱怨你没有在你的例子中放置一个主包装器比在你的例子中放置一个要多得多。这不能成为你不做你能做的最少事情的借口。