【问题标题】:Scramble a Word using Java使用 Java 打乱单词
【发布时间】:2010-11-22 16:41:35
【问题描述】:

我想打乱一个字符串,让它不可读,所以想出了这个方法:

public String scrambleWord(String start_word){

     char[] wordarray = start_word.toCharArray();

        char[] dummywordarray = start_word.toCharArray();

        Random random = new Random();

        int r = random.nextInt(wordarray.length-1);
        int i = 0;

        int j = r+1;

        while(i <= r){

            dummywordarray[wordarray.length -i-1] = wordarray[i];

            i++;
        }


        while (j <= wordarray.length -1){

            dummywordarray[j-r-1] = wordarray[j];

            j++;

        }

        String newword = String.valueOf(dummywa);



        return newword;

所以我首先将字符串转换为 char 数组,在我的方法中我必须复制 char 数组“dummywordarray”。通过这个算法,单词的每个字母都会改变位置。但它不会被打乱得很好,从某种意义上说,你一眼就能把它重新组合起来。 所以我通过该方法传递了一个少于 9 个字符的给定字符串 7 次,并且这些单词被打乱得很好,即不可读。 但是我用一个 30 个字符的字符串尝试了它,它经过了 500 次传递,然后我才能保证它被很好地打乱了。 500! 我确定有更好的算法,我想要一些建议 a) 改进此方法 或者 b) 更好的方法。

【问题讨论】:

  • 你所说的“很好地乱码”是什么意思
  • 您是否只需要单向随机播放字母,以后将无法恢复?或者你真的想要一个密码来创建一个可逆的洗牌?
  • 很好地打乱是相当主观的。对不起,我不能给你一个正确的定义。如果原来的词是麻烦制造者,那么 makerelbuort、tromakbleuer 就不是“很好地打乱了。你可以在五秒钟后把它们放回去。
  • 不需要反转。我只想要一个高效的洗牌。
  • @JJG:随机性的本质是有时“麻烦制造者”会被随机打乱为“麻烦制造者”。人类大脑在“洗牌”的不同阶段解决字谜或混乱的能力是一个更大的问题,与编程 IMO 几乎没有关系。

标签: java shuffle


【解决方案1】:

怎么样

ArrayList<Character> chars = new ArrayList<Character>(word.length());
for ( char c : word.toCharArray() ) {
   chars.add(c);
}
Collections.shuffle(chars);
char[] shuffled = new char[chars.size()];
for ( int i = 0; i < shuffled.length; i++ ) {
   shuffled[i] = chars.get(i);
}
String shuffledWord = new String(shuffled);

换句话说,您可以利用现有的java.util.Collections.shuffle(List) 方法。不幸的是,您必须跳过几个环节才能使用它,因为您不能在泛型中使用原语。

编辑:

shuffle 工作的基本方式(完整解释请参见 Javadoc)如下:

for position = last_index to first_index
   let swap_pos = random number between first_index and position, inclusive
   swap(swap_pos, position)

编辑 2:

使用 Guava 的 Chars 实用程序,这种方法明显不那么冗长:

List<Character> chars = Chars.asList(word.toCharArray());
Collections.shuffle(chars);
String shuffledWord = new String(Chars.toArray(chars));

【讨论】:

  • 漂亮而简单。您可以使用 Arrays.asList(word.toCharArray()) 进一步缩短它。
  • @Adamski:我认为这会导致List&lt;char[]&gt;,因为Character[]char[] 不同。
  • 谢谢,我会调查的。我在泛型方面没有太多经验,但我会试一试。但是你知道 suffle(list) 方法中的算法吗?我只是想知道他们是怎么做到的。
  • 你可以使用char[] shuffled = chars.ToArray(char[] shuffled) 删除第二个for 构造吗?
  • 请注意,这是 Knuth shuffle 或 Fisher-Yates shuffle。 en.wikipedia.org/wiki/Shuffling#Randomization
猜你喜欢
  • 2017-07-10
  • 2014-04-05
  • 2012-01-27
  • 2017-07-18
  • 2011-02-12
  • 2019-03-18
  • 2019-12-10
  • 2017-09-07
  • 1970-01-01
相关资源
最近更新 更多