繁体   English   中英

3n + 1问题。 为什么会出现断点错误,如何返回计数器“ Max”

[英]3n+1 Issue. Why do I get a breakpoint error, and how can I return my counter “Max”

我需要一些帮助来弄清楚我的代码有什么问题。

首先,我应该做的。 我正在计算3n + 1 | n / 2问题。

如果正数(输入)为偶数,则为I n / 2。 如果是奇数,我使用3n + 1。 我应该继续这个顺序,直到我获得第一名。

脚步:

  1. 收集一系列数字。 该范围将用作n。
  2. 查找最长的计算序列。
  3. 打印出最长的序列。

这是一个执行外观的示例:

  • 输入序列开始的范围的最小值:1
  • 输入序列开始的最大范围:5

起始值在[1,5]范围内的最长序列有8个元素。

3, 10, 5, 16, 8, 4, 2, 1 

到目前为止,我的问题是使用时出现断点错误

sequenceLength = longestSequence(minimum, maximum);

我不明白为什么这是一个问题。 其次,对于最长序列的长度,我没有得到想要的回报。 我相信我没有返回正确的价值?

我是C ++的新手,仍然有一些概念需要掌握! 希望你们能帮上忙。 这是我的代码。

#include <iostream>
using namespace std;
// Functions
string generateSequence(); // A print of the longest sequence. To be made. I can't figure it out yet. Arrays?
int counter = 1; // To start out the counter in getNextElement
void getUserInput(int &start, int &end) // collects the user input for minimum and maximum
{
    cout << "Enter the min of the range for the sequence to start " << endl;
    cin >> start;
    cout << "Enter the max of the range for the sequence to start " << endl;
    cin >> end;
}
int getNextElement(int x) // // This function does the 3n+1 computation
{
    if (x != 1) // Checks for the end of the sequence. The end being when the number is 1.
    {
        counter++; //this is the counter for the number of times the sequence is done with the specific number.
        if (x % 2 == 0) // checks if its even
            getNextElement(x / 2); // takes the new number through the function again
        else
            getNextElement(x * 3 + 1); // takes the new number into the function again
    }
    return counter; // this is returned as length in the longestSequence function. No?
}

int longestSequence(int minimum, int maximum) // this function compares all the sequence lengths within the range of minimum and maximum.
{
    int first = 0; // minimum
    int second = 0; // maximum
    int max = 0; // start of longest sequence counter. Is this bad?

    for (int i = first; i <= second; i++)
    {
        int length = getNextElement(i); // length is a temp that will hold the largest sequence    

        if (length > max) // this loop validates if the newest "length" from the sequence is bigger than the previous one       
            max = length; // after the first run of the loop, max stores the longest sequence, and updates it after each run of the for loop if its longer
        counter = 1; // resets the counter to 1. This counter is length    
    }
    return max;
}

int main()
{
    int minimum;
    int maximum;
    int sequenceLength;
    getUserInput(minimum, maximum); // retrieves user input

    sequenceLength = longestSequence(minimum, maximum); // starts longest sequence counter

    cout << sequenceLength;
    cout << "This is the end of main. Nothing is after this" << endl;

    return 0;
}

这些是我应该使用的功能。

getUserInput –接受两个参数start和end并要求用户输入要检查范围的最小值和最大值。 它将开始设置为最小值,将结束设置为最大值。 该函数不返回任何内容。

getNextElement –取一个值并根据规则返回序列中的下一个值。 1应返回1。

generateSequence –接受序列的起始值和序列字符串。 它从该起始值开始返回所生成序列的长度,并将序列字符串设置为所生成序列。

longestSequence-接受一个起始值和一个终止值,指定要检查的起始值范围和一个序列字符串。 它返回遇到的最长序列的长度,起始值在range [start,end]范围内,并将序列字符串设置为遇到的最长序列。

到目前为止,我的问题是当我使用“ sequenceLength = longestSequence(minimum,maximum);”时出现断点错误。

断点错误听起来有点奇怪,所以让我们看一下longestSequence ,看看它可能在做什么。

int longestSequence(int minimum, int maximum) 

一个直接的收获是该函数未使用maximumminimum

{
    int first = 0; // minimum
    int second = 0; // maximum

minimummaximum在注释中引用,它们对程序没有任何帮助,请问一个问题,为什么不仅仅使用minimummaximum而不是firstsecond

    int max = 0; // start of longest seqence counter. Is this bad?

为什么会不好? 人们应该始终将变量设置为已知值。 如果您正在寻找最大计数,则将默认值设置为0表示计数器只能通过一种方式:上升! 好电影。 如果没有,应该看到它。

    for (int i = first; i <= second; i++)

在这里使用firstsecond而不是minimummaximum开始会引起问题。 它们都为0,导致循环的一次迭代: 0 <= 0 getNextElement只能用0调用。

    {
        int length = getNextElement(i); 
        if (length > max) // this loop validates if the newest "length" from the sequence is bigger than the previous one       
            max = length; // after the first run of the loop, max stores the longest seqence, and updates it after each run of the for loop if its longer
        counter = 1; // resets the counter to 1. This counter is length    
    }

答对了。 这几乎是完全正确的。 但是要了解为什么它仍然失败,我们必须检查getNextElement 这就提出了一个眉毛的一个位counter 为什么既有length又有counter 他们追踪同一件事。 当您发现两个变量做的相同或几乎完全相同时,您应该停下来问自己为什么。 很有可能您正在做可以改进的事情。

    return max;
}

好。 那么getNextElement怎么了? 其实不多。 它的实际问题是数字小于1。我将删除所有注释,因为它们只是在重申明显的内容并增加噪音。

int getNextElement(int x) 
{
    if (x != 1) 

这是一个递归函数,是的。 我们需要退出条件。 我们可以对其进行调整,以更好地过滤不可能的值,但是这样做很好。

    {
        counter++; 

这又是counter 我们在longestSequence看到了反击。 所有计数器所做的就是计数。 longestSequence并不在乎它的计数,它只在乎最终返回的计数。 那么,为什么longestSequence完全与之交互? 要重置计数器? 可以在此函数内部完成,而无需将计数器作为全局变量。

如果您可以消除全局性,那就去做。 它们可能导致整个程序中带有触角的有趣小错误。 为了最大的利益,将事物保持在尽可能小的范围内,这样当出现问题时,您不必查看太多代码即可找到它。

        if (x % 2 == 0) 
            getNextElement(x / 2); 
        else
            getNextElement(x * 3 + 1); 
    }
    return counter; 
}

此功能的其余部分非常出色。 那为什么失败呢? 让我们逐步了解0的firstsecond

for (int i = 0; i <= 0; i++)

所以我=0。这意味着

    int length = getNextElement(0);

int getNextElement(0)
{
    if (0 != 1) // always true
    {
        counter++; 
        if (0 % 2 == 0) // always even
            getNextElement(0 / 2);  // always calls getNextElement(0) again
        else
            getNextElement(0 * 3 + 1); 
    }
    return counter; 
}

很快变成

counter++;
getNextElement(0);
counter++;
getNextElement(0);
counter++;
getNextElement(0);
counter++;
getNextElement(0);
counter++;
getNextElement(0);

对于所有永恒。 哎呀。 迟早您将耗尽内存,并且该程序会执行奇怪的操作。

如何解决这个问题:

首先,使用用户输入。

int longestSequence(int minimum, int maximum) 
{
    int max = 0; 
    for (int i = minimum; i <= maximum; i++)
    {
        int length = getNextElement(i); 
        if (length > max) 
            max = length; 
        counter = 1; 
    }
    return max;
}

其次,拒绝getNextElement无法以更智能的退出条件处理的值:

int getNextElement(int x)
{
    if (x > 0) // only execute if x can be processed
    {
        counter++; 
        if (x % 2 == 0) 
            getNextElement(x / 2); 
        else
            getNextElement(x * 3 + 1); 
    }
    return counter; 
}

该程序将在此时正确终止,但是...第三,考虑减小计数器的范围

int getNextElement(int x, 
                   int counter = 1) // if counter is not provided it will be set to 1
{
    if (x > 0) // only execute if x can be processed
    {
        counter++; 
        if (x % 2 == 0) 
            getNextElement(x / 2, counter); 
        else
            getNextElement(x * 3 + 1, counter); 
    }
    return counter; 
}

int longestSequence(int minimum, int maximum) 
{
    int max = 0; 
    for (int i = minimum; i <= maximum; i++)
    {
        int length = getNextElement(i); 
        if (length > max) 
            max = length; 
    }
    return max;
}

这确实具有使功能所需的内存加倍的副作用,因此在这种情况下可能不是一个好主意。 取决于需要获取getNextElement迭代次数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM