我們在實現某些應用或者做測試的時候,需要將某些數據亂序。例如1,2,3三個數,隨機亂序後,可能是2,1,3。
最簡單的方法是:輸入一系列數,順序訪問每個位置的數,將當前位置的數與一個隨機數相關的位置進行內容交換。
純C實現
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
// n : the length of an array
int rand_id(int n){
return rand() % n;
}
// data : 1-D
// size_ele : size of per element
// len : the length of data
void rand_perm(uint8_t* data, uint8_t size_ele, int len, int (*rand_id)(int)){
int i, j, idx;
uint8_t *cptr = data;
uint8_t *tmp = (uint8_t*)malloc(size_ele);
for (i = 0; i < len; i++){
idx = rand_id(len);
for (j = 0; j < size_ele; j++){
tmp[j] = data[idx*size_ele + j];
}
for (j = 0; j < size_ele; j++){
data[idx*size_ele + j] = cptr[j];
}
for (j = 0; j < size_ele; j++){
cptr[j] = tmp[j];
}
cptr += size_ele;
}
free(tmp); tmp = 0;
}
#define __N 4
int main(int argc, char** argv){
// test int
int32_t a[__N] = {10000000,20000000,30000000,40000000};
rand_perm((uint8_t*)a, sizeof(a[0]), __N, rand_id);
for (int i = 0; i < __N; i++){
printf("%d ", a[i]);
}
printf("\n");
// test float
float b[__N] = {1.E-6f, 2.E-6f, 3.E-6f, 4.E-6f};
rand_perm((uint8_t*)b, sizeof(b[0]), __N, rand_id);
for (int i = 0; i < __N; i++){
printf("%f ", b[i]);
}
printf("\n");
// test double
double c[__N] = { 1.E-6, 2.E-6, 3.E-6, 4.E-6 };
rand_perm((uint8_t*)c, sizeof(c[0]), __N, rand_id);
for (int i = 0; i < __N; i++){
printf("%f ", c[i]);
}
printf("\n");
return 0;
}
輸出結果
10000000 40000000 30000000 20000000 0.000001 0.000002 0.000004 0.000003 0.000002 0.000004 0.000003 0.000001
純C++
C++標準裏有隨機洗牌函數,我們可以直接調用。
#include <iostream>
#include <algorithm>
using namespace std;
#define __N 4
int main(int argc, char** argv){
// test int
int a[__N] = { 10000000, 20000000, 30000000, 40000000 };
std::random_shuffle(a, a + __N);
for (int i = 0; i < __N; i++){
cout << a[i] << " ";
}
cout << endl;
// test float
float b[__N] = { 1.E-6f, 2.E-6f, 3.E-6f, 4.E-6f };
std::random_shuffle(b, b + __N);
for (int i = 0; i < __N; i++){
cout << std::fixed << b[i] << " ";
}
cout << endl;
// test double
double c[__N] = { 1.E-6, 2.E-6, 3.E-6, 4.E-6 };
std::random_shuffle(c, c + __N);
for (int i = 0; i < __N; i++){
cout << std::fixed << c[i] << " ";
}
cout << endl;
return EXIT_SUCCESS;
}
輸出結果
10000000 20000000 40000000 30000000 0.000004 0.000001 0.000003 0.000002 0.000003 0.000001 0.000004 0.000002