質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.82%

<C++>ランダム・組み合わせ

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,160

tkz

score 25

前提・実現したいこと

最終的に
「 ○ × △ × □ 」と出力したい。
○、△、□、はそれぞれ10個の要素から一つランダムで選んだもの(10C1)!それ三つの掛け合わせを出力したいというわけである。

ただし、○、△、□、には文字を入れたい!

発生している問題・エラーメッセージ

回答およびそのリンク先を参考して、乱数の発生をやってみたものの、初めてでうまくできませんでした!どう修正すればよいのでしょうか?

ソースコード

言語:C++
 #include <iostream>
 #include <string>
 #include <stdio.h>
 #include <time.h>
using namespace std;

inline void InitRand(){
    srand((unsigned int)time(NULL));
}

inline int Dice(){
    return rand()%6+1;
}

int main(){

    char const* moji[]={"moji-retsu0", "moji-retsu1", "moji-retsu2", "moji-retsu3", "moji-retsu4", "moji-retsu5", "moji-retsu6", "moji-retsu7", "moji-retsu8", "moji-retsu9"};
    int rnd0, rnd1, rnd2;

    InitRand();
    for (rnd0=0;rnd0<10;rnd0++)
        cout << Dice()+Dice() <<'';
    for (rnd1=0;rnd1<10;rnd1++)
        cout << Dice()+Dice() <<'';
    for (rnd2=0;rnd2<10;rnd2++)
        cout << Dice()+Dice() <<'';

    cout << flush;

    cout << moji[rnd0] << "x" << moji[rnd1] << "x" << moji[rnd2] << "\n";

    return 0;

}

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • WoodenHamlet

    2016/02/29 23:05

    コードを書くときは </> ボタンを押してその中にコードを埋め込むとよいですよ

    キャンセル

回答 2

checkベストアンサー

+1

こんにちは。

「10個の要素」が10個の文字の意味でしたら、下記のようにすると良いです。

まず、その10文字をchar moji[]="0123456789";のように定義します。(0~9の部分は実際に使いたい文字を書いて下さい。全角文字は使えません。半角のアルファベットと数字記号です。)
次に、3つの0~9までの乱数を生成します。int rnd0, rnd1, rnd2;に生成したと仮定します。
そして、std::cout << moji[rnd0] << "x" << moji[rnd1] << "x" << moji[rnd2] << "\n";で終わりです。
乱数の生成方法はググればたくさんでてきます。例えば、こことかですね。

もし、「10個の要素」が10個の文字列の意味でしたら、mojiの定義を下記のように変更すればOKです。
char const* moji[]={"moji-retsu0", "moji-retsu1", ..., "moji-retsu9"};
もちろん、"moji-retsu*"の部分は実際に使いたい文字列を入れて下さいね。

全角文字を使いたい時は、後者を使えばたぶんできます。(コンパイラやOSでおまじないが必要な場合がありますので、必要であればコンパイラやOSの情報も書いて別途質問して下さい。)

では、頑張って下さい。


【追記】

お疲れ様です。

シングル・クォートは文字をはさむ必要があります。文字がないのでエラーになっています。
リンク先では、' 'と間にスペースが入っていますよ。

次に、rand()関数は要するに0以上のランダムな整数を返却します。
m % nはmをnで割った余りを求めます。
つまり、`rand() % 6'は、0以上のランダムな整数を6で割った余りです。0~5になりますね?


【追記】 答えです。

#include <iostream>
#include <string>
#include <stdio.h>
#include <time.h>
using namespace std;

inline void InitRand()
{ 
    srand((unsigned int)time(NULL)); 
}

inline int Dice()
{ 
    return rand()%10;   // ←ここ
}

int main()
{
    char const* moji[]=
    {
        "moji-retsu0",
        "moji-retsu1",
        "moji-retsu2",
        "moji-retsu3",
        "moji-retsu4",
        "moji-retsu5",
        "moji-retsu6",
        "moji-retsu7",
        "moji-retsu8",
        "moji-retsu9"
    }; 
    int rnd0, rnd1, rnd2;

    InitRand(); 
    rnd0=Dice();   // ←この辺
    rnd1=Dice();
    rnd2=Dice();

    cout << moji[rnd0] << "x" << moji[rnd1] << "x" << moji[rnd2] << "\n";

    return 0;
}

元のソースとどこが異なるのか、較べて見て下さい。マークしているところを意味的に変えてます。
(他の部分は見やすくするために変更させて頂きました。)
この差を説明する根性が足りませんでした。すいません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/03 18:07

    なるほど。修正してみました。for文のrnd<20のところをすべて<10にすれば良かったのでしょうか?

    どのように、moji-retsuを入力により代入させるですか?(cin??でも、どのように?)

    キャンセル

  • 2016/03/03 21:24

    長くなりそうですので、回答文に答えを追記します。

    キャンセル

  • 2016/03/04 13:39

    できました。丁寧に教えていただきほんとにありがとうございます。

    キャンセル

0

10個の要素から3個を取り出すでいいのですよね?それなら、std::shuffleを使ってランダムに並び替えして、最初の3個を取るのが実装が一番簡単だと思います。(ただし、最速ではありません)

参考までに作りました。C++11で作成していますので、clang++でコンパイルするときは"-std=c++11"や"-std=c++14"を付けて下さい。

#include <algorithm>
#include <iostream>
#include <random>
#include <string>
#include <vector>

int main()
{
    // シード値には非決定的な random_device を用います。
    // random_device は極めて低速ですが、予測は不可能な乱数です。
    std::random_device seed;
    // 乱数には優秀なメルセンヌツイスター mt19937 を用います。
    // C++11以上では、特殊な事情が無い限り、メルセンヌツイスターを
    // 使用して下さい。
    std::mt19937 engine(seed());

    // 文字列は string を、リストは vector を用います。
    // C++11 からは初期化子リストが使えます。
    std::vector<std::string> moji = {"moji-retsu0", "moji-retsu1",
            "moji-retsu2", "moji-retsu3", "moji-retsu4",
            "moji-retsu5", "moji-retsu6", "moji-retsu7",
            "moji-retsu8", "moji-retsu9"};

    // 一様な分布は uniform_int_distribution を使います。
    std::uniform_int_distribution<int> dist(0, moji.size() - 1);

    // あとは dist(engine) で 1 から mojiにある個数-1 までの乱数を求めて、
    // その位置にある要素を取り出します。
    std::cout << moji.at(dist(engine)) << "x" << moji.at(dist(engine))
          << "x" << moji.at(dist(engine)) << std::endl;

    // 重複したくない場合は、リストを shuffle します。
    std::shuffle(moji.begin(), moji.end(), engine);
    // はじめの三つだけ取り出します。
    std::cout << moji.at(0) << "x" << moji.at(1) << "x" << moji.at(2)
          << std::endl;

    return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.82%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る