我正在解决使用 C++ 的原理和实践文本中的一些问题,我遇到的具体问题如下。用户必须想到 1 到 100 之间的数字,然后计算机将通过一系列猜测找出问题是什么。
当前代码除了数字 1 之外都有效(由于除以 2 时整数会向下舍入)。我似乎想不出解决这个问题的方法。
这是当前的源代码:
#include <iostream>
using namespace std;
const int MAX_VALUE = 100;
const int MIN_VALUE = 1;
int guess;
int high = MAX_VALUE;
int low = MIN_VALUE;
char choice;
int main(){
cout<<"Think about a number between "<<MIN_VALUE<<" and "<<MAX_VALUE<<". \n\n";
guess = ( high-low ) / 2;
while((high-low)!=1){
cout<<"Is your number less than or equal to "<<guess<<"? \nEnter y or n. \n\n";
cin>>choice;
if(choice=='y' || choice=='Y') {
high = guess;
guess -= ( high - low ) / 2;
}
else if(choice=='n' || choice=='N') {
low = guess;
guess += (high - low ) /2;
}
else cout<<"Incorrect choice."<<endl;
}
cout<<"Your number is: "<<high<<".\n";
system("pause");
return 0;
}
您选择
while((high-low)!=1)
作为 while 表达式的想法是什么?
你的代码基本上是在说 - 当
high
和 low
之间的差为 1 时,正确的数字必须是 high
。这就是为什么当有人选择最低值(在本例中为 1 )时它不起作用。
您需要确保最低值
low
以 guess
的形式呈现给用户。
所以 - 单步执行你的代码:
让我们使用
MIN_VALUE
为 1 的示例,并且玩家选择 1 作为他们的想法数字。现在,当 high
为 3 并且 guess
为 2 时,您会执行 while 循环,并且因为当玩家询问他们选择的数字是否小于或等于 guess
时回答“Y”,所以 high
最终会出现如 2.
有趣的是
guess
保持在 2,因为它减少了 (high-low)/2
。向下舍入为 0。这意味着 guess
永远不会达到最低值 - 这是一个问题。
继续 - 下次计算 while 表达式时,它将返回 false (因为 2-1 == 1 )。
然后您返回
high
(当前为 2)。
所以我认为你有两个问题。
1) 当你发现自己将
guess
减少 0 时,那么玩家认为数字 has 为 low
,你应该将 guess
设置为 low
以允许将其呈现给用户作为计算机的猜测。
还有2) 当
high
和 low
之间的差为 1 时,您需要找到一种方法允许进入 while 循环。这允许当 guess
等于 low
时将其呈现给玩家
.
有人发帖
while(high > low)
我觉得还好。
但是你还需要检查
high
和 low
之间的差异何时为 1,因为 a) 你不想无休止地将 guess
减 0 和 b) 数字 必须 的想法是此时low
。
所以:
while((high>low){
cout<<"Is your number less than or equal to "<<guess<<"? \nEnter y or n. \n\n"` ;
cin>>choice;
if(choice=='y' || choice=='Y') {
high = guess;
if( high-low == 1)
{
guess = low;
}
else
{
guess -= ( high - low ) / 2;
}
}
该程序存在三个缺陷,但只解决了一个缺陷,该缺陷本身无法工作:
循环的正确退出条件是
while(guess>low)
,while(high>low)
和while(guess!=high)
都不会退出,除了当猜测的数字为1和guess=low
时。 最小值必须设置为0,
const int MIN_VALUE = 0;
否则你需要8次猜测数字1,但只允许7个问题。它还可以防止循环在满足数字 1 的条件之前退出:当达到猜测的数字时,guess 将被设置为低并退出循环:
if(high-low==1) guess=low;
else guess -= ( high - low ) / 2;
请参阅下面更正和测试的代码:
#include <iostream>
using namespace std;
const int MAX_VALUE = 100;
const int MIN_VALUE = 0;
int guess;
int high = MAX_VALUE;
int low = MIN_VALUE;
char choice;
int main(){
cout<<"Think about a number between "<<MIN_VALUE<<" and "<<MAX_VALUE<<". \n\n";
guess = ( high-low ) / 2;
while(guess>low){
cout<<"Is your number less than or equal to "<<guess<<"? \nEnter y or n. \n\n";
cin>>choice;
if(choice=='y' || choice=='Y') {
high = guess;
if(high-low==1) guess=low;
else guess -= ( high - low ) / 2;
}
else if(choice=='n' || choice=='N') {
low = guess;
guess += (high - low ) /2;
}
else cout<<"Incorrect choice."<<endl;
}
cout<<"Your number is: "<<high<<".\n";
return 0;
}
你尝试过吗:
while(high>low){
...
}
我也在看文字学习c++。
《使用 C++ 的原理与实践》第 4 章练习 4 的文本要求:
编写一个程序来玩猜数字游戏。用户想到 1 到 100 之间的数字,您的程序会提出问题来找出该数字是什么(例如,“您正在考虑的数字是否小于 50?”)。您的程序应该能够在询问不超过七个问题后识别该数字。提示:使用 < and <= operators and the if-else construct.
我试图通过在最大值和最小值之间应用经典平均值来找到解决方案,但很明显,使用整数会由于除以二而导致数据丢失。 经过多次失败的尝试后,我采用了不同的解决方案。基本上,该程序的第一部分将 1 到 100 之间的数字编码为 7 位二进制(也就是说,每次尝试使用一位;对于 1 到 100 之间的每个数字,我使用所有可用的七个位)。 观察纸上生成的值,您会发现一个奇怪的现象,即每三个数字丢失一个。基本上,数字 1 用 0000001 编码,100 用二进制 1111111 或 127 编码。 所有转换为十进制的内容都会插入向量中。然后,通过适当使用索引的 for 循环的魔力,可以找到当时正在搜索的数字与该向量的值之间的对应关系。 它的工作效率是 100%,而不是 101%,它也找到了 0。 请不要用石头砸我:)
vector <double> strangeNumbers;
for (int i = 1; i <= 100; i++)
{
int min{ 1 };
int mid{ 50 };
int max{ 100 };
int pos = i;
vector <int> binaryVector;
for (int i = 0; i < 7; ++i)
{
int hint = i + 1;
if (pos < mid)
{
max = mid;
binaryVector.push_back(0);
mid = min + (max - min) / 2;
}
else
{
min = mid;
binaryVector.push_back(1);
mid = min + (max - min) / 2;
}
}
double sum{ 0 };
int base{ 0 };
int exp{ 6 };
double val{ 0 };
for (int i = 0; i < 7; ++i)
{
if (binaryVector[i] == 0)
{
base = 0;
}
else if (binaryVector[i] == 1)
{
base = 2;
}
if (base == 2)
{
val = pow(base, exp);
}
else if (base == 0)
{
val = 0;
}
sum += val;
--exp;
}
strangeNumbers.push_back(sum);
}
bool a{ true };
while (a)
{
int min{ 1 };
int mid{ 50 };
int max{ 100 };
vector <int> binaryVector;
char check{ 0 };
for (int i = 0; i < 7; ++i)
{
int hint = i + 1;
cout << "\nIs the number you are thinking of less than " << mid << " ? (y or n)\n";
cin >> check;
if (check == 'y' || check == 'Y')
{
max = mid;
binaryVector.push_back(0);
mid = min + (max - min) / 2;
}
else if (check == 'n' || check == 'N')
{
min = mid;
binaryVector.push_back(1);
mid = min + (max - min) / 2;
}
cout << "\nHint: " << hint << "\n\n";
}
double sum{ 0 };
int base{ 0 };
int exp{ 6 };
double val{ 0 };
int thinkedNumber{ 0 };
for (int i = 0; i < 7; ++i)
{
if (binaryVector[i] == 0)
{
base = 0;
}
else if (binaryVector[i] == 1)
{
base = 2;
}
if (base == 2)
{
val = pow(base, exp);
}
else if (base == 0)
{
val = 0;
}
sum += val;
--exp;
}
for (int i = 0; i < strangeNumbers.size(); ++i)
{
if (strangeNumbers[i] == sum)
{
thinkedNumber = i + 1;
}
}
cout << "The number you thought of is : " << thinkedNumber << "\n\n";
cout << "Try again? Y or N" << "\n";
cin >> check;
if (check == 'N' || check == 'n') a = false;
cout << "\n\n";
cout << "----------------------" << "\n\n";
}
只需将最小值改为0即可解决问题。