如何使用两个 for 循环执行唯一的洗牌

How to execute a unique shuffle using two for loops

本文关键字:执行 循环 唯一 for 两个 何使用      更新时间:2023-10-16

我正在尝试编写一个名为func1的函数,该函数可以在给定另外两副牌,起始牌组和生成的牌组的情况下,唯一地洗牌给定的牌组(数组)。例如,一副牌 [1, 2, 3, 4, 5] 被洗牌并产生另一副牌 [4, 5, 2, 1, 3]。我想完成同样的洗牌(将插槽 0 中的牌放入插槽 3,将插槽 1 中的牌放入插槽 2,依此类推),但这次是在另一副牌 [2, 3, 1, 5, 4] 上。如果我正确编写代码,它应该打印出 [5, 4, 3, 2, 1]。虽然它运行程序,但它只能正确打印第一张"卡",其余的都是真正的大数字。我做错了什么?我使用的是正确的方法,还是应该重新考虑我的设计?

#include <iostream>
using namespace std;

int * func1(int *deck) // A unique shuffle given two decks, a starting and ending deck (in this case, "start" and "shuff1")
{
    int start[5] = { 1,2,3,4,5 }; // Starting deck
    int shuff1[5] = { 4,5,2,1,3 }; // Resulting deck after shuffle. This is the specific type of shuffle that we are copying
    int finish[5] = {}; // The deck that we are returning
    for (int i = 0; i < 5; i++) // Looks at a specific spot (i) in the start deck...
    {
        for (int j = 0; j < 5; j++) // Looks through all the spots (j) in the shuff1 deck...
        {
            if (start[i] == shuff1[j]) // And if the cards themselves are identical, then it takes the ith card
            {                          // in the given deck and puts it in the jth spot in the finish deck
                int temp = deck[i];
                finish[j] = temp;
                j = 5;
            }
        }
    }
    return finish;
}
int main()
{
    int test[5] = { 2,3,1,5,4 }; // Given deck
    int* shuff2 = func1(test); // Calls a specifc shuffle and sets it equal to a deck called shuff2
    for (int i = 0; i < 5; i++)
    {
        cout << shuff2[i] << endl; // Prints shuff2
    }

    return 0;
}

你的func1返回一个指向 finish 的指针,它是函数的局部变量。当控件从函数中传递出来时,该变量就会超出范围 - 你可以说它过期了。因此,指针指向无效内存荒野中的一个点,取消引用指针(例如通过shuff2[i])会导致未定义的行为,这意味着如果你幸运的话,奇怪的数字。

一种解决方案是让func1堆上构造finish。另一种方法是让函数接受指向数组的指针,它应该用洗牌值填充该数组;调用代码(例如 main ) 将负责提供指向有效数组的指针。

您的主要问题是您返回指向堆栈上分配的变量的指针,这是您无法做到的。 将指向"finish"的指针作为第二个参数传递。

不确定我是否很好地遵循了您描述所提出的算法的方式,但我认为您会想要创建一个偏移量数组,如下所示:

void func1(int *deck, int *finish) {
    int offsets[5] = {3, 1, 2, -3, -3};
    for (int i = 0; i < 5; ++i) {
        finish[i + offsets[i]] = deck[i];
    }
}

或者将实际的目标索引放入数组中:

void func1(int *deck, int *finish) {
    int desti[5] = {3, 2, 4, 0, 1};
    for (int i = 0; i < 5; ++i) {
        finish[desti[i]] = deck[i];
    }
}

虽然你确实特别说"使用两个 for 循环",所以也许我误解了你描述算法的方式。