界限和整数

时间:2013-01-06 11:04:15

标签: c++ math bounds

我正在阅读Bjarne Stroustrup的“使用C ++编程原理和实践”。我在第4章,练习4。

练习如下:

  

编写程序来玩数字猜谜游戏。用户会想到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。

让我走的任何线索?我觉得我很亲密,但会感激一些帮助。

谢谢,

马特

3 个答案:

答案 0 :(得分:1)

 double range = ( upperBound - lowerBound ) / 2;

这一行会给你带来问题,因为所有操作数都是int,因此它被评估为int而不是double。如果这不是故意的,请更改2 - &gt; 2.0来解决此问题。

int rangeDelta = range - (int)range;

你确定不想要double rangeDelta

答案 1 :(得分: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;

现在最后一个问题仍然存在问题,这个问题永远都是一样的。问题是当range = 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)

您也可以使用数组来实现这一点,第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";