将数组的特定元素移动到新数组

时间:2019-02-27 22:57:51

标签: c++ arrays

我有一个长度为52的一维数组(一个甲板),在1-13之间有4组数字。

此刻,我拥有一个随机数生成器来选择一个元素,如果该数字在某个范围内,则它是一种颜色,在另一范围内,则是另一种颜色,等等。

我希望能够删除RNG选择的元素,将其移动到另一个数组(即播放器),并将其转换为具有相应颜色的二维数组。我想每次使数组更小,因此没有重复项。现在,我一次可以显示13个数字,但是还有很长的路要走。

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    int x = 51;
    while (x >=1)
    {
        int ar[x] = {1,2,3,4,5,6,7,8,9,10,11,12,13,1,2,3,4,5,6,7,8,9,10,11,12,13,1,2,3,4,5,6,7,8,9,10,11,12,13,1,2,3,4,5,6,7,8,9,10,11,12,13};

        int ft = 14;

        srand(time(NULL));
        int rNumber = rand() % x;

        if (rNumber < ft)
        {
            cout << ("yellow") << ar[rNumber] << "\n";
            x--;
        }
        else if (rNumber < ft * 2)
        {
            cout << ("blue") << ar[rNumber] << "\n";;
            x--;
        }
        else if (rNumber < ft * 3)
        {
            cout << ("red") << ar[rNumber] << "\n";
            x--;
        }

        else cout << ("black") << ar[rNumber] << "\n";
        x--;
    }
}

2 个答案:

答案 0 :(得分:0)

要删除数组中的某个元素,请查看数组中的最后一个索引,然后将其与要删除的索引交换。然后,减小数组的大小。 例如:

int arr [] = {1,2,3,4,5};
int itemCount = 5; 

如果我想删除数组中的第二项,我会这样做:

arr[1] = arr[itemCount-1]; //Assigns 4th Index of array to 2nd Index.
itemCount--;

如果显示新数组,它将看起来像这样:

{1,5,3,4}

答案 1 :(得分:0)

如果我理解您的问题,那么您会遇到许多问题,这些问题使您无法实现将52张卡按西装分为四个阵列以收集某种“手” 的目标。按西装分类的卡片数量,其中任何一件西装中没有卡片是(1 - 13的副本,例如“王牌->国王”。

如果我有这个权利,那么您想使用rand在卡组上循环选择一个“卡号”,然后根据您的if (rNumber < FT) ...逻辑使用该卡号对卡进行分类类似于:

  YELLOW     BLUE      RED    BLACK

      13       12        5       11
       7        8        1        5
       8       13       13        1
      10        1       12        7
       6        7        3       12
       3        4       11        3
      11        3        2        4
       0        0        9        6
       0        0        6        2

0仅表示“未处理”,例如,与7 - YELLOW and BLUE cards卡相比,本次运行中仅生成9 = RED and BLACK。(总数与{{1}之间的差异}代表生成的重复卡)要确保交易完整,您需要对每张生成的唯一卡进行52递增while (x < 52)循环,而不是简单地循环x次-这留给您)

正如其他人在评论中所建议的那样,您可以使用C ++提供的容器简化事情,同时减少代码的出错率。 52vector之类的工具,其中自动内存管理和内置的边界检查迭代例程可以防止您误入未定义的行为。就是说,理解和学习如何处理普通数组没有错。 (在过去30年编写的许多C ++中,您会经常发现它们)。既然您已经选择了数组,那么让我们继续解决您的问题。

为了实现卡的合理分配,您需要解决许多问题。您遇到的主要两个问题是map返回一个递减的数字,这与您选择的int rNumber = rand() % x;进行比较,可以确保您生成的卡ft = 14为零(或非常接近于零)。

您每次迭代生成的随机卡号应该是BLACK中的有效卡号,以与0 - 51数组的有效索引相对应,例如

ar

接下来,如果#define SUITS 4 /* no. of suits */ #define FT 13 /* cards per-suit (left as FT as your original was ft) */ #define CARDS 52 /* cards per-deck */ ... int rNumber = rand() % CARDS; /* mod with total cards not x */ 黄色<14 should not be蓝色<28 . Think about your红色<42 statements 10 { {1}}黑色`。相反,您需要:

, then

(这样and(例如, that's not right, that only leaves的有效索引就可以精确地映射到每张卡的每张卡的对应数组元素)

要处理将卡片分成单独的2D数组,其中每一行代表一个西装,然后每一列可以容纳每个西装的每张唯一卡片,只需声明一个足够大的2D数组即可,例如

possible cards for

(其中 if (rNumber < FT) { /* separate into suit, copy to deal array */ ... 仅保存添加到13 - cards中每套西装的卡数,例如,当将一张卡添加到0 - 12时,您将增加 int deal[SUITS][FT] = {{0}}, /* 2D array holding cards by suit */ count[SUITS] = {0}, /* count per-suit in deal */

要使事情变得更轻松,您可以创建一个全局count,它将您的西装颜色映射到适当的值,以在代码的其余部分中使用,例如

deal

现在,您有了常量deal[YELLOW][n]count[YELLOW]++;enumenum { YELLOW, BLUE, RED, BLACK }; /* color constants */ ,可以在分离条件期间轻松地将卡映射到西服,例如

YELLOW = 0

就足够了。卡全部分离后,您可以遍历BLUE = 1阵列并找到任何一套西装的最大卡数,然后输出RED = 2阵列以显示如何随机选择卡并将其过滤到不同的西装。将其放到一个简短的示例中,您可以执行以下操作:

BLACK = 3

使用/输出示例

当您确信原始卡号已按照您的意图被西装分开时,您可以在每个 if (rNumber < FT) { /* separate into suit, copy to deal array */ cout << ("yellow - ") << ar[rNumber] << "\n"; if (isunique (deal[YELLOW], count[YELLOW], ar[rNumber])) deal[YELLOW][count[YELLOW]++] = ar[rNumber]; } else if (rNumber < FT * 2) { cout << ("blue - ") << ar[rNumber] << "\n"; if (isunique (deal[BLUE], count[BLUE], ar[rNumber])) deal[BLUE][count[BLUE]++] = ar[rNumber]; } ... 中删除原始count语句。它们留在下面(为了便于阅读,在颜色和数字之间添加了空格和连字符),因为这就是您原始代码的方式。

deal

虽然您可以使用C ++容器使逻辑更简单,例如#include <iostream> #include <cstdlib> #include <cstring> #include <ctime> using namespace std; #define SUITS 4 /* no. of suits */ #define FT 13 /* cards per-suit */ #define CARDS 52 /* cards per-deck */ enum { YELLOW, BLUE, RED, BLACK }; /* color constants */ /* function to scan 'a' for 'val` * returning 1 if 'val` doesn't exist, 0 otherwise */ int isunique (int *a, int sz, int val) { for (int i = 0; i < sz; i++) if (a[i] == val) return 0; return 1; } int main (void) { int ar[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }, deal[SUITS][FT] = {{0}}, /* 2D array holding cards by suit */ count[SUITS] = {0}, /* count per-suit in deal */ maxcount = 0, /* max cards per-suit in deal */ x = CARDS; srand (time(NULL)); while (x--) /* loop 52 times */ { /* get card number (0 - 51) */ int rNumber = rand() % CARDS; /* mod with total cards not x */ if (rNumber < FT) { /* separate into suit, copy to deal array */ cout << ("yellow - ") << ar[rNumber] << "\n"; if (isunique (deal[YELLOW], count[YELLOW], ar[rNumber])) deal[YELLOW][count[YELLOW]++] = ar[rNumber]; } else if (rNumber < FT * 2) { cout << ("blue - ") << ar[rNumber] << "\n"; if (isunique (deal[BLUE], count[BLUE], ar[rNumber])) deal[BLUE][count[BLUE]++] = ar[rNumber]; } else if (rNumber < FT * 3) { cout << ("red - ") << ar[rNumber] << "\n"; if (isunique (deal[RED], count[RED], ar[rNumber])) deal[RED][count[RED]++] = ar[rNumber]; } else { cout << ("black - ") << ar[rNumber] << "\n"; if (isunique (deal[BLACK], count[BLACK], ar[rNumber])) deal[BLACK][count[BLACK]++] = ar[rNumber]; } } for (int i = 0; i < SUITS; i++) /* find max cards in any one suit */ if (count[i] > maxcount) maxcount = count[i]; /* output deal */ printf ("\n%8s %8s %8s %8s\n\n", "YELLOW", "BLUE", "RED", "BLACK"); for (int i = 0; i < maxcount; i++) printf ("%8d %8d %8d %8d\n", i < count[YELLOW] ? deal[YELLOW][i] : 0, i < count[BLUE] ? deal[BLUE][i] : 0, i < count[RED] ? deal[RED][i] : 0, i < count[BLACK] ? deal[BLACK][i] : 0); } cout等。学习如何处理简单数组没有错(在过去的30年中,有很多C ++代码专门使用它们)。仔细研究一下,如果您还有其他问题,请告诉我。