如果数组中存在重复的数字,如何返回“ false”?

时间:2019-06-06 11:53:08

标签: c++

我正在尝试创建一个函数,如果数组中有任何重复的数字,则返回“ false”。(我正在制作乐透程序,并且它没有任何重复的数字。)代码来解决这个问题,但是我遇到的问题是主程序中存在无限循环。问题是,如果我执行该“检查”功能,则可能会发生“ a [1] == a [1]”,那么代码将陷入无限循环(它将继续仅返回)假)。然后,我的代码将有一个无限循环。如何正确修复我的功能?

#include <iostream>
#include <ctime>
#include <array>
#include <cstdlib>
using namespace std;
bool check(const int a[], int size, int num) {
    for (int i{ 0 }; i < size - 1; i++) {
        for (int j{ 1 }; j < size; ++j) {
            if (a[i] == a[j]) {
                return false;
            }
        }
    }
    return true;
}
int main() {
    int lotto[6]{ 0 };
    const int size = 6;
    srand(static_cast<unsigned int>(time(0)));
    for (int i{ 0 }; i < size; i++) {
        int num = rand() % 45 + 1;
        lotto[i] = num;
    }
    bool a{ false };
    while (a != true) {
        a = check(lotto, size, 1);
        if (a == false) {
            for (int i{ 0 }; i < size; i++) {
                int new_num = rand() % 45 + 1;
                lotto[i] = new_num;
            }
        }
        else if (a == true)
            break;
    }
    my_sort(lotto, size);
    for (int j{ 0 }; j < size; j++) {
        cout << lotto[j] << " ";
    }
    cout << endl;
    return 0;
}

我试图解决这样的问题,

bool check(const int a[], int size, int num) {
    for (int i{ 0 }; i < size - 1; i++) {
        for (int j{ 1 }; j < size; ++j) {
            if (i == 0) { int j = 1; }
            if (i == 1) { int j = 2; }
            if (i == 2) { int j = 3; }
            if (i == 3) { int j = 4; }
            if (i == 4) { int j = 5; }
            if (i == 5) { int j = 6; }

            if (a[i] == a[j]) {
                return false;
            }
        }
    }
    return true;
}

但是它仍然不起作用:(。 教我如何修复“检查”功能是我的荣幸。

2 个答案:

答案 0 :(得分:1)

您的算法将遍历所有元素,并将每个元素与其余所有元素进行比较,只要您找到两个相等的元素即可。但是,您总是从值1开始内部循环,并在第二次迭代中将第二个元素与其自身进行比较。这就是案例a[1] == a[1]来自的地方。要修复它,您可以这样写:

bool check(const int a[], int size, int num)
{
    for (int i = 0; i < size - 1; i++) {
        for (int j = i + 1; j < size; ++j) {
            //-------^^^^^
            if (a[i] == a[j]) {
                return false;
            }
        }
    }
    return true;
}

替代解决方案可能看起来像:

bool check(const int a[], int size, int num)
{
    std::unordered_set<int> uniqueItems;
    for (int j = 0; j < size; ++j)
    {
        auto res = uniqueItems.emplace(a[j]);
        if (!res.second) {
            // The item wasn't inserted as it's already in the set
            return false;
        }
    }
    return true;
}

答案 1 :(得分:0)

虽然其他答案可能指出您的检查功能存在问题,但您的问题与XY problem有关,这种情况在您尝试解决问题X的过程中出现,而在尝试的解决方案中遇到问题Y ,然后开始询问如何求解Y而不是X。

您的Y问题是检查功能损坏;您的X问题是如何从固定域中绘制唯一值的子集。为此,请考虑彩票图纸的工作原理(或多或少),并进行模拟。

  1. 准备一个按顺序唯一编号的球笼。
  2. 旋转笼子。
  3. 画数字。
  4. (可选)在绘图板上对它们进行排序。

我们可以用代码来实现。

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <numeric>
#include <random>

static constexpr int N_CAGE = 45;
static constexpr int N_DRAW = 6;

std::vector<int> makeTicket()
{
    static std::mt19937 rng{ std::random_device{}() };

    // prepare a cage of balls, uniquely numbered in sequence.
    std::vector<int> cage(N_CAGE);
    std::iota(cage.begin(), cage.end(), 1);

    // spin the cage
    std::shuffle(cage.begin(), cage.end(), rng);

    // build a ticket of first values
    std::vector<int> ticket(cage.begin(), std::next(cage.begin(), N_DRAW));

    // sort those for a prettier ticket
    std::sort(ticket.begin(), ticket.end());

    return ticket;
}

就是这样。将其与main驱动程序结合使用,该程序可以生成并打印10张票证:

int main()
{
    for (int i = 0; i < 10; ++i)
    {
        auto t = makeTicket();
        for (auto x : t)
            std::cout << std::setw(2) << std::setfill('0') << x << ' ';
        std::cout.put('\n');
    }
}

我们得到了X的解决方案

输出(很明显是可变的)

14 30 35 37 39 45
01 09 21 35 39 43
02 10 12 14 18 41
01 05 11 17 25 44
02 06 08 40 42 43
03 07 10 27 34 43
12 14 23 32 41 45
22 35 38 42 43 44
07 15 23 26 35 36
11 13 16 18 21 31