0

私の問題は、Random() と .toCharArray() を使用して、(たとえば) String "asdf" を "sdfa" に変更しようとしていることです。

重複した乱数を取得しないようにするにはどうすればよいですか?

元の配列を変更せずに char をランダムに格納するために、新しい Char 配列を作成することになっていると思います。

私はこのコードではそれをしませんでしたが、それは別の方法かもしれません???

編集:私はそれをメインクラスにしました。これにより、簡単になります。ありがとうございました。

import java.util.Random;


public class Scramble {

public static void main(String[] args) {

            String str = "asdf";

            Random randomGenerator = new Random();

            int lengthOfStr = str.length();

            char[] chars = str.toCharArray();



            // do for length of str
            for (int i=0; i < lengthOfStr; i++)
            {

            int n = randomGenerator.nextInt(lengthOfStr);

            chars[i] = chars[n];

            String newStr = new String(chars);
            str = newStr;
            }

            System.out.println(str);            
}

}

4

3 に答える 3

3

配列を正しくランダムにスクランブルする方法については、Fisher-Yatesシャッフルを調べてください。(ちなみに、このアルゴリズムは、Javaの乱数ジェネレーターが乱数を提供する方法に完全に適合しており、乱数を一意にする必要はありません。)

于 2012-04-27T04:05:42.373 に答える
1

最初の質問に関しては、メソッドのローカル変数ではなく、乱数ジェネレーターをクラスのメンバーにすることで、乱数の重複を (大部分) 回避できます。次のコードは、スクランブルされた単語のかなりランダムな分布を生成する必要があります。その長さは、shuffleプリミティブ配列を操作できるメソッドがないことに起因する可能性があります。必要に応じて調整します。

public class Flipper {
   Random randomGenerator = new Random();

   public static void main(String[] args) {
      final String sample = "Hello World";

      final Flipper flipper = new Flipper();
      for (int i = 0; i < 100; i++) {
         System.out.println(flipper.scramble(sample));
      }
   }

   public String scramble(String str) {
      if (str == null)
         return null;

      char[] arr = str.toCharArray();
      List<Character> charList = new ArrayList<Character>(arr.length);
      for (final char c : arr) {
         charList.add(c);
      }

      Collections.shuffle(charList, randomGenerator);
      char[] converted = new char[charList.size()];
      for (int i = 0; i < charList.size(); i++) {
         converted[i] = charList.get(i).charValue();
      }

      return new String(converted);
   }
}
于 2012-04-27T04:22:48.657 に答える
1

これは、O(n) 期間の順序を持​​つ単純なものです。ループには 3 つの命令しかありません。ランダムな文字を新しい文字列に追加し、元の文字列から削除するため、次のランダムな文字が取得されると、以前に取得された文字は対象外になります。この関数を書いた後、これがフィッシャー・イェーツ シャッフル アルゴリズムの形式のように見えることに気付きました。

public class Scramble {

    public static String scramble(String str) {   
        StringBuilder newStringBuilder = new StringBuilder();
        StringBuilder stringBuilder = new StringBuilder(str);

        while (stringBuilder.length() > 0) {
            int n = (int)(Math.random() * stringBuilder.length()));
            newStringBuilder.append(stringBuilder.charAt(n));
            stringBuilder.deleteCharAt(n);
        }

        return newStringBuilder.toString();
    }

    public static void main(String[] args) {
        System.out.println(scramble("hola"));
    }
}
于 2012-04-27T04:45:40.143 に答える