我怎样才能洗牌一个单词的字母?

Posted

技术标签:

【中文标题】我怎样才能洗牌一个单词的字母?【英文标题】:How can I shuffle the letters of a word? 【发布时间】:2014-01-02 12:49:21 【问题描述】:

对数组中单词的字母进行洗牌的最简单方法是什么?我在一个数组中有一些单词,我随机选择一个单词,但我也想打乱它的字母。

public static void main (String[] args ) 
    String [] animals =  "Dog" , "Cat" , "Dino"  ;    
    Random random = new Random();
    String word = animals [random.nextInt(animals.length)];

    System.out.println ( word ) ;
    //I Simply want to shuffle the letters of word     

我不应该使用那个 List 的东西。我想出了类似的东西,但是使用此代码,它会打印随机字母,而不会随机播放。如果该字母已经打印,也许我可以编写类似不打印的代码?

//GET RANDOM LETTER
for (int i = 0; i< word.length(); i++ ) 

char c = (word.charAt(random.nextInt(word.length())));
System.out.print(c);  
  

【问题讨论】:

向你展示你的尝试:) How to shuffle characters in a string 的可能重复项 我已经访问过它使用列表的那个页面,但我无法使用它。 @user2999672 然后在您的问题中添加该要求。另外,那里有一些使用列表的答案 再想想你的随机播放方法。您当前打印一个随机字符,但没有针对每次打印相同字符的保护措施。您必须在打印时从单词中删除字符。 【参考方案1】:

真的不需要收集,除了以下内容:

public static void main(String[] args) 

    // Create a random object
    Random r = new Random();

    String word = "Animals";

    System.out.println("Before: " + word );
    word = scramble( r, word );
    System.out.println("After : " + word );


public static String scramble( Random random, String inputString )

    // Convert your string into a simple char array:
    char a[] = inputString.toCharArray();

    // Scramble the letters using the standard Fisher-Yates shuffle, 
    for( int i=0 ; i<a.length ; i++ )
    
        int j = random.nextInt(a.length);
        // Swap letters
        char temp = a[i]; a[i] = a[j];  a[j] = temp;
           

    return new String( a );

【讨论】:

为什么在条件为&lt; 时使用a.length-1 而不是使用a.length。当限制为&lt; a.length-1 时,最后一个字符总是停留在同一个地方。当使用&lt; a.lengthrandom.nextInt(a.length) 时,最后一个字符也会在随机播放过程中被考虑,但除此之外,这个解决方案还不错!感谢@Rastikan 我根据我自己的测试和@mkli90 的评论编辑了算法以随机播放最后一个字符。【参考方案2】:

你可以使用Collections.shuffle

List<Character> l = new ArrayList<>();
for(char c :  word.toCharArray()) //for each char of the word selectionned, put it in a list
    l.add(c); 
Collections.shuffle(l); //shuffle the list

StringBuilder sb = new StringBuilder(); //now rebuild the word
for(char c : l)
  sb.append(c);

word = sb.toString();

我不应该使用那个 List 的东西。

然后你可以创建两个StringBuilder 对象。一个将保留原始单词,一个将创建洗牌的单词:

StringBuilder s = new StringBuilder(word);
StringBuilder wordShuffled = new StringBuilder();
while(s.length() != 0)
    int index = random.nextInt(s.length());
    char c = s.charAt(index);
    wordShuffled.append(c);
    s.deleteCharAt(index);

System.out.println(wordShuffled.toString());

我发现了类似 deleteCharAt 但我想它适用于 StringBuilder 什么的。我不能用那个

Here 你可以找到一些不错的实用程序方法来允许对数组进行洗牌。

public static char[] shuffleArray(char[] x)     
       for ( int i = x.length; i > 0; i-- ) 
            int rand = (int)(Math.random()*(i));
            char temp = x[i-1];
            x[i-1] = x[rand];
            x[rand] = temp;
        
       return x;

然后只需调用此方法并使用构造函数String(char[] value)

System.out.println(new String(shuffleArray(word.toCharArray())));

下次明确说明,什么可以用/什么不能用。

【讨论】:

【参考方案3】:

这样的事情怎么样?

// Shuffle an array of characters.
public static void shuffleArray(char[] a) 
  int n = a.length; // the length of the array.
  for (int i = 0; i < n; i++) 
    int t = random.nextInt(n); // pick a random number 0 - the length.
    if (t == i)               // if the random number is the loop counter
      if (i > 0)              // check if we're at the first element.
        t = random.nextInt(i); // pick another number between 0 - and the loop counter.
       else 
        t = a.length - 1;      // the end of the loop.
      
    
    a[i] ^= a[t];              // swap a[i] and a[t]
    a[t] ^= a[i];
    a[i] ^= a[t];
  


private static Random random = new Random(); // the shared random.

public static void main(String[] args) 
  String[] animals =  "Dog", "Cat", "Dino" ;
  String word = animals[random
      .nextInt(animals.length)];

  System.out.println(word);            // the random word.
  char[] arr = word.toCharArray();     // the char[] from the word.
  shuffleArray(arr);                   // shuffle it.
  System.out.println(new String(arr)); // print it.

【讨论】:

这可以按我的意愿工作,但是请您解释一下交换部分,因为我不知道 ^= 是什么以及为什么我们要交换 3 次。 @Elliott Frisch【参考方案4】:

使用集合随机播放字符串。

import java.util.*;

public class ShuffleString 
    
    public static void main(String[] args) 
        
        String str = "Team India Is Best";
        String shuf = "";
        String s1 = str.substring(0, 4);
        String s2 = str.substring(5, 10);
        String s3 = str.substring(11, 13);
        String s4 = str.substring(14, 18);
        ArrayList<String> arr = new ArrayList<String>();
        arr.add(s1);
        arr.add(s2);
        arr.add(s3);
        arr.add(s4);
        Collections.shuffle(arr);

        for(String a : arr)
        
            shuf += a + " ";
        
        System.out.println(shuf);
    

【讨论】:

以上是关于我怎样才能洗牌一个单词的字母?的主要内容,如果未能解决你的问题,请参考以下文章

洗牌算法

如何给扑克洗牌才能更公平?

如何给扑克洗牌才能更公平?

如何避免pyspark中加入操作中的过度洗牌?

Scikit-learn,GroupKFold 与洗牌组?

我怎样才能找到部分单词匹配/找到c ++