Home > OS >  shuffling strings without arrays and collections.shuffle
shuffling strings without arrays and collections.shuffle

Time:10-22

i been trying to make a method that shuffles a multiple choice question choices( A, B, C, D) and update the correct answer matching the new order but you cant use array and collections.shuffle.

CodePudding user response:

The algorithm of shuffling may look like this:

  1. Create two StringBuilder instances, one is a copy of the input string, the other is an accumulator of shuffled data.
  2. In the loop, calculate random position in the copy, append the character at this position to accumulator and remove from copy until copy is not empty
public static String shuffle(String str) {
    if (null == str || str.length() < 2) {
        return str; // nothing to shuffle, return as is
    }
    StringBuilder copy = new StringBuilder(str);
    StringBuilder acc = new StringBuilder();
    
    Random random = new Random();
    while (copy.length() > 0) {
        int pos = random.nextInt(copy.length());
        acc.append(copy.charAt(pos));
        copy.deleteCharAt(pos);
    }
    
    return acc.toString();
}

Tests:

for (int i = 0; i < 10; i  ) {
    System.out.println(i   " ABCD -> "   shuffle("ABCD"));
}

Output:

0 ABCD -> BDCA
1 ABCD -> BCAD
2 ABCD -> DBCA
3 ABCD -> DCAB
4 ABCD -> BCAD
5 ABCD -> CDBA
6 ABCD -> BACD
7 ABCD -> ACDB
8 ABCD -> ADBC
9 ABCD -> CDAB

A version using List<Character> to hold a copy and String instead of StringBuilder:

public static String shuffle(String str) {
    if (null == str || str.length() < 2) {
        return str;
    }
    List<Character> copy = new ArrayList<>();
    for (int i = 0; i < str.length(); i  ) {
        copy.add(str.charAt(i));
    }
    
    Random random = new Random();
    String result = "";
    while (copy.size() > 0) {
        int pos = random.nextInt(copy.size());
        result  = copy.get(pos);
        copy.remove(pos);
    }

    return result;
}

CodePudding user response:

Another one version of a shuffling algorithm:

  1. Copy all string characters to an intermediate character buffer
  2. Iterate this buffer and swap each character with an element at a random index
  3. Create resulting string from that buffer

Java code for this solution:

public static String shuffle(String str, Random random) {
    CharBuffer chars = CharBuffer.wrap(str.toCharArray());

    for (int i = 0; i < chars.capacity(); i  ) {
        int index = random.nextInt(chars.capacity());
        char tmp = chars.get(index);
        chars.put(index, chars.get(i));
        chars.put(i, tmp);
    }

    return chars.toString();
}

P.S. and that's ~10x faster on my machine, than doing this with a StringBuilder or Lists.

  • Related