是什么让这个二叉搜索更接近最大范围

What makes this binary search move closer to the max range?

本文关键字:接近 范围 搜索 是什么      更新时间:2023-10-16

我正在制作一个小数字猜测程序(称之为我制作真实游戏的第一步)。它有两种主要模式,让用户猜测计算机的号码(我很容易),以及用户选择号码的位置,计算机必须得到它。这两种模式都适用于用户以某种形式键入"高"或"低"或"精确"以更接近答案。

但是我在使用二进制搜索让计算机找到用户选择的数字时遇到了麻烦。这一切都运行了,我能够进入模式,但是每当我按 Enter 时,它就会进入最大范围(范围从 1-100)。我担心我的二进制搜索中有一些小的逻辑故障,但从我所看到的。

在我写这篇文章的时候,我发现了一个新的错误。如果我输入猜测并猜测计算机的编号并再次键入猜测,它只会循环,直到我按选择或退出。我还没有调查过。但任何意见将不胜感激。

我自己的目标是至少进入更复杂的基于文本的游戏逻辑,或者实际上从物理图形开始。

程序本身....

#include <iostream>
#include <string>
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main(){
   int i, randomNumber, guess
        , computerGuess, middle;
   int last = 100;
   int first =1;
   string choice, answer;
   srand(time(NULL));
   randomNumber= (rand()% last + first);

   //Loop entire program until QUIT is specified.
   do{
      i = 0;
      cout << "nnGood day, I would like to play";
      cout << " a number guessing game" << endl;
      cout << "Type QUIT to quit the program n" << endl;
      cout << "Who would you like to be?" << endl;
      cout << "Guesser or picker?" << endl;
      getline(cin,choice);
      //Changes the string choice to uppercase
      while (i<choice.size()){
         choice[i] = toupper(choice[i]);
         i++;
      }
      //initiates guess mode
      if (choice.find("GUESS") != string::npos){
         cout << "You picked guess." << endl;
      while (guess != randomNumber){
         cout << "Please guess the computer's number." << endl;
         cin >> guess;
            //User guesses and computer responds
            if (guess == randomNumber){
               cout << "nYou guess right!n" << endl;
            } else if (guess > randomNumber){
               cout << "nToo high!n" << endl;
            } else if (guess < randomNumber){
               cout << "nToo low!n" << endl;
            } else {
               cout << "ERROR" << endl;
            }
          }
      }
      //Initiates pick mode
      if (choice.find("PICK") != string::npos){
            cout << "nYou want to pick the number." << endl;
            cout << "Have the number in your head?"<< endl;
            cout << "Alright, I'll guess.nn" << endl;

            //start binary search
            do{
               middle= (last+first)/2;
               cout << "Is " << middle << " the number?" << endl;
               getline (cin,answer);
               //changes answer to uppercase
               while (i<answer.size()){
               answer[i] = toupper(answer[i]);
               i++;
               }
               //add (middle+1) to first if LOW
               if (answer.find("LOW")){
                  first = middle +1;
               }else if (answer.find("HIGH")){
                  //add (middle-1) to last if HIGH
                  last = middle -1;
               }
            }while (answer.find("EXACT") == string::npos);
            cout << "So the number is " << middle << endl;
      }
   }while (choice.find("QUIT") == string::npos);
   return (0);
}

我不完全确定这是否解决了所有问题,但我确实看到了几个错误:

在注释下方的 do{.. } 循环中的代码部分中://start 二分搜索

第一个错误:转换为大写时,您有:

while (i<answer.size()){
    answer[i] = toupper(answer[i]);
    i++;
}

但是你在代码前面已经定义了我,所以当你到达程序的这一部分时,我是非零的,或者可能大于 answer.size(),那么你的字符串没有被正确转换。

所以你想要的是这样带有新索引的东西,比如 k:

int k = 0;
while (k<answer.size()){
    answer[k] = toupper(answer[k]);
    k++;
}

第二个错误:你应该在代码中使用这样的string.find():

if (answer.find("LOW")!= std::string::npos){
    first = middle + 1;
} else if (answer.find("HIGH")!= std::string::npos){
    last = middle - 1;
}

而不是列出它的方式,否则,第一个和最后一个值不会正确更新。

在这些更改之后,计算机搜索对我来说效果很好。

如果你有一个调试器,请在这些位置单步执行代码,你就会明白我的意思。