我正在尝试编写一个代码,该代码至少会对每个元素进行一次洗牌,但它对我来说并不起作用。
我尝试的代码是:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void show(int[],int);
void shuffle(int[],int,int*);
int main (void)
{
int karten[]={1,2,3,4,5,6,7,8,9,10};
int n = sizeof(karten)/sizeof(int);
int s=0;
srand(time(NULL));
printf("Karten vor dem Mischen: \n");
show(karten,n);
shuffle(karten,n,&s);
printf("Karten nach dem Mischen:\n");
show(karten,n);
return 0;
}
void show(int karten[],int n)
{
for(int i=0;i<n;i++)
{
printf("%d,",karten[i]);
}
printf("\n");
}
void shuffle(int karten[],int n,int *s)
{
int i=0;
int d=0;
int vi;
int vd;
int q;
*s=0;
int *v=(int*)malloc(sizeof(int)*n);
q=0;
while(1)
{
i=rand()%10;
d=rand()%10;
vi=karten[i];
vd=karten[d];
karten[d]=vi;
karten[i]=vd;
*s=*s+1;
v[i]=1;
v[d]=1;
for(int b=0;b<=n;b++)
{
if(v[b]==1)
{
q++;
}
}
if(q==n)
{
break;
}
}
printf("Es wurden %d Vertauschungen gemacht\n",*s);
free(v);
}
错误是代码工作了一些时间并且有时不起作用。当它工作时,我认为它不能正常工作,因为洗牌时间是(3)或(4)。我试着让它变得尽可能简单。
答案 0 :(得分:2)
有三个问题。
首先,在分配内存后,您没有初始化v
。您应该将所有值设置为0,或者只使用calloc
来为您执行此操作。
第二个是在for
循环中,您正在检查所有卡是否已被洗牌:
for(int b=0;b<=n;b++)
您的数组索引b
的范围从0
到n
,但由于数组中包含n
个元素,因此有效索引为0
到{{ 1}}。因此,将n-1
更改为<=
:
<
第三个是你使用for(int b=0;b<n;b++)
。您应该在q
循环开始时将其初始化为0
,而不是在输入之前。否则,您将把前一次运行中的混洗元素的数量添加到当前计数。
例如,假设在第一次迭代while
为2且i
为3.那么将交换2个总元素。您将d
增加2,所以现在q
等于2.现在假设下一次迭代q
为4,i
为5.共4元素已被交换。所以你增加d
4次。但q
的上一次迭代的值为q
,因此现在2
为q
。再一次迭代,6
将至少为12.因此,条件q
永远不会得到满足。
答案 1 :(得分:1)
试试这个随机播放。它会在0到swap
的范围内得到一个随机数n-1
(确保swap
不等于n-1
),然后递减n
。由n
和swap
索引的两个值将被交换。继续,直到n
为零。
void shuffle(int karten[],int n)
{
int swap = 0;
int temp = 0;
while(n)
{
do {
swap = rand ( ) % n;
} while ( n > 1 && swap == n - 1);
n--;
temp = karten[swap];
karten[swap] = karten[n];
karten[n] = temp;
}
}