i が 0 の場合を、特別扱いしたいのなら、
コード:
num[0] = rand() % j + 1;
for (int i = 1; i < j; i++) {
int n;//n定義
do {
n = 0;//n初期化
num[i] = rand() % j + 1;
for (int k = 0; k < i; k++) {
if (num[k] == num[i])
n = 1;
}
} while (n);
}
としたほうが良いでしょう。元のままだと、i が 0 か
どうかのチェックを 3000回実行することになります。
もっと問題なのが、1~3000 の値を乱数で生成し、それが既に
存在するかどうかを毎回チェックしていることです。
既に 2999個の値が確定しているとき、残り 1個の値は1通り
しかありません。それなのに 3000通りの値を乱数で生成すると
既に存在するものにぶつからない確率は 1/3000。
既に 2998個の値が確定しているとき、残り 2個の値は2通り
しかありません。それなのに 3000通りの値を乱数で生成すると
既に存在するものにぶつからない確率は 2/3000。
試しにデータの個数を 3万個にしてみてください。
表示していると時間の計測ができなので、
出力はファイルにリダイレクトするとして、
何秒かかりますか?
改善案として、次のようなやり方を考えましょう。
コード:
#include <iostream> // cout
#include <ctime> // time
#include <cstdlib> // srand, rand
using namespace std;
int main()
{
srand(time(NULL));
const int n = 20;
int num[n];
for (int i = 0; i < n; i++) num[i]= i + 1;
for (int i = 0; i < n; i++) {
int j = rand() % n, t = num[i];
num[i] = num[j], num[j] = t;
}
for (int i = 0; i < n; i++) cout << num[i] << '\n';
}
また、こんなやり方もあります。
コード:
#include <iostream> // cout
#include <ctime> // time
#include <cstdlib> // srand, rand
using namespace std;
int main()
{
srand(time(NULL));
const int n = 20;
int num[n];
for (int i = 0; i < n; i++) num[i]= i + 1;
for (int i = n; i > 0; ) {
int j = rand() % i, t = num[--i];
num[i] = num[j], num[j] = t;
}
for (int i = 0; i < n; i++) cout << num[i] << '\n';
}
それぞれ、どういうことをやっているか説明できますか?