2012-03-25 3 views
2

私は学校用のサイコロシミュレータを作っていますが、特定の数値が転記された割合を計算する必要があります。テストを実行しましたが、C++で分割しても正しい結果が得られない

How many dice do you want to roll? 
3 
How many times do you want to roll the dice? 
1000000 
144414: 1000000 196039 % 

これが私のメインクラスのコードです:

#include <iostream> 
#include "Dice.h" 
#include "DiceSimulator.h" 

using namespace std; 

static int inputNumber(const string question); 

int main(int argc, const char * argv[]) 
{ 
    int numberOfDice = inputNumber("How many dice do you want to roll?"); 

    const int times = inputNumber("How many times do you want to roll the dice?"); 

    DiceSimulator sim(times, numberOfDice); 

    cout << sim.howManyTimesDidWeRollACertainNumber(11) 
    << ": " << times << " " 
    << ((sim.howManyTimesDidWeRollACertainNumber(11) * 100.0)/times) 
    << " %" << endl; 

    return 0; 
} 

int inputNumber(const string question) 
{ 
    int number = 0; 
    cout << question << endl; 
    cin >> number; 
    return number; 
} 

は、これが私のDiceSimulator.cppです:

#include <iostream> 
#include "DiceSimulator.h" 

using namespace std; 

DiceSimulator::DiceSimulator(const int times, const int numberOfDice) 
{ 
    this->numberOfDice = numberOfDice; 
    int timesRolled[6 * numberOfDice - 2]; 
    Dice dice[numberOfDice]; 

    for(int i = numberOfDice; i <= 6 * numberOfDice; i++) 
    { 
     timesRolled[i - numberOfDice] = 0; 
    } 

    for(int i = 0; i < times; i++) 
    { 
     int roll = 0; 
     for(int j = 0; j < numberOfDice; j++) 
     { 
      roll = roll + dice[j].roll(); 
     } 

     timesRolled[roll - numberOfDice]++; 
    } 

    this->timesRolled = timesRolled; 
} 

int DiceSimulator::howManyTimesDidWeRollACertainNumber(int number) 
{ 
    if(number < numberOfDice || number > numberOfDice * 6) 
     return 0; 

    return timesRolled[number - numberOfDice]; 
} 

とT彼はDiceSimulator.h

#include "Dice.h" 

#ifndef _3_01_Dice_Simulator_DiceSimulator_h 
#define _3_01_Dice_Simulator_DiceSimulator_h 

class DiceSimulator 
{ 
    int numberOfDice; 
    int *timesRolled; 
public: 
    DiceSimulator(const int times, const int numberOfDice); 
    int howManyTimesDidWeRollACertainNumber(int number); 
}; 

#endif 

であるあなたは、100を掛け1000000で割っ144414は右、14.4414であると思うだろうか?これが間違った結果をもたらす可能性はありますか?

+5

これは不可能です。真実を実現しようとする:壊れた部分ではないが、それは自分のコードだけである。 –

+1

@KerrekSB:* "真実を実現しようとする" * [Matrix](http://ja.wikipedia.org/wiki/The_Matrix)の小さな子供のように聞こえますか? :P – Nawaz

+1

'sim.howManyTimesDidWeRollACertainNumber(11)'は、呼び出すたびに異なる番号を生成することができますか?おそらくあなたは 'cout'の前に変数に結果を保持しておくべきでしょう。 – Yaniro

答えて

5
int timesRolled[6 * numberOfDice - 2]; 
// ... 
this->timesRolled = timesRolled; 

これはできません。 timesRolledは、コンストラクタの最後でスコープを外れるローカル変数です。一度それが起こると、メモリはもはや有効ではなく、そのメモリへのポインタにアクセスすると、未定義の動作につながります。

+0

ありがとう、どうすればいいですか? –

+0

ここでは、[bashphorisms](http://wiki.bash-hackers.org/misc/bashphorisms)が0,1,2となっていますか? –

+1

@SanderDeclerck 'new []'を使ってメモリを割り当て、デストラクタでそれを 'delete []'することができます。あるいは、配列の代わりに 'std :: vector'を使うのが良いでしょう。 – sepp2k

0

あなたは決してオペレータの優先順位を取るべきではありません。括弧を使う。彼らは多くの費用はかかりません。以下のように第3数の計算を変更します。

((sim.howManyTimesDidWeRollACertainNumber(11) * 100.0)/times) 

を、それがその後も間違っている場合、あなたはその関数のコードを表示する必要があります...明らかに誰もがそれなしで、さらにあなたを助けることはできません。

+5

罰金は読みやすいです。彼らはOPのコードでは全く役に立たない。重複した括弧が読みやすくすることができる状況があります。しかし、プログラマーがBODMASに問題がある場合、私は彼らがprescoolに戻ることを提案します。 –

+0

私はそれを試しましたが、それは変更されません、私はまた私のポストに他のコードを追加しました... –

+1

@Konrad、 '<<'か '*'が優先順位が高いかどうかはわかりません。私はそれが '*'だと信じています。だから私は少なくとも外側の括約物に感謝します。 –

1

はい、答えが与えられたと認められたが、私はまだこれを好きではないされています:

int timesRolled[6 * numberOfDice - 2]; 

for(int i = numberOfDice; i <= 6 * numberOfDice; i++) 
{ 
    timesRolled[i - numberOfDice] = 0; 
} 

ので、例えば、numberOfDiceが1の場合、timesRolledは4つの要素を持つ配列であること、およびあなたはそれの要素0から5を記入します。後でそれを調べることができます。

+0

私はすでにそれをtimesLolled = new int [5 * numberOfDice]に変更しました。 –

+0

@Sander恐ろしいコードです。ここで 'std :: vector'を使います。あなたがする必要がない限り、[ポインタを使用しない](https://twitter.com/#!/klmr/status/177173159836008448)。 –

関連する問題