0

My problem is that I am trying to make (for example) String "asdf" changed to "sdfa" by using Random() and .toCharArray().

How do I not get duplicate random numbers?

I figure that I am supposed to create a new Char array in order to randomly store the char's without changing my original array because if I do, then the new string will be messed up, if that makes any sense.

I didn't do it here in this code, but that might be an alternative???

edit: I have made it into a main class, which should make it easier. Thank You.

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);            
}

}

user1360211
  • 1
  • 2
  • 3
  • possible duplicate of [How to shuffle characters in a string](http://stackoverflow.com/questions/3316674/how-to-shuffle-characters-in-a-string) – Thilo Apr 27 '12 at 04:05

3 Answers3

3

Look up the Fisher-Yates shuffle for how to correctly randomly scramble an array. (That algorithm, by the way, is perfectly suited to how Java's random number generators provide you with random numbers, and doesn't require making your random numbers unique.)

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • i understand the fisher-yates shuffle, but i do not understand how to get that into java code. – user1360211 Apr 27 '12 at 04:16
  • http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm is basically literally what you're looking for. "A random integer between 0 and i" is just `random.nextInt(i + 1)`. – Louis Wasserman Apr 27 '12 at 04:27
1

As to your first question, you can avoid (to a large extent) duplicated random numbers by making the random number generator a member of your class, as opposed to a local variable in your method. The following code should generate a fairly random distribution of scrambled words. You can blame its length on the lack of a shuffle method that can work with primitive arrays. Adapt as appropriate to your needs:

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);
   }
}
Perception
  • 79,279
  • 19
  • 185
  • 195
  • yes, but i am not sure if i can use Collections, is there any other way without using Collections.? – user1360211 Apr 27 '12 at 04:37
  • You can manually shuffle the array. Using the random numbers from the RND generator and scoping them to the size of the array. Thats a very different solution from what I've shown though. You might want to edit your original question to indicate the requirements of this ... homework? – Perception Apr 27 '12 at 04:47
1

Here is a simple one with a O(n) duration order. The loop has only 3 instructions: It appends the random char in a new string and removes it from the original one, so when the next random char is obtained, the previously obtained chars are not eligible. I noticed after writing this function that it seems it is a form of the Fisher–Yates shuffle algorithm.

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"));
    }
}
CCC
  • 2,642
  • 7
  • 40
  • 62
  • thank you for your solution, but im not sure if i can use .append. =[ maybe instead of a complete solution, more of like something that shoots out random numbers say from a range of 0 - 10, but no duplicates. – user1360211 Apr 27 '12 at 05:17
  • so you should've asked that in the first place and also add the homework tag. – CCC Apr 27 '12 at 06:05