[英]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,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)
一个直接的收获是该函数未使用maximum
和minimum
。
{
int first = 0; // minimum
int second = 0; // maximum
minimum
和maximum
在注释中引用,它们对程序没有任何帮助,请问一个问题,为什么不仅仅使用minimum
和maximum
而不是first
和second
?
int max = 0; // start of longest seqence counter. Is this bad?
为什么会不好? 人们应该始终将变量设置为已知值。 如果您正在寻找最大计数,则将默认值设置为0表示计数器只能通过一种方式:上升! 好电影。 如果没有,应该看到它。
for (int i = first; i <= second; i++)
在这里使用first
和second
而不是minimum
和maximum
开始会引起问题。 它们都为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的first
和second
:
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.