簡體   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