简体   繁体   English

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

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

I need some help figuring out whats wrong with my code. 我需要一些帮助来弄清楚我的代码有什么问题。

First what I'm supposed to do. 首先,我应该做的。 I'm computing the 3n+1 | 我正在计算3n + 1 | n/2 problem. n / 2问题。

If a positive number(input) is even, I n/2. 如果正数(输入)为偶数,则为I n / 2。 If odd I use 3n+1. 如果是奇数,我使用3n + 1。 I'm supposed to continue this sequence until I get to number 1. 我应该继续这个顺序,直到我获得第一名。

Steps: 脚步:

  1. Collect a range of the numbers. 收集一系列数字。 The range will serve as the n. 该范围将用作n。
  2. Find what is the longest sequence of computations. 查找最长的计算序列。
  3. Print out the longest sequence. 打印出最长的序列。

This is an example of how the execution should look like: 这是一个执行外观的示例:

  • Enter the min of the range for the sequence to start: 1 输入序列开始的范围的最小值:1
  • Enter the max of the range for the sequence to start: 5 输入序列开始的最大范围:5

The longest sequence with a start value in the range [1, 5] has 8 elements. 起始值在[1,5]范围内的最长序列有8个元素。

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

My problem so far is that I'm getting breakpoint error when I use 到目前为止,我的问题是使用时出现断点错误

sequenceLength = longestSequence(minimum, maximum);

I don't understand why this is an issue. 我不明白为什么这是一个问题。 Secondly, I'm not getting the return I want for the length of the longest sequence. 其次,对于最长序列的长度,我没有得到想要的回报。 I believe I'm not returning the right value? 我相信我没有返回正确的价值?

I'm relatively new to c++ and there's still some concepts I have to grasp! 我是C ++的新手,仍然有一些概念需要掌握! I hope you guys can help. 希望你们能帮上忙。 Here's my code. 这是我的代码。

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

These are the functions I'm supposed to use. 这些是我应该使用的功能。

getUserInput – takes two parameters start and end and asks the user to enter the min and max of the range to check. getUserInput –接受两个参数start和end并要求用户输入要检查范围的最小值和最大值。 It sets start to min and end to max. 它将开始设置为最小值,将结束设置为最大值。 The function returns nothing. 该函数不返回任何内容。

getNextElement – takes a value and returns the next value in the sequence according to the rules. getNextElement –取一个值并根据规则返回序列中的下一个值。 1 shall return 1. 1应返回1。

generateSequence – takes a start value for the sequence and a sequence string. generateSequence –接受序列的起始值和序列字符串。 It returns the length of the generated sequence starting with that start value and the sequence string is set to the generated sequence. 它从该起始值开始返回所生成序列的长度,并将序列字符串设置为所生成序列。

longestSequence - takes a start and an end value specifying the range of start values to check and a sequence string. longestSequence-接受一个起始值和一个终止值,指定要检查的起始值范围和一个序列字符串。 It returns the length of the longest sequence encountered with a start value in the range[start, end] and the sequence string is set to the longest sequence encountered. 它返回遇到的最长序列的长度,起始值在range [start,end]范围内,并将序列字符串设置为遇到的最长序列。

My problem so far is that I'm getting breakpoint error when I use "sequenceLength = longestSequence(minimum, maximum); " 到目前为止,我的问题是当我使用“ sequenceLength = longestSequence(minimum,maximum);”时出现断点错误。

Breakpoint error sounds kind of odd, so let's look at longestSequence and see what it could be doing. 断点错误听起来有点奇怪,所以让我们看一下longestSequence ,看看它可能在做什么。

int longestSequence(int minimum, int maximum) 

One immediate take-away is that minimum and maximum are not used in the function. 一个直接的收获是该函数未使用maximumminimum

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

minimum and maximum are referenced here in comments where they don't do the program any good, begging the question why not just use minimum and maximum instead of first and second ? minimummaximum在注释中引用,它们对程序没有任何帮助,请问一个问题,为什么不仅仅使用minimummaximum而不是firstsecond

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

Why would it be bad? 为什么会不好? One should always set variables to a known value. 人们应该始终将变量设置为已知值。 If you are looking for a maximum count, setting the default to 0 says there's only one way the counter can go: Up! 如果您正在寻找最大计数,则将默认值设置为0表示计数器只能通过一种方式:上升! Great movie. 好电影。 You should see it if you haven't. 如果没有,应该看到它。

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

Here using first and second instead of minimum and maximum starts causing problems. 在这里使用firstsecond而不是minimummaximum开始会引起问题。 They are both 0 resulting in one iteration of the loop: 0 <= 0 . 它们都为0,导致循环的一次迭代: 0 <= 0 getNextElement can only be called with 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    
    }

Bingo. 答对了。 This is almost exactly right. 这几乎是完全正确的。 But to see why it still fails, we have to examine getNextElement . 但是要了解为什么它仍然失败,我们必须检查getNextElement The one bit that raises an eyebrow is counter . 这就提出了一个眉毛的一个位counter Why have both length and counter ? 为什么既有length又有counter They track the same thing. 他们追踪同一件事。 When you find yourself with two variables doing the same, or almost exactly the same, thing you should stop and ask yourself why. 当您发现两个变量做的相同或几乎完全相同时,您应该停下来问自己为什么。 Odds are good that you're doing something that can be improved. 很有可能您正在做可以改进的事情。

    return max;
}

OK. 好。 So what goes wrong with getNextElement ? 那么getNextElement怎么了? Not that much, actually. 其实不多。 It just has a real problem with numbers less than 1. I'm going to strip out all of the comments because they are simply restating the obvious and add noise. 它的实际问题是数字小于1。我将删除所有注释,因为它们只是在重申明显的内容并增加噪音。

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

This is a recursive function, so yeah. 这是一个递归函数,是的。 We need an exit condition. 我们需要退出条件。 We can tweak this to better filter impossible values, but otherwise this is good. 我们可以对其进行调整,以更好地过滤不可能的值,但是这样做很好。

    {
        counter++; 

Here is counter again. 这又是counter We saw counter in longestSequence . 我们在longestSequence看到了反击。 All counter does is count. 所有计数器所做的就是计数。 longestSequence doesn't care that it counts, it only cares about the final returned count. longestSequence并不在乎它的计数,它只在乎最终返回的计数。 So why does longestSequence have any interaction with it at all? 那么,为什么longestSequence完全与之交互? To reset the counter? 要重置计数器? That can be done inside this function, removing the need for counter as a global variable. 可以在此函数内部完成,而无需将计数器作为全局变量。

If you can do away with a global, do it. 如果您可以消除全局性,那就去做。 They can lead to interesting little bugs with tentacles throughout the entire program. 它们可能导致整个程序中带有触角的有趣小错误。 It is in your best interests to keep things in as small a scope as possible so that when something does go wrong, you don't have to look at as much code to find it. 为了最大的利益,将事物保持在尽可能小的范围内,这样当出现问题时,您不必查看太多代码即可找到它。

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

The rest of this function is excellent. 此功能的其余部分非常出色。 So why does it fail? 那为什么失败呢? Let's walk through with first and second of 0: 让我们逐步了解0的firstsecond

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

So i = 0. That means 所以我=0。这意味着

    int length = getNextElement(0);

and

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

This quickly turns into 很快变成

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

For all eternity. 对于所有永恒。 Oops. 哎呀。 Sooner or later you will run out of memory and the program does weird things. 迟早您将耗尽内存,并且该程序会执行奇怪的操作。

How to fix this: 如何解决这个问题:

First, use the user input. 首先,使用用户输入。

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

Second, reject values that getNextElement cannot handle with a slightly smarter exit condition: 其次,拒绝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; 
}

The program will terminate correctly at this point, but... Third, consider reducing the scope of 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;
}

This does have a side effect of doubling the memory needed by the function, so maybe it isn't a good idea in this case. 这确实具有使功能所需的内存加倍的副作用,因此在这种情况下可能不是一个好主意。 Depends on how many iterations of getNextElement are needed. 取决于需要获取getNextElement迭代次数。

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

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