2013-01-06 60 views
0

我正在經歷Bjarne Stroustrup的「使用C++編程原則和實踐」。我在第4章,行使4.界限和整數

的鍛鍊; Tibial如下:

寫一個程序,玩數字猜謎遊戲。用戶認爲數字在1到100之間,程序會提出問題來確定數字是什麼(例如,「您的數字是否小於50?」)。在詢問不超過七個問題後,你的程序應該能夠識別這個數字。提示:使用<和< =運算符和if-else結構。

現在,這是偉大的,我已經設法實現這一罰款。

我以爲我會嘗試和推動自己,嘗試和實現這個使用循環,並調整每次下限或上限。

這裏是我的代碼:

#include "std_lib_facilities.h" 

int main(){ 
    int count = 0; 
    int lowerBound = 0; 
    int upperBound = 100; 
    string userInput = ""; 

    while (lowerBound != upperBound){ 
    // Increment count 
    ++count; 

    int halfRange = 0; 

    // Make halfRange a while number, round up if any decimal portion. 
    double range = (upperBound - lowerBound)/2; 

    int rangeDelta = range - (int)range; 

    if (rangeDelta != 0) 
     halfRange = (int)range + 1; 
    else 
     halfRange = range; 

    cout << count <<": Is your number between " << lowerBound << " and " << lowerBound + halfRange << "? "; 
    cin >> userInput; 

    // Reset the bounds 
    if (userInput == "y" || userInput == "Y") 
     upperBound -= halfRange; 
    else if (userInput == "n" || userInput == "n") 
     lowerBound += halfRange; 
    else { 
     --count; 
     cout << "Error! Answer could not be understood."; 
    } 
    } 

    cout << "lowerBound: " << lowerBound << ", upperBound: " << upperBound << "\n\n"; 
    cout << "Your number is: " << lowerBound << "\n"; 

    return 0; 
} 

的問題?那麼,它發生在有小數部分的數字和使用整數除法的情況下,這會導致小數部分丟失。如果你使用數字48,程序會猜到47和47.

任何線索讓我走?我覺得我很接近,但會感謝一些幫助。

感謝,

馬特

+0

聽起來好像這將是作爲'INT halfRange =標準::小區更好地實現本;'。 'ceil'接受一個浮點數並返回。或者,它看起來像'std :: rint'總是向上舍入的風格會做的伎倆,並返回一個整數類型。 – chris

+3

說實話,我會擺脫浮點數*完全*。 – NPE

+0

@NPE,沒錯,在這裏這樣做並不差。 – chris

回答

0

我認爲還有在你的代碼(即使該錯誤之前的固定信號)的問題:應該明確的是,上界和下界都包括在可能的數字剩餘,這是不清楚從你的代碼:在第一個問題,如果我回答'y',新的區間是[0,50],如果我回答'n',新的區間是[50,100],這是錯誤的! 50不應該包含在第二個時間間隔中。

爲了解決這個問題,你應該將範圍的更新更改爲類似:

if (userInput == "y" || userInput == "Y") 
    upperBound = lowerBound + halfRange; 
else if (userInput == "n" || userInput == "n") 
    lowerBound = lowerBound + halfRange + 1; 

現在還有與最後一個問題,它仍然是相同的一個永遠的問題。問題是,當範圍= 1時,半角= 1,問題保持不變。

要解決該問題,您應該圍繞下降範圍。只需將其定義爲:

int halfRange = (upperBound - lowerBound)/2; 

現在您的代碼應該可以工作。下面是我會用while循環代碼:

while (lowerBound != upperBound){ 
// Increment count 
++count; 

int halfRange = (upperBound - lowerBound)/2; 
int midpoint = lowerBound + halfRange; 

cout << count <<": Is your number between " << lowerBound << " and " << midpoint << "? (both included) "; 
cin >> userInput; 

// Reset the bounds 
if (userInput == "y" || userInput == "Y") 
    upperBound = midpoint; 
else if (userInput == "n" || userInput == "n") 
    lowerBound = midpoint + 1; 
else { 
    --count; 
    cout << "Error! Answer could not be understood."; 
} 

}

備註,現在我們只使用整數,沒有雙可言!如果你使用整數,儘量避免通過double,並使用整數除法和模數來處理它們(並且不要用double來表示整數)。

希望它有幫助! ( - 下界)/ 2.0(UPPERBOUND)

1
double range = (upperBound - lowerBound)/2; 

此行會給你的問題,因爲所有的操作數int因此其被評估爲int,而不是爲double。如果這不是故意的,請更改2 - >2.0以解決此問題。

int rangeDelta = range - (int)range; 

而且你肯定不想double rangeDelta

+0

謝謝,這有些幫助。在最後一個問題中,我的問題仍然是縮小數字。我正在將halfRange添加到導致問題的upperBound或lowerBound – SwiftlyDone

+0

@SwiftlyDone我不太確定..也許你可以在紙上做出來,看看它出錯了。 –

0

也可以與陣列,其由章說明4.

int min = 1; // range for our guessing game 
int max = 10; 
int guess = 0; // value to keeep track of guessing 
char choice = ' '; 
vector<int>v; 

// put all our values into a vector 
for(int i = min; i <= max; i++) { 
    v.push_back(i); 
} 


while (v.size() != 1) { // if there is only one value left, no guessing needed. jump out of loop 

    guess = v[v.size()/2]; // find median 

    cout << "\nIs your number less than " << guess << "? (y/n)\n"; // ask user for hint 
    cin >> choice; 

    if(choice == 'y') { //y: value is below median, pop values of median and above out of our range of values 
     for(int i = 0; i < v.size(); i++) 
     v.pop_back(); 
    } 
    else { // n: value is median or above. erase the lower values out of our range of values 
     for(int i = 0; i < v.size(); i++){ 
      v.erase(v.begin()); 
     } 
    } 
} // end while 
cout << "The number is " << v[0] << "\n";