1

私は最近、Python で非常に単純な練習用プログラムを作成しました。これは、ユーザー入力を受け取ってサイコロを転がします。コードは次のとおりです。

import random
import sys
import math

def roll(rolls, sides, results):
    for rolls in range(1, rolls + 1):
        result = random.randrange(1, sides + 1)
        print result
        results.append(result)
def countf(rolls, sides, results):
    i = 1
    print "There were", rolls, "rolls."
    for sides in range(1, sides + 1):
        if results.count(i) != 1:
            print "There were", results.count(i), i,"s."
        else:
            print "There was", results.count(i), i
        i = i + 1
        if i == sides:
            break
    rolls = input("How many rolls? ")
        sides = input("How many sides of the die? ")
        results = []

        roll(rolls, sides, results)
        countf(rolls, sides, results)

(実際には、これはより大きなプログラムの一部なので、一部を切り取って貼り付ける必要があり、何かを見逃している可能性があります)。

そこで、それを Java に翻訳することにしました。ここでのアルゴリズムに注意してください: 乱数を取得し、それを出力して、それを配列に追加し、最後に配列内の各数値の量を数え、その値を出力します。someArray.count(someIndex)問題は、 Java 構文で同等の処理を行う方法がわからないことです。したがって、私のJavaプログラムはこれまでのところ次のようになっています。

import java.util.*;

public class Dice {
    static Scanner input = new Scanner(System.in);
    public static void main(String[] args) {
        final static int TIMES_TO_ROLL = getInt("Times to roll?");
        Random flip = new Random();
        int[] results = new int[TIMES_TO_ROLL];
        for (int i = 0; i < TIMES_TO_ROLL; i++) {
            int result = flip.nextInt(6);
            System.out.println(result);
            results[i] = result;
        }
    }
    public static int getInt(String prompt) {
        System.out.print(prompt + " ");
        int integer = input.nextInt();
        input.nextLine();
        return integer;
    }
}

それで、誰かが配列カウントコードで私を助けることができますか? 結局、Python の方がレベル高いので、これが定義済みのメソッドではない可能性があることは理解しています。そのため、独自の配列カウント メソッドを作成できますが、Python のような Java には定義済みのメソッドがあるかどうか疑問に思っていました。

編集:私はこのようなものを管理しました:

public static int arrayCount(int[] array, int item) {
    int amt = 0;
    for (int i = 0; i < array.length; i++) {
        if (array[i] == item) {
            amt++;
        }
        else {
            amt = amt;
        }
    }
    return amt;
}

EDIT:コマンドプロンプトを使用してJavaプログラムとPython.exe(Pythonのコマンドプロンプトコンソール)を実行すると仮定すると、どちらが高速になりますか(つまり、同じコードの場合、どちらの言語がより優れたパフォーマンスを発揮しますか? )?

4

6 に答える 6

7

HashMap を使用して結果を格納できます。

新しい番号がマップにない場合は、初期値として「1」を追加します。存在する場合は、現在のマップ値に「+1」を入れます。

値を表示するには、for each ループでエントリを反復処理するだけです。

于 2012-06-15T15:28:52.657 に答える
5

解決策は、配列をリストに変換してから、次のCollections.frequencyメソッドを使用することです。

List<Integer> resultList = Arrays.asList(results);
int freq = Collections.frequency(resultList, 4);

ArrayListまた、変換を保存する最初から使用することもできます。

List<Integer> result = new ArrayList<Integer>();
// add results
int freq = Collections.frequency(result, 4);

コレクションのドキュメントはこちら

編集:パフォーマンスが問題である場合(コメントで提案されているように)、次のように、配列の各インデックスをカウンターとして使用することをお勧めします。

    Random flip = new Random(SIDES);
    int[] counters = new int[SIDES];
    for (int i = 0; i < TIMES_TO_ROLL; i++) {
        int result = flip.nextInt;
        counters[result] = counters[result]+1;
    }

配列内のすべてのカウンターを既に取得しており、ハッシュを計算するオーバーヘッドがないため、最後にカウントする必要がなくなったことに注意してください。

于 2012-06-15T15:36:42.617 に答える
3

これを行うライブラリがいくつかあります。

  1. Google Guava のMultiSet
  2. アパッチコモンズバッグ

しかし、非常に単純なものの場合、余分なライブラリーは少し過剰であると考えるかもしれません。

を使用して自分でこれを行うこともできますint[]。サイコロが整数を使用していると仮定すると、転がされた数字が配列のインデックスを参照し、そのインデックスの値がインクリメントされます。特定の数値の値を取得する必要がある場合は、その値をインデックスで検索します。

private static final int NUMBER_DICE_SIDES = 6;
public static void main(String[] args) {
    final static int TIMES_TO_ROLL = getInt("Times to roll?");
    Random flip = new Random(NUMBER_DICE_SIDES);
    int[] results = new int[NUMBER_DICE_SIDES];
    for (int i = 0; i < TIMES_TO_ROLL; i++) {
        int result = flip.nextInt;
        System.out.println(result);
        results[result]++;
    }

    for(int i = 0; i < NUMBER_DICE_SIDES; ++i) {
        System.out.println((i+1)+"'s: " + arraysCount(results, i));
    }
}

public static int arrayCount(int[] array, int item) {
    return array[item];
}
于 2012-06-15T15:36:14.537 に答える
3

コレクションには頻度メソッドがあります

 int occurrences = Collections.frequency(listObject, searchItem);

コレクションの Java ドキュメント

于 2012-06-15T15:38:08.763 に答える
1

私の知る限り、配列内の特定の要素の頻度を返す定義済みのメソッドはありません。カスタム メソッドを作成する場合は、配列を反復処理して各値をチェックし、その値が目的の要素と一致する場合はカウンターをインクリメントするだけです。

次のようなものです:

// in this example, we assume myArray is an array of ints
private int count( int[] myArray, int targetValue) {
    int counter = 0;
    for (int i = 0 ; i < myArray.length; i++ ) {
        if (myArray[i] == targetValue) {
            counter++;
        }
    }
    return counter;
}

もちろん、配列内のすべての一意の値の頻度を見つけたい場合、これは非常に非効率になる可能性があります。

また、なぜ 7 面ダイスを使用しているのですか? nextInt() は、Random0 から最大値を含まないまでの数値を返します。したがって、サイコロは 0 ~ 6 の値を返しnew Random(6);ますflip.nextInt() +1;

于 2012-06-15T15:29:12.267 に答える