在给定长度无限循环的Collat​​z Conjecture中查找起始编号的代码

时间:2017-10-19 01:56:11

标签: c++ collatz

我基本上在标题中说过,但我正在尝试编写一个程序,它会给出最小长度的起始整数。我编写了一个不同的程序来计算给定起始整数的长度,但是我有很多很多的麻烦逆转它,即使使用前面的代码作为基础。我把目标长度设为3,这应该在x = 2时停止代码,但事实并非如此。相反,它是循环的,但我不确定为什么。

#include <iostream>
#include <cmath>

using namespace std;

int main()
{
   char choice; //whether the program will run again

   do
   {
      int x = 1; //starting integer
      int targetK = 0; //desired minimum length
      int i = 0; //number of iterations run
      int lengthK = 0; //length of sequence

      cout << "\nEnter a required length." << endl;
      cin >> targetK;

      while (lengthK < targetK)
      {
         int lengthK = 1; //length of sequence

         do
         {
            cout << x << endl;

            if (x % 2 == 0)
            {
               x /= 2;
            }
            else
            {
               x = x * 3 + 1;
            }
            lengthK++;
         } while (x != 1);

         i++;
         x += i;
      }

      cout << x;
      cout << "\nLength of sequence before repeating: " << lengthK << endl;
      cout << "Would you like to run the function again? (Y/N)" << endl;
      cin >> choice;
   } while (choice == 'y' || choice == 'Y');

   return 0;
}

cout就是这样,我知道它运作正常 - 或者,在这种情况下,我知道它不是。

1 个答案:

答案 0 :(得分:0)

因此,我发现您的代码存在四个问题。首先,在while循环中使用语句lengthK创建一个新的局部变量int lengthK = 1;。此变量与您在循环外使用的变量具有相同的名称,用于测试终止条件,但它是一个不同的变量。由于除了在循环内增加值之外你什么都不做,我假设这是一个错误,你真的打算使用你先声明的变量。这是无限循环的主要原因。

您只需说出lengthK = 1;即可解决此问题。只需删除int,您将不再声明一个全新的变量,其生命周期仅限于循环,而是改变现有变量的值。我实际上认为它应该是lengthK = 0;,但这在很大程度上取决于其他细节。

我看到的第二个问题是你正在做x += i;。我很确定你只想要x = i;,尽管x += i;可能会意外地工作,因为当x到达那段代码时x总是1。 x = i;肯定会更清楚。

第三个问题也很棘手,因为很难确切地知道你的意图。但我认为你需要一个while循环,测试位于顶部而不是do循环用于内循环。

最后一个问题更容易,只会影响输出的有用性,而不会影响算法的正确性。您可能希望打印出x - 1而不是x,因为x实际上为您提供足够长的Collat​​z链的值比x退出循环时的值小1

我冒昧地编辑你的问题来收紧你的代码。细心的缩进是一个非常好的习惯,我很高兴看到它。但是过多的空白几乎和太少一样糟糕。

以下是我修改过的代码版本,以便解决您的问题。我在大多数地方删除了endl,因此速度会更快。

#include <iostream>
#include <cmath>

using namespace std;

int main()
{
   char choice; //whether the program will run again

   do
   {
      int x = 1; //starting integer
      int targetK = 0; //desired minimum length
      int i = 0; //number of iterations run
      int lengthK = 0; //length of sequence

      cout << "\nEnter a required length." << endl;
      cin >> targetK;

      do
      {
         ++i;
         x = i;
         lengthK = 1; //length of sequence

         cout << "Testing " << x << "\n  ";
         while (x != 1)
         {
            cout << x << " -> ";

            if (x % 2 == 0)
            {
               x /= 2;
            }
            else
            {
               x = x * 3 + 1;
            }
            lengthK++;
         }
         cout << "1\n";
      } while (lengthK < targetK);

      cout << i;
      cout << "\nLength of sequence before repeating: " << lengthK << endl;
      cout << "Would you like to run the function again? (Y/N)" << endl;
      cin >> choice;
   } while (choice == 'y' || choice == 'Y');

   return 0;
}