0から、N-1までの、ダブらない整数の乱数発生コード。
C:
Version 1.5 (6/20)
N回以上呼び出した時のバグ修正。手直し。LoiuS0616さんのコードから。
Version 1.7 (6/20)
フィッシャー-イェーツのシャッフルアルゴリズムを使用。
C++:
Version 2.1
Python:
Pythonでも、書いてみました。
#C
krand.c
/*
整数での、0からN-1までの、ダブらない乱数発生
Ver 1.7
ここでは、Nは、400にしています。
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 400
int numbers[N];
void initrnd(void) {
for(int i = 0; i < N; ++i) {
numbers[i] = i;
}
for(int i = 0; i < N - 1; ++i) {
int r = rand() % (N - i) + i;
{
int tmp = numbers[i];
numbers[i] = numbers[r];
numbers[r] = tmp;
}
}
}
int rnd(void) {
static int rcount = 0;
int t;
t=numbers[rcount++];
if (rcount==N) { initrnd(); rcount=0; }
return t;
}
int main(void) {
srand((unsigned)time(NULL));
initrnd();
for(int i = 0; i < 2*N; ++i) {
printf("%d\n", rnd());
}
return 0;
}
#C++
krand.cpp
// 整数での、0からN-1までの、ダブらない乱数発生
// Ver 2.1
#include <iostream>
#include <random>
#include <vector>
#include <numeric>
#include <cstdlib>
#include <algorithm>
using namespace std;
class krand {
int rcount;
vector<int> num;
void init(int n) {
N=n;
for(int i=0;i<n;i++)
num.push_back(i);
std::random_device seed_gen;
std::mt19937 engine(seed_gen());
std::shuffle(num.begin(), num.end(), engine);
rcount=0;
}
public:
krand(int n) {init(n);}
int rnd() {
int t;
t=num[rcount++];
if (rcount==N) {
std::vector<int>().swap(num);
init(N); }
return t;
}
~krand() {
std::vector<int>().swap(num);
}
int N;
};
int main(void) {
krand r(400),r2(200);
for(int i = 0; i < r2.N; ++i)
cout << r2.rnd() << endl;
for(int i = 0; i < r.N; ++i)
cout << r.rnd() << endl;
r.~krand();
r2.~krand();
return 0;
}
#Python
krnd.py
#!/usr/bin/python3
import random
class krand:
def __init__(self, n):
self.N = n
self.ini(n)
def ini(self, n):
self.ns = [0]*n
for i in range(n):
self.ns[i] = i
random.shuffle(self.ns)
def rnd(self):
i = self.ns.pop(0)
if len(self.ns) == 0:
self.ini(self.N)
return(i)
def __del__(self):
self.ns = []
self.N = 1
k = krand(400)
for i in range(400):
print(k.rnd())
for i in range(400):
print(k.rnd())
del k