将数组的特定元素移动到新数组
Moving a particular element of an array to a new array
我有一个长度为 52 的一维数组(一副牌),有 4 组介于 1-13 之间的数字。
目前,我有它,以便随机数生成器选择一个元素,如果该数字在某个范围之间,则是一种颜色,在另一个范围之间是不同的颜色,等等。
我希望能够删除 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--;
}
}
如果我理解你的问题,你有很多问题阻止你达到你的目标,即按花色将 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
只是意味着"未发牌",例如,与9 = RED and BLACK
牌相比,这次运行中只生成了7 - YELLOW and BLUE cards
。(代表生成的重复卡片的总数和52
之间的差异)为了确保完整的交易,您需要在生成的每张唯一卡上循环while (x < 52)
递增x
,而不是简单地循环52
次 - 这留给您)
正如其他人在评论中建议的那样,您可以使用 C++ 提供的容器来简化事情,同时使您的代码不易出错,例如vector
或map
等情况下,自动内存管理和内置的边界检查迭代例程可以防止您误入未定义的行为。也就是说,理解和学习如何处理普通的旧数组并没有错。(你会在过去 30 年写的许多C++中经常找到它们)。既然您已经选择了数组,那么让我们继续解决您的问题。
为了实现一些合理的卡片分配,您有许多问题需要解决。您遇到的两个主要问题是返回一个递减的数字,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 */
接下来,"如果statements
黄色<14, then
蓝色<28and
红色<42, that's not right, that only leaves
10possible cards for
黑色,则should not be
14. Think about your
"。相反,您需要:
if (rNumber < FT) { /* separate into suit, copy to deal array */
...
(这样13 - cards
的有效索引(例如0 - 12
)精确映射到每张花色每张牌的相应数组元素)
要将卡片分成单独的 2D 数组,其中每行代表一个花色,然后每列都可以容纳每个花色的每个唯一卡片,只需声明一个足够大小的 2D 数组,例如
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]++;
)
为了让自己更轻松,您可以创建一个全局enum
,将您的西装颜色映射到适当的值,以便在代码的其余部分使用,例如
enum { 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
数组,显示如何随机选择卡牌并过滤到不同的花色中。把它放在一个简短的例子中,你可以做这样的事情:
#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 %8snn", "YELLOW", "BLUE", "RED", "BLACK");
for (int i = 0; i < maxcount; i++)
printf ("%8d %8d %8d %8dn",
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);
}
示例使用/输出
当您确信原始卡号以您想要的方式按预期方式按花色分隔时,您可以删除每个if(..) else if (..)...
中的原始cout
语句。它们被留在下面(为了便于阅读,在颜色和数字之间添加了空格和连字符),因为这就是你拥有原始代码的方式。
$ ./bin/card_array
blue - 12
black - 11
red - 5
blue - 8
red - 1
black - 5
blue - 8
yellow - 13
blue - 8
blue - 8
blue - 13
blue - 1
blue - 12
red - 13
black - 1
black - 7
black - 5
red - 12
blue - 7
red - 3
blue - 8
red - 11
red - 2
yellow - 7
yellow - 8
black - 12
red - 5
yellow - 13
blue - 4
black - 7
red - 12
black - 3
black - 4
blue - 3
yellow - 10
blue - 4
red - 9
yellow - 6
yellow - 6
yellow - 3
blue - 13
red - 5
black - 6
black - 11
black - 6
red - 6
black - 5
red - 11
black - 6
yellow - 11
black - 2
yellow - 13
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
虽然您可以通过使用C++容器来简化逻辑,例如vector
、map
等,学习如何处理简单的数组并没有错(在过去的30年里,有很多C++代码专门使用它们)。仔细查看,如果您有其他问题,请告诉我。
要删除数组的某个元素,我查看数组中的最后一个索引,然后将其与要删除的索引交换。然后,减小数组的大小。 例如:
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}
- 如何将元素从向量转移到新数组?
- 如何在新数组较小时创建新数组并将旧数组的最后一个元素复制到新数组中?
- C++ "oldstyle container ":指针/数组/新 - 可能误会?
- 是复制了新数组还是指向结构中引用的数组的指针?
- 标量"新 T "与数组"新 T[1]"
- 如何将大括号初始值设定项用于动态大小数组和新数组?
- 如何按姓氏排序并打印新数组
- 如何修改数组,从中删除空格,然后将其存储在新数组中
- 有没有办法创建一个花哨的迭代器和相应的新数组,以便检查每个索引的索引值的条件?
- 从一系列的evens和赔率中,新数组是持续的第一个赔率
- 在新数组中获取随机值
- 将数组的特定元素移动到新数组
- 我如何使用此二叉搜索函数的修改后的最大/最小值创建新数组
- 如何从函数返回的数组中创建一个新数组
- 合并排序 - 返回新数组,而不是将合并的数组复制到输入数组
- C 2 DIM数组新获得0
- 创建新数组时写入位置时发生访问冲突
- 将 argv 复制到新数组中
- C++中的动态数组(指针数组还是新数组?
- 编译器认为新数组正在创建新对象