如何在 while 循环中存储 int 的值而不在用户输入后更改值

问题描述 投票:0回答:4

我正在尝试制作一个猜谜游戏,问题是我必须说出它花了多少次尝试,但只是为了计算独特的尝试。因此,如果我猜 1、2 和 3,则需要尝试 3 次,但如果我猜 1、1 和 2 或 1、2 和 1,则应该尝试 2 次。这是到目前为止我的游戏部分。

int g = 0;
int tries = 0;
// loop for the user to guess
while (g != numberToGuess) {
    printf("Guess a number between 0 and 99: ");
    cin >> g;
    int t1 = 0, t2 = 0;
    tries++;
    if (g < numberToGuess) {
        printf("The number is higher\n");
    }
    else if (g > numberToGuess) {
        printf("The number is lower\n");
    }
    else if (g > 100) {
        printf("Number has to be lower than 100. ");
    }
    else {
        printf("You guess the correct number. You tried %d ", tries, tries == 1 ? "time" : "times");
        break;
    }

我正在尝试获取 g,我的猜测,并将其存储以将其与最后的猜测进行比较,以确定它是否相同。

c++
4个回答
1
投票

正如已经指出的那样,你不能只存储一个变量,因为用户可以输入 1、2、3、1 等数字......所以你需要存储每个数字,最好的方法是使用数组.

    while(g != numberToGuess){
        printf("Guess a number between 0 and 99: ");
        cin >> g;
        //check if number is in array before storing it
        //you will either have to write a function or use something like std::find
        if(/*checkIfInArray*/) { 
             triesArray[tries] = g;
             tries++;
         }
         .
         .
         .
        }

如果允许您使用 std::find 搜索来了解如何使用它,如果不是,则只需创建一个函数,如果该元素在数组中,则返回 true,如果不在数组中,则返回 false


0
投票

使用 C++ std::set

C++ 提供了 std::set,它是一个包含唯一对象作为 keys 的容器。在您的情况下,对象是来自

0 - 99
的简单整数值,但对象的类型可以是任何类型。关键(没有双关语)是,由于对象存储为
std::set
的键,因此每个对象只能有一个,因此键将始终是唯一的。

因此,在您的情况下,您需要做的就是 std::set::insert 每个用户猜测,完成后该集合将保存用户所做的唯一猜测集。此时您需要做的就是获取该集合的

.size()
来获取用户的唯一条目数。

例如,您可以这样做:

#include <iostream>
#include <set>

int main (void) {
  
  int g = -1, numberToGuess = 23;     /* g, numberToGuess */
  std::set<int> guesses{};            /* set of int */
    
  /* loop for the user to guess */
  while (g != numberToGuess) {
    
    std::cout << "Guess a number between 0 and 99: ";
    
    if (!(std::cin >> g)) {
      std::cerr << "  error: invalid integer input.\n";
      return 1;
    }
    
    if (g < 0 || 99 < g) {
      std::cout << "Number must be from 0 to 99\n";
      continue;
    }
    
    guesses.insert(g);      /* insert g in set - duplicates ignored */
    
    if (g < numberToGuess) {
      std::cout << "The number is higher\n";
    }
    else if (g > numberToGuess) {
      std::cout << "The number is lower\n";
    }
    else {
      size_t tries = guesses.size();
      std::cout << "\nYou guessed the correct number. You tried " <<
                tries << (tries == 1 ? " time.\n" : " times.\n");
      break;
    }
  }
}

注意:您正在使用C++,无需将C

stdio.h
输出函数与
iostream
函数混合[有时这可能是有利的,但不是这里]。学习C++请注意使用它提供的功能。另请参阅为什么“使用命名空间 std;”被认为是不好的做法? - 对于简短的示例来说是可以的。只是要注意缺点)

示例使用/输出

./bin/numtoguess-set
Guess a number between 0 and 99: 23

You guessed the correct number. You tried 1 time.

或者更多尝试:

$ ./bin/numtoguess-set
Guess a number between 0 and 99: 50
The number is lower
Guess a number between 0 and 99: 25
The number is lower
Guess a number between 0 and 99: 10
The number is higher
Guess a number between 0 and 99: 20
The number is higher
Guess a number between 0 and 99: 22
The number is higher
Guess a number between 0 and 99: 23

You guessed the correct number. You tried 6 times.

始终确保您也处理无效的输入错误,例如

./bin/numtoguess-set
Guess a number between 0 and 99: 40
The number is lower
Guess a number between 0 and 99: What about 30?
  error: invalid integer input.

使用简单的频率数组

如果您无法使用 C++ 提供的容器,则可以使用一个简单的 Frequency Array (初始化为全零),其中数组中有一个元素对应您需要跟踪唯一性或计数的每个可能值。当用户输入一个值时,您只需增加数组中该元素的数字即可。 (例如

guesses[g] += 1;
)当您需要确定猜测的唯一数量时,只需循环遍历数组并计算不为零的元素数量即可。1

重写代码以使用频率数组只需将

std::set
替换为您的数组,例如

#include <iostream>

#define VALUES_IN_RANGE 100

int main (void) {
  
  int g = -1, numberToGuess = 23,     /* g, numberToGuess */
      guesses[VALUES_IN_RANGE] = {0}; /* array of 100 int initialized zero */
  
  /* loop for the user to guess */
  while (g != numberToGuess) {
    
    std::cout << "Guess a number between 0 and 99: ";
    
    if (!(std::cin >> g)) {
      std::cerr << "  error: invalid integer input.\n";
      return 1;
    }
    
    if (g < 0 || 99 < g) {
      std::cout << "Number must be from 0 to 99\n";
      continue;
    }
    
    guesses[g] += 1;    /* add one to the element at g */
    
    if (g < numberToGuess) {
      std::cout << "The number is higher\n";
    }
    else if (g > numberToGuess) {
      std::cout << "The number is lower\n";
    }
    else {
      int tries = 0;
      
      /* loop over array to get number of unique tries */
      for (int i = 0; i < VALUES_IN_RANGE; i++) {
        if (guesses[i]) {   /* if element non-zero */
          tries += 1;       /* add 1 to tries */
        }
      }
      
      std::cout << "\nYou guessed the correct number. You tried " <<
                tries << (tries == 1 ? " time.\n" : " times.\n");
      break;
    }
  }
}

(输出相同)

在这里,由于您不关心每个猜测的计数,只关心用户是否猜测了该数字,因此您可以将数组设为

char
数组,并简单地设置
guesses[g] = 1;
每个节省 3 个字节- 存储中的元素。如果您要处理的值范围很大并且只需要唯一性,则需要考虑一些事情。

最后,这是一个提示,请将代码留出更多空间。这使得它更容易阅读和维护(特别是对于眼睛老的人来说)。您甚至可能会发现,当不查看所有表达式和运算符都紧密包装在一起的代码时,它可以让您更轻松地查找和解决错误。由你决定。

有两种方法可以解决这个问题。如果您还有其他问题,请告诉我。

脚注:

1. 在回答如何删除 C 中字符串中的重复字符时提供了对频率数组

的更完整解释

0
投票

我使用 std::set 得到了它

int g = -1;
int tries;
set<int> guesses{};
while(g != numberToGuess){
    printf("Guess a number between 0 and 99: ");
    if(!(cin >> g)){
       printf("Error: Invalid input\n");
       return 1;
    }
    if (g > 100 || g < 0) {
       printf("Number has to be between 0 and 99.\n");
       continue;
    }
    guesses.insert(g);
    if (g > numberToGuess) {
       printf("The number is lower\n");
    } else if (g < numberToGuess) {
       printf("The number is higher\n");
    } else {
       size_t tries = guesses.size();
       printf("You guess the correct number. You tried %d %s ", tries, (tries == 1 ? "time\n" : "times\n"));
       break;
    }
}

虽然 git hub 自动评分不合作


0
投票

我建议你省点麻烦。 for 循环可以管理递增

tries
并在做出正确猜测时终止循环。

由于循环仅在猜测正确时退出,因此成功消息也可能出现在循环之后。只要

tries
不是循环本地的,之后仍然可以打印。

我展示了如何使用

continue
跳过循环体的其余部分,并在输入不正确时进入下一次迭代。

int g = -1;
int tries;

for (tries = 1; g != numberToGuess, tries++) {
    cout << "Guess a number between 0 and 99: ";
    cin >> g;
    
    if (g < 0 || g > 99) {
        cout << "Number has to be between 0 and 100.\n";
        continue;
    }
    
    if (g < numberToGuess) {
        cout << "The number is higher.\n";
    }
    else {
        cout << "The number is lower.\n";
    }
}

cout << "You guessed the correct number. You tried " 
     << tries << (tries == 1 ? "time" : "times")
     << endl;
© www.soinside.com 2019 - 2024. All rights reserved.