1

so my program is supposed to access a text document then do all that jazz that currently works. The only problem that I can't figure out is how to shuffle the contents of an array without having them end up on top of each other. Both internets and multiple tries with random and for loops have been unfruitful. here is my code:

import java.io.*;
import java.util.*;
public class lab_6 {
public static void main(String[] args)throws FileNotFoundException {
    Scanner input = new Scanner(System.in); //reads from keyboard
    System.out.println("What is the name of your file. ");
    String name = input.nextLine();
    Scanner reader = new Scanner(new File(name));// Open text file
    System.out.println("how many names are in your array");
    int num = input.nextInt();
    String[] names = new String[num];    
    for (int index = 0; index< names.length; index++)
    {
        names[index] = reader.nextLine();// Gets a line while there is one 
    } 
    System.out.println("\nOriginal List");
    printList(names);
    System.out.println("\nShuffled List");
    shuffle(names);
    printList(names);
    System.out.println("\nSorted List");
    Arrays.sort(names);  // this is a built in method
    printList(names);
    System.out.println("What name are you looking for");
    Scanner input1 = new Scanner(System.in); //reads from keyboard
    String find = input1.nextLine();
    int index = search(names,find);
    if(index == -1)
        System.out.println("The name was not there");
    else
        System.out.println(find+" was found at position "+index);
    System.out.println("The average length of all the names is "+averageLength(names));
}
public static void printList(String[] array) // print the list of names numbered
{
    for (int i=0; i<array.length; i++)
    {
        System.out.println((i+1)+") "+ array[i]);
    }

}
public static void shuffle (String[] array) // mix-up the array
{


}
public static int search(String[] array, String find) 
{   
    for(int i=0; i<array.length; i++) {

        if (array[i].equals(find) ) return i;

    } 
    return -1;
}
public static double averageLength(String[] array) //return the average length of the names 
{       
    int sum=0;
    for (int i=0; i<array.length; i++)
    {
        int l= array[i].length();
        sum +=l;
    }
    int average = sum/(array.length);
    return average; 

}

}
kanye east
  • 17
  • 1
  • 4
  • What about reading the data(an index) randomly, instead of shuffle the array? –  Mar 10 '14 at 22:39
  • how would i go about that? @parsaporahmad – kanye east Mar 10 '14 at 22:41
  • how about using an ArrayList http://stackoverflow.com/a/716619/2399024 – donfuxx Mar 10 '14 at 22:42
  • Note: with Java 7 you can use `Files.readAllLines()`, this will read all lines from the input file and put them all in a `List` – fge Mar 10 '14 at 22:43
  • Several answer suggest using collections, and it's true that there's a ready-made shuffle there, but it's just using Fisher-Yates under the covers and a collection is probably overkill if you already have your data in an array. On the other hand, using the tested version in the Java Collections API means one less thing you might get wrong. – David Conrad Mar 10 '14 at 23:13

3 Answers3

6
String[] names = ...;
Collections.shuffle(Arrays.asList(names));
// done

Note that Arrays.asList() returns a modifiable (but fixed-length) list, backed by the array, and not a copy of the array. So the array will be shuffled.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
3

Just use the Fisher-Yates shuffle (Knuth algorithm P):

private Random rand = new Random();

public static void shuffle(String[] array) { // mix-up the array
    for (int i = array.length - 1; i > 0; --i) {
        int j = rand.nextInt(i + 1);
        String temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

See:

  1. Knuth, D. 1969, 1998: Seminumerical Algorithms 1st & 3rd Eds. The Art of Computer Programming Series, Volume 2, p. 125.
  2. Fisher, Ronald A.; Yates, Frank (1948) [1938]. Statistical tables for biological, agricultural and medical research (3rd ed.). London: Oliver & Boyd. pp. 26–27.
  3. http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
  4. https://stackoverflow.com/a/1520212/636009
Community
  • 1
  • 1
David Conrad
  • 15,432
  • 2
  • 42
  • 54
1

You can use the Collections class, with the shuffle method. The documentation is available here.

Example

int[] values = {1,2,3,4,5};

List<Integer> valuesList = Arrays.asList(values);

Collections.shuffle(valuesList);

// valuesList is shuffled.
christopher
  • 26,815
  • 5
  • 55
  • 89
  • Except that this is java, there's no such thing as an `Int`, and `asList` messes up big time with primitive arrays. – trutheality Mar 10 '14 at 22:44
  • @trutheality But there is the `Integer` object wrapper class for the primitive `int`. Very helpful for primitive `List`s. – Andrew Gies Mar 10 '14 at 22:52
  • @AndrewG Except it won't auto-box an array of `int`s. You need to give `asList` an array of `Integers` to get a `List`. See http://stackoverflow.com/questions/1467913/arrays-aslist-not-working-as-it-should?lq=1 – trutheality Mar 10 '14 at 22:56
  • @trutheality I didn't say that it would auto-box. But you said that there is no Java object representing an integer, which is incorrect. This answer is still incorrect, and your logic in the second comment is correct. – Andrew Gies Mar 10 '14 at 23:00
  • @AndrewG No, I just said there's no `Int` I didn't mean that there's no primitive wrapper. Also I just noticed that the array declaration syntax is wrong. – trutheality Mar 10 '14 at 23:02
  • @trutheality Ok, fair enough. And hmm? `int[] values = {1,2,3,4,5};` is valid code... – Andrew Gies Mar 10 '14 at 23:05