【问题标题】:How do check an array for repeat numbers in c++? [closed]如何在 C++ 中检查数组中的重复数字? [关闭]
【发布时间】:2017-10-11 15:11:00
【问题描述】:

我正在尝试生成一个包含 4 个随机生成的 [srand seeded rand()] 的数组,没有任何重复。我正在使用 for 循环:

在数组中选择一个位置, 生成一个数字, 将编号分配给当前突出显示的位置 根据以下伪代码检查分配的数字是否不等于先前的条目。

if no - 
    Then select the next position in the array and generate a new number
if yes -
    Do not move to the next array position and generate a new number again.

repeat until array position 3

这是我的尝试:

int operator_selection;
int operator_index[3];
int random_value;
for (operator_selection = 0; operator_selection < 4; operator_selection++)
{
    random_value = rand() %4 + 1;

    if (random_value = operator_index[0] || operator_index[1] || operator_index[2])
    {
        (operator_selection - 1);
    }
    operator_index[operator_selection] = random_value;
    cout<<operator_index[operator_selection]<<" ";

    if (operator_selection == 3)
    {
        cout<<endl;
    }
}

但是,当我运行可执行文件时,我总是以重复结束,所以我很确定我的第一个“if 语句”背后的逻辑是有缺陷的。

我是一名 C++ 初学者,这是我第三次尝试从头开始编写源文件,如果我犯了一个愚蠢的错误,敬请见谅。

【问题讨论】:

  • 如果您需要存储唯一值,请使用 std::set
  • 除了错误写入的条件之外,您还有未定义的行为。在分配元素之前,您不能检查它的值。例如,在第一次迭代中,只有 operator_index[0] 被赋值,但随后您检查索引 1 和 2 处的元素。您应该重新考虑只验证先前定义的元素的方法。此外,您可以确定,如果您为元素 0 分配一个值,那么该元素的值将等于您刚刚分配给它的值。
  • 用唯一值填充您的数组(不是随机的,1,2,3 ... 很明显),然后使用std::random_shuffle 使它们随机化。
  • 顺便说一句,检查数组值是否唯一的简单方法:array_size == std::set( array_begin, array_end ).size()
  • 所示代码中有多个错误,包括逻辑错误和语言错误。 “if (random_value = operator_index[0] || operator_index[1] || operator_index[2])”——这在许多基本方面都是完全错误的。你真的需要阅读一本好的 C++ 书籍。 C++ 根本无法以这种方式工作。 “(operator_selection - 1);”——这绝对没有任何作用。真的:去读一本好的 C++ 书。抱歉,此代码不可挽救。

标签: c++ arrays c++11 random logic


【解决方案1】:

我在您发布的代码中发现了几个问题。

问题 1

线

if (random_value = operator_index[0] || operator_index[1] || operator_index[2])

没有做你希望做的事。你需要使用:

if ( (random_value == operator_index[0]) || 
     (random_value == operator_index[1]) ||
     (random_value == operator_index[2]) )

问题 2

比较 random_valueoperator_index[0]operator_index[1]operator_index[2] 是不正确的。你只需要比较operator_index[operator_selection-1]

问题 3

线

(operator_selection - 1);

不会更改operator_selection 的值。它只是计算表达式并丢弃值。

您需要一个减少operator_selection 值的语句。例如

--operator_selection;

问题 4

当你找到一个现有值时,你需要继续循环的下一次迭代。


这是循环的更新版本:

for (operator_selection = 0; operator_selection < 4; operator_selection++)
{
   random_value = rand() %4 + 1;

   bool matchFound = false;
   for ( int i = 0; i < operator_selection-1; ++i )
   {
      if ( random_value == operator_index[i] )
      {
         matchFound = true;
         break;
      }
   }

   if ( matchFound )
   {    
      --operator_selection;
      continue;
   }

   operator_index[operator_selection] = random_value;
   cout<<operator_index[operator_selection]<<" ";
}

// Move this out of the loop.
cout<<endl;

【讨论】:

  • 感谢您的帮助,完全按照我现在的预期工作,感谢您对错误的解释。我知道它很笨重,但我打算以此为基础。
【解决方案2】:

这是一个使用std::arraystd::random_shuffle的版本:

#include <iostream>
#include <array>
#include <algorithm>
#include <random>

int main()
{ 
    std::array<int, 4> a = {1, 2, 3, 4};
    std::random_device rd;
    std::mt19937 g(rd());
    std::shuffle(a.begin(), a.end(), g);
    for(auto& i : a)
        std::cout << i << " ";
}

Live Demo

这个版本更具可读性和效率。

更新:这并不能按原样回答问题,如果它是家庭作业,则不适合。但我会把它留在这里,以防 OP 对更好的选择感兴趣。

【讨论】:

  • 这可能会产生正确的结果,但无法解决原始代码的多个基本问题,因此并不能真正回答原始代码有什么问题的问题,在每个大大地。当然,这是一项艰巨的任务,因为几乎所有事情都错了。这里的正确答案是,真的,“读一本 C++ 书”。
  • 我删除了我的反对票,但同意 Sam,现在答案不再真正回答问题了
  • @SamVarshavchik 是的,我同意。无论如何,我会把它挂起来以防万一。
【解决方案3】:

首先,您需要使阵列更大。如前所述,使用 std::array 会更好,但我会坚持使用旧样式。您定义 operator_index 的维度为 3,它只允许 3 个元素(偏移量从 0 到 2)。所以这需要一个维度为 4。

您还应该初始化数组的内容(或确保您永远不会从未初始化的元素中读取)。

接下来,对于第一个随机数,不可能发生冲突。所以可以直接放入数组中。

operator_index[0] = rand() %4 + 1;

然后您可以从 1 循环到 3 以获取剩余的 3 个条目。

你甚至可以比这更进一步。当你填写了前3个条目后,你可以直接计算最后一个,

operator_index[3] = 10 - operator_index[2] - operator_index[1] - operator_index[0];

(1到4的和是10,所以最后一个元素是10——前三个的和

你的代码的主要问题是这个

if (random_value = operator_index[0] || operator_index[1] || operator_index[2])
{
    (operator_selection - 1);
}

这是一个赋值,而不是一个相等性检查。它被分配了前 3 个元素的逻辑或。由于您没有初始化数组,您将读取垃圾,结果可能是random_value 将设置为 1,并且条件将评估为 true。

(operator_selection - 1) 是一个没有副作用的运算符。它不会修改operator_selection。此外,一旦找到重复项,您就想重新开始循环。

这是一个最小化循环的版本。

#include <iostream>
#include <cstdlib>
#include <ctime>

int main()
{
    int operator_selection;
    int operator_index[4] = {0};
    int random_value;
    srand(time(0));
    operator_index[0] = rand() %4 + 1;
    for (operator_selection = 1; operator_selection < 3; operator_selection++)
    {
        random_value = rand() %4 + 1;

        if (operator_index[0] == random_value || operator_index[1] == random_value)
        {
            --operator_selection;
            continue;
        }
        operator_index[operator_selection] = random_value;
    }
    operator_index[3] = 10 - operator_index[2] - operator_index[1] - operator_index[0];

    for(auto& elem : operator_index)
        std::cout << elem << " ";
    std::cout << "\n";
}

话虽如此,我仍然更喜欢 std::random_shuffle 方法,我也建议这样做。

【讨论】:

    【解决方案4】:

    另一个技巧是如果条件不满足,则将 lopp 倒退一步。

    #include <iostream>
    #include <ctime>
    using namespace std;
    
    
    
    int main(void)
    {
          const int size=100 ;
          int  arr[100] ;
          int i=0;
    
          srand(time(0));
    
          for ( i=0;i<size;i++)   {
              arr[i]=rand() % size;
              for(int j=0; j < i ; j++)  if (arr[j] == arr[i]) i--; 
          }
           cout<<"   \n\n\n ";
    
    
          // Loop to display the array arr[ ]
          for (  i=0;i<size;i++) cout<<""<<arr[i]<<"\t";
    
          cout<<" \nPress any key to continue\n";
          cin.ignore();
          cin.get();
    
      return 0;
    }
    

    输出:

     91     71      14      65      12      25      64      98      83      28
    99      9       5       0       89      36      95      55      73      90
    78      2       52      70      39      63      17      50      7       58
    34      84      40      51      20      31      38      32      35      49
    61      66      72      92      6       59      41      13      22      23
    81      56      1       16      21      62      57      10      11      54
    77      86      76      93      4       96      8       33      94      67
    29      48      15      82      97      37      26      46      43      80
    68      85      60      30      42      53      18      69      45      88
    47      79      75      44      24      27      74      3       19      87
    
    Press any key to continue
    

    【讨论】:

      猜你喜欢
      • 2021-06-28
      • 2017-04-07
      • 1970-01-01
      • 2019-06-28
      • 2014-09-27
      • 2021-06-10
      • 2015-06-14
      • 1970-01-01
      • 2017-03-12
      相关资源
      最近更新 更多