给个思路,编程题解决方案

给个思路,编程题
现在有衣服新的扑克拍,由四种花色的1,2,3,4,5,6,7,8,9,j,p,k组成,
不包括大小王,请写一个函数,可以将扑克牌洗牌,要求洗牌后,每张拍都不能在原来位置出现,要求函数的操作时间为常数,并且能够一等规律发生出全部可能的排序。

------解决方案--------------------
1.按这个要求,肯定需要两个容器来保存洗之前的顺序和洗之后的循序
2.这肯定要用到随机排列
3.不好说了...


------解决方案--------------------
给牌设定序号0-51;

int n[52];// 初始化n[i] = i

int k = 52;

loop:
int index = rand() % k;// 随机一张牌;

swap(n[index] ,n[k-1]);// 抽中的牌放在最后;

k--;// 下面在数组的前51个中随机抽取;
goto loop;直到全部最后一张


n[52]就是一副随机牌;

------解决方案--------------------
C/C++ code

int n[52];//洗牌前的牌

void change(int n[])
{
    int k =52 ;
    int index ;
    while(k>1)
    {
        index = rand()% k;
        while(index == (k-1)) // 位置相同
             index = rand()% k;// 重新洗
        swap(n[index],n[k]);
        k--;
    }
}

------解决方案--------------------
好像不需要重新洗,只要把k初始值改一下就好了
C/C++ code

void change(int n[])
{
    int k =51 ;
    int index ;
    while(k>0)
    {
        index = rand()% k;        
        swap(n[index],n[k]);
        k--;
    }
}

------解决方案--------------------
楼上的,如果你的index恰好等于k-1,就不符合要求了
------解决方案--------------------
。。。我说的是二楼。。怎么都回复这么快。。
------解决方案--------------------
随机必然有重复,所谓“不重复的随机”实质上是洗牌。
C/C++ code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int d[6];
int i,n,a,b,t;
int c,j;
void main() {
    srand(time(NULL));
    printf("shuffle 0..n-1 demo\n");
    for (n=1;n<=5;n++) {/* 测试1~5个元素 */
        printf("_____n=%d_____\n",n);
        j=1;
        for (c=1;c<=n;c++) j=j*c;/* j为n! */
        j*=n*2;
        for (c=1;c<=j;c++) {/* 测试n*2*n!次 */
            for (i=0;i<n;i++) d[i]=i;/* 填写0~n-1 */
            for (i=n;i>0;i--) {/* 打乱0~n-1 */
                a=i-1;b=rand()%i;
                if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
            }
            printf("%04d:",c);
            for (i=0;i<n;i++) printf("%d",d[i]);
            printf("\n");
        }
    }
    printf("shuffle 1..n demo\n");
    for (n=1;n<=5;n++) {/* 测试1~5个元素 */
        printf("_____n=%d_____\n",n);
        j=1;
        for (c=1;c<=n;c++) j=j*c;/* j为n! */
        j*=n*2;
        for (c=1;c<=j;c++) {/* 测试n*2*n!次 */
            for (i=1;i<=n;i++) d[i]=i;/* 填写1~n */
            for (i=n;i>1;i--) {/* 打乱1~n */
                a=i;b=rand()%i+1;
                if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
            }
            printf("%04d:",c);
            for (i=1;i<=n;i++) printf("%d",d[i]);
            printf("\n");
        }
    }
}