2011-12-31 20 views
1

私はC++が初めてです。これはおそらく乱雑に見えるので、2日間だけプログラミングされている。プログラムの目的は単語を入力することであり、プログラムはその単語の文字の配置をランダム化します。このランダマイザで何が問題なのか分かりません。

私には3つの質問があります。

  1. 同じ文字列を2回入力すると、同じ「ランダム」番号が出力されますか?
  2. 乱数が2回選択されていないことを確認する方法を教えてください。 FOR文の中に入れ子にされたIF文をすでに試しましたが、問題が悪化しました。
  3. この作業はどのように行われますか?

コード:

#include <iostream> 
#include <sstream> 
#include <string> 
#include <cstdlib> 
#include <stdio.h> 
#include <string.h> 

using namespace std; 

int main() { 
    cout << "Enter word to be randomized: "; 
    char rstring[30]; 
    char rstring2[30]; 
    cin >> rstring; 
    strcpy(rstring2, rstring); 
    int length; 
    length = strlen(rstring); 

    int max=length; 
    int min=0; 
    int randint; 

    for (int rdm=0; rdm<length; rdm++) { 
     randint=rand()%(max-min)+min; 
     cout << rstring[rdm]; //This is temporary. Just a visualization of what I'm doing. 
     cout << randint << endl; //Temporary as well. 
     rstring2[randint]=rstring[rdm]; 
    } 

    cout << endl << rstring2 << endl; 
    return 0; 
} 

あなたがこれをコンパイルして実行する場合は、同じ乱数が同じテキストのために出力されることがわかります。 "hello"の出力24330と同じです。なぜこのランダムジェネレータが非ランダムな数値を生成していますか?

+0

あなたが "2" に手の込んだてもらえますか?すべての数字を最大で1回だけ表示しますか? – bitmask

+0

*ランダム置換をしたい場合*あなたのアルゴリズムは以前にピックアップされたものを "覚え"なければなりません。 –

+0

@BasileStarynkevitch:ランダムな選択の代わりに、私の答えが示唆するように、またはシャッフル。 –

答えて

5

実行ごとに異なる結果を得るには、seed your random number generatorが必要です。それ以外の場合は、(あなたが気づいたように)実行ごとに同じ乱数が得られます。

プログラムの開始時にこれを置く:

srand(time(NULL)); 

これは、時間の経過とともに乱数生成器にシードされます - おそらく実行間で異なることであろう。

time()機能にアクセスするには、#include <time.h>も必要です。

+0

これは、RNGをシードするために何千もの異なる方法があることに注意してください。私がここに与えたのはいつもの方法です。さまざまな状況でより良い結果を得るための方法があります(これを省略します)。 – Mysticial

+0

この問題を修正していただきありがとうございます。 –

+0

@Redmastif:「問題を解決していただきありがとうございます。 [回答の左側にあるチェックボックスの概要をクリックすることで最もよく表現されています。](http://stackoverflow.com/faq#howtoask) – Johnsyweb

3

乱数ジェネレータを使用していません。 rand()は疑似乱数ジェネレータであり、真の乱数(例えば、平均、標準偏差、周波数スペクトルはすべて正しい)を持つ多くのプロパティを共有する一連の数値を生成します。

異なるシーケンスを取得するには、srand()を使用してシードを初期化する必要があります。これを行うための通常の方法ではありません:

srand(time(NULL)); 

はさらに、同じ数の2倍取り出すことができない保証シーケンスは、もは​​やi.i.d.のシーケンスであります(独立して同一分布する)乱数である。 (シーケンスは非常に依存します)乱数の大部分の使用はi.i.dに依存します。したがって、ライブラリ提供の関数はi.i.dです。しかし、繰り返しのフィルタリングは特に難しいことではありません。

文字列内の各文字のカーディナリティー(出現回数)を変更したくない場合、最も簡単なことは文字を1文字選択してからランダムにスワップすることです。スワップするだけで、順序は変更されますが、カーディナリティは変更されません。

+0

ハードウェアとオペレーティングシステムの中には、実際には乱数ジェネレータがあります。 Linuxの '/ dev/random'を参照してください。 –

+1

@BasileStarynkevitch:そうですが、彼が使っているC標準ライブラリ関数 'rand()'はまだ疑似ランダムです。 –

+0

合意。標準では、 'rand'や関連する関数には* pseudo * -randomnessが必要です。 –

0

rand()によって生成される乱数は擬似ランダムです。C++のrand()のマニュアルは、次の

ランド()と言うRAND_MAXの範囲0で擬似乱数整数を返します。

この数は明らかに非関連の番号が呼び出されるたびのシーケンスを返すアルゴリズムによって生成されます。このアルゴリズムは、系列を生成するためにシードを使用します。系列は、srandを使用していくつかの特有の値に初期化する必要があります。

0

(少なくともLinux上で)擬似乱数生成器は、(プログラムをより確定的にするために、その二つの連続の同一のランが同じ答えを与えるであろう)と同じ値を播種しているため。

あなたは別の値(時間、PID、何でも)とあなたのPRNGのシードができます。 Linuxでは、/dev/urandom(またはまれには/dev/random)の擬似ファイルを読むことも考えられます。多くの場合、PRNGをシードします。

0

以下のコードは、以前に選ばれたものを乱数を記憶しています。 一意の乱数を1回だけ生成します。 rand()がすでに存在する数字 を生成した場合、その番号を配列に格納しないように結果を配列に格納します。

#include <ctime> 
#include <iostream> 
using namespace std; 


int main() 
{ 

     int size=100; 
     int random_once[100]; 
     srand(time(0)); 

     cout<<"generating unique random numbers between [0 and "<<size <<"] only once \n\n"; 

     for (int i=0;i<size;i++) // generate random numbers 
     { 
      random_once[i]=rand() % size; 

       //if number already exists, dont store that number in the array 
      for(int j=0;j<i;j++) if (random_once[j]==random_once[i]) i--; 
     } 

     for (i=0;i<size;i++) cout<<" "<<random_once[i]<<"\t"; 
     cout<<"\n"; 

    return 0; 

} 

出力:

generating unique random numbers between [0 and 100] only once 

50  80  99  16  11  56  48  36  21  34 
90  87  33  85  96  77  63  5  60  52 
59  4  84  30  7  95  25  1  45  49 
10  43  44  82  22  74  32  68  70  86 
57  24  39  51  83  2  81  71  42  94 
78  72  41  73  92  35  76  9  3  58 
19  40  37  67  31  23  55  69  8  17 
64  46  93  27  28  91  26  65  47  14 
15  75  79  88  62  97  54  12  18  89 
13  38  61  0  29  66  53  6  98  20 

Press any key to continue 
関連する問題