Pergunta

I am creating a program that will output the letters of a string, but scrambled. It works, but there is no way to prevent a letter from appearing more than once. How would i go about this?

my code:

import java.util.Random;


public class Final {

    public static void main(String[] args) {
        Random rand = new Random();
        String str = "pumpkinpie";

        String[] split = str.split("");
        for(int i = 0; i < split.length; i++){
            int randomLet = rand.nextInt(split.length);
            System.out.print(split[randomLet]);
        }

    }

}
Foi útil?

Solução

You can add each character from the String into an ArrayList and shuffle it using the Collections.shuffle() method, which also accepts a Random instance:

    //1. initiate the string you want to shuffle
    String originalString = "pumkinpie";
    //2. initiate a List into which the characters will be added
    List<Character> characterList= new ArrayList<Character>();
    //3. add each character from the String to the List
    for (char character : originalString.toCharArray()) {
        characterList.add(character);
    };
    //4. shuffle using Collections.shuffle
    Collections.shuffle(characterList, new Random());
    //5. print each character
    for (Character character : characterList) {
        System.out.println(character);
    }

Outras dicas

Add the letters to an array/Set/List, and print only only if the array/Set/List does not contain the letter:

Set<String>...
for(int i = 0; i < split.length; i++){
    int randomLet = rand.nextInt(split.length);
    if(set does not contain split[randomLet]){
        System.out.print(split[randomLet]);
        add split[randomLet] to set
    }
}

Mostly Conceptual Answer

If you are trying to randomize the string, recognize then that putting a logical filter that letters can not repeat actually lowers entropy, and thus security or base randomness for any purpose. Also, this will be very difficult as it would require re-scrambling if a repeat is detected.

Take for instance:

randomize "add" - characters as 123
a   - 1
ad  - 13
add - 132
! back to drawing block

As a human we know that only one non-repeating string can come of this, dad (in the character order of 312 and 213), but the system will hit every option until it hits one of those, starting over each time...

add > add > dad > dad > dda > dda 
123 > 132 > 213 > 312 > 321 > 231 

Or a word like sorry: There are 120 permutations, of those, there are 8 different ways in which 3rd and 4th letters repeat (rr) in either 34, or 43 fashion (2 ways, and four positions in the resulting string). Of the 120 possibilities, this accounts for 48 permutations, and many of those permutations are not discovered until many characters in.

In words with more repeating characters (like, for instance comodo, with 6 different doubles of o, this covers 576 permutations of the possible 720) you get into conditions where your script becomes woefully inefficient due to thrashing...

But, if you need this, your best bet would be to write a function that randomizes a word, checks, then randomizes again. Doing it by hand (one character at a time) will be slower for easier words, and you will have about as much luck as anything else for troublesome words. Let Lady Luck guide you...

If OP just wanted to scramble and not wanted to remove any characters.

in other words pmieupnpki is one of the valid out put

then,

instead of blindly take the random Swap the elements in that array. since Random within small range could be same.

Random rand = new Random();
        String str = "pumpkinpie";

        char[] split = str.toCharArray();
        for(int i = 0; i < str.length(); i++){
            int randomLet = rand.nextInt(split.length);
            char c = split[randomLet];
            split[randomLet] =  split[i];
            split[i] = c;
        }
        System.out.println(String.valueOf(split));
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top