[英]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.