题目:
Modify the guessing program of Listing 8.4 so that it uses a more intelligent guessing strategy. For example, have the program initially guess 50, and have it ask the user whether the guess is high, low, or correct. If, say, the guess is low, have the next guess be halfway between 50 and 100, that is, 75. If that guess is high, let the next guess be halfway between 75 and 50, and so on. Using this binary search strategy, the program quickly zeros in on the correct answer, at least if the user does not cheat.
Listing 8.4
/* guess.c -- an inefficient and faulty number-guesser */
#include <stdio.h>
int main(void)
{
int guess = 1;
printf("Pick an integer from 1 to 100. I will try to guess ");
printf("it.\nRespond with a y if my guess is right and with");
printf("\nan n if it is wrong.\n");
printf("Uh...is your number %d?\n", guess);
while (getchar() != 'y') /* get response, compare to y */
printf("Well, then, is it %d?\n", ++guess);
printf("I knew I could do it!\n");
return 0;
}
Code 1:
/* ex5, chptr8*/
#include <stdio.h>
#include <stdbool.h>
#define PRNT "\nI guess right!"
#define GUESS "I guess it's %d. Yes ('y') or No ('n')? "
#define THEN "Then is it %d? "
#define EXCEED "\nGuess exceeds %d!"
#define FALL "\nGuess falls under %d!"
char getinput(void);
void providechoice(int mid);
bool guessright(char equal);
void guesswork(int guess, int limit, bool direction);
int main(void)
{
char choice;
bool dir = true;
printf("\nPick a number between %d and %d and I'll try to guess it.",1, 100);
providechoice(50);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
{
providechoice(75);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
{
providechoice(87);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
{
providechoice(93);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
guesswork(94, 100, dir);
else
guesswork(92, 88, !dir);
}
else
{
providechoice(81);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
guesswork(82, 86, dir);
else
guesswork(80, 76, !dir);
}
}
else
{
providechoice(62);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
{
providechoice(68);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
guesswork(69, 74, dir);
else
guesswork(67, 63, !dir);
}
else
{
providechoice(56);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
guesswork(57, 61, dir);
else
guesswork(55, 51, !dir);
}
}
}
else
{
providechoice(25);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
{
providechoice(37);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
{
providechoice(43);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
guesswork(44, 49, dir);
else
guesswork(42, 38, !dir);
}
else
{
providechoice(31);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
guesswork(32, 36, dir);
else
guesswork(30, 26, !dir);
}
}
else
{
providechoice(12);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
{
providechoice(18);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
guesswork(19, 24, dir);
else
guesswork(17, 13, !dir);
}
else
{
providechoice(6);
choice = getinput();
if(guessright(choice))
puts(PRNT);
else if(choice == 'h')
guesswork(7, 11, dir);
else
guesswork(5, 1, !dir);
}
}
}
}
void providechoice(int mid){
printf("\nIs the number is equal ('e') to %d or is lower ('l') or higher ('h') than that?\n", mid);
}
char getinput(void)
{
char ch;
while((ch = getchar()) == '\n')
continue;
while(ch != 'e' && ch != 'h' && ch != 'l')
{
printf("%c is invalid input. Input again: ", ch);
ch = getchar();
}
return ch;
}
bool guessright(char ch)
{
bool rightornot = true;
return (ch == 'e')? rightornot : !rightornot;
}
void guesswork(int guess, int limit, bool direction)
{
char yn;
printf(GUESS, guess);
if(direction)
{
while((yn = getchar()) == '\n')
continue;
while(yn != 'y' && guess < limit)
{
getchar();
printf(THEN, ++guess);
yn = getchar();
}
if(guess <= limit)
puts(PRNT);
else
printf(EXCEED, limit);
}
else
{
while((yn = getchar()) == '\n')
continue;
while(yn != 'y'&& guess >= limit)
{
getchar();
printf(THEN, --guess);
yn = getchar();
}
if(guess >= limit)
puts(PRNT);
else
printf(FALL, limit);
}
}
Code 2:
/* Programming Exercise 8-5*/
/* binaryguess.c -- an improved number-guesser */
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int high = 100;
int low = 1;
int guess = (high + low)/2;
char response;
printf("Pick an integer from 1 to 100. I will try to guess it.\n");
printf("Respond with a 'y' if my guess is right, with an 'h' if it is high, and with an 'l' if it is low.\n");
printf("Uh...is your number %d?\n", guess);
while((response = getchar()) != 'y') /* get response */
{
if(response == '\n')
continue;
if(response != 'h' && response != 'l')
{
printf("I don't understand that response. Please enter 'h' for high, 'l' for low, or 'y' for correct.\n");
continue;
}
if(response == 'h')
high = guess - 1;
else if(response == 'l')
low = guess + 1;
guess = (high + low)/2;
printf("Well, then, is it %d?\n", guess);
}
printf("I knew I could do it!\n");
return 0;
}
这两个代码在精神上孰优孰劣就立即显现了,不用多说。