0

Ok so i am working on a way to sort a 2D array, one of the dimensions having a string then the other having an int (Stored as a string for convenience sake) I had looked everywhere for a solution on how to sort the arrays in a way that the data from firstArray[1] is moved at the same time (its index's are a child to the movement of:) as firstArray[0]

This effect was achieved by using this

Arrays.sort(fps, new Comparator<String[]>() {
            @Override
            public int compare(final String[] entry1, final String[] entry2) {
                final String time1 = entry1[0];
                final String time2 = entry2[0];
                return time1.compareTo(time2);
            }
        });

Now i am having troubles with the thing. I will step through the code here and please if you can find a problem with it do tell.

First off i have the array:

String[][] fps = new String[2][15];
Arrays.fill(fps[0], "empty");
Arrays.fill(fps[1], "0");

Second i fill the array with some things that the other part of the program gives me, for this example ill use garbage values:

fps[0][0] = "Java";
fps[1][0] = "1";

fps[0][1] = "C++";
fps[1][1] = "14";

fps[0][2] = "C#";
fps[1][2] = "21";

fps[0][3] = "Python";
fps[1][3] = "9001";

Now is where i would call the above sorting command (Note that these values do not completly fill the array, there are some bins where there is no new data.)

Arrays.sort(fps, new Comparator<String[]>() {
            @Override
            public int compare(final String[] entry1, final String[] entry2) {
                final String time1 = entry1[0];
                final String time2 = entry2[0];
                return time1.compareTo(time2);
            }
        });

Now we have the array sorted and i want to search the 2D array for a value, so i use the Arrays.search to find which bin the query is at.

int searchIndex = Arrays.binarySearch(fps[0], "Java");
System.out.println(searchIndex);

So that is the code, and i think i have isolated the problem to being that the sorting part is not working correctly. If any of you have any more questions please post them in the comments. Likewise if you have a possible solution to this puzzling problem, I would love to hear of it!


PS: Just to be clear I had this working, then i shutdown my lappy and next time i booted (and since then) it has not worked.

PPS: As requested the outputs:

Current output:

-16
FPS:
    0 ---- No FPS For you!
    1 ---- Only one FPS
    2 ---- Only two FPS
    3 ---- Only three FPS
    4 ---- Only four FPS
    5 ---- Only five FPS
    6 ---- Only six FPS
    7 ---- Only seven FPS
    8 ---- Only eight FPS
    9 ---- Only nine FPS
    1 ---- Blah!

Expected/Hoped Output:

-16
FPS:
    1 ---- Blah!
    0 ---- No FPS For you!
    8 ---- Only eight FPS
    5 ---- Only five FPS
    4 ---- Only four FPS
    9 ---- Only nine FPS
    1 ---- Only one FPS
    7 ---- Only seven FPS
    6 ---- Only six FPS
    3 ---- Only three FPS
    2 ---- Only two FPS

PPPS: If you would like to see the code that i am working with currently:

import java.util.*;

public class Test
{
  public static void main (String [] args)
  {

    String[][] fps = new String[2][15];
    Arrays.fill(fps[0], "empty");//Fill up all the spaces so the sort and the search dont crap out
    Arrays.fill(fps[1], "0"); 


    //fps[ROW][COLOUMN] = Value + "";
    //fps[ROW][COLOUMN] = Value Instances + "";

    fps[0][0] = "No FPS For you!";
    fps[1][0] = 0 + "";

    fps[0][1] = "Only one FPS";
    fps[1][1] = 1 + "";

    fps[0][2] = "Only two FPS";
    fps[1][2] = 2 + "";

    fps[0][3] = "Only three FPS";
    fps[1][3] = 3 + "";

    fps[0][4] = "Only four FPS";
    fps[1][4] = 4 + "";

    fps[0][5] = "Only five FPS";
    fps[1][5] = 5 + "";

    fps[0][6] = "Only six FPS";
    fps[1][6] = 6 + "";

    fps[0][7] = "Only seven FPS";
    fps[1][7] = 7 + "";

    fps[0][8] = "Only eight FPS";
    fps[1][8] = 8 + "";

    fps[0][9] = "Only nine FPS";
    fps[1][9] = 9 + "";
    /* FUMBLE WITH ARRAY AFTER THIS LINE ONLY!*/

    //Things to have inputed into the method:
    //currentValue (from the line)
    //currentVariable (so we know what the name of the array we're dealing with is named)

    String currentValue = "Blah!"; //This is the value that will be searched for in the array, if found its child int is incremented by one, if not found it is added to the array.


    //Do a binary sort then search in the fps[0] side of things, makesure that the [1] are carried with the [0] changes.

    Arrays.sort(fps, new Comparator<String[]>() {
            @Override
            public int compare(final String[] entry1, final String[] entry2) {
                final String time1 = entry1[0];
                final String time2 = entry2[0];
                return time1.compareTo(time2);
            }
        });

    int searchIndex = Arrays.binarySearch(fps[0], currentValue); //Get the index of the current search value
    System.out.println(searchIndex); //  <-- Returns a neg number each time which shows that the sorting is not working correctly, and therefore the search is being thrown off... need to somehow fix.

    if(searchIndex >= 0)// If the value is found
    {
      fps[0][searchIndex] = (Integer.parseInt(fps[0][searchIndex]) + 1) + "";  //Add one instance to the value

    } //end if
    else //Otherwise find the next open value spot and change it to the current search query (and assign its instances to 1
    {

      for(int i = 0; i < fps[1].length ; i++)
      {
        if(fps[1][i].equals("empty"))
        {
          fps[1][i] = currentValue;
          fps[0][i] = 1 + "";
          i = fps[1].length; //force the for loop to exit

          Arrays.sort(fps, new Comparator<String[]>() {
            @Override
            public int compare(final String[] entry1, final String[] entry2) {
                final String time1 = entry1[0];
                final String time2 = entry2[0];
                return time1.compareTo(time2);
            }
        }); //end Arrays.sort
        }//end if
      }//end for
    }//end else


    //... Print array in rectangular form
    System.out.println("FPS:");

    for (int i =0; (!(fps[1][i].equals("empty")) ) ; i++)
    {
      System.out.println("\t" + fps[0][i] + " ---- " + fps[1][i] );


    }//end for
  }//end main
}//end class
MagikEh
  • 1
  • 2
  • Okey, but what's the output of your example with Java, C++ etc.? – Blood Mar 08 '13 at 21:22
  • Love the Seinfeld reference. `No soup for you!!` - This is what happens when you code on a lappy.... – vikingsteve Mar 08 '13 at 21:34
  • "PS: Just to be clear I had this working, then i shutdown my lappy and next time i booted (and since then) it has not worked." i know that feeling – Mirco Mar 08 '13 at 21:46

3 Answers3

1

I believe you have your indexes backwards. You are sorting fps. fps has only 2 elements which are being sorted. I believe you are trying to sort the 15 elements. If you reverse your indexes I believe you will get the desired sorting.

String[][] fps = new String[15][2];

You might consider an array of objects rather than a 2d array in this case. It seems to be a more logical structure and would avoid this type of confusion.

James Montagne
  • 77,516
  • 14
  • 110
  • 130
  • What i need is 2 arrays with 15 elements, the setup you have is 15 arrays with two elements. I'm not sure how i'd be able to do a search of the arrays.. And to the second point (<-- Newb programmer) do you have any resources about the objects (when used in a similar instance to this) that you could point me to? Thanks! ^_^/ – MagikEh Mar 09 '13 at 02:17
0

do you have any resources about the objects (when used in a similar instance to this

See: Sorting using Comparator- Descending order (User defined classes) for an example of how to do this when using a custom object.

one of the dimensions having a string then the other having an int (Stored as a string for convenience sake)

Its not convenient, since sorting a String representation of a number is different than sorting a number. Using a custom object will allow you to store the data properly so you can have a proper sort.

Community
  • 1
  • 1
camickr
  • 321,443
  • 19
  • 166
  • 288
0

In addition to the problem pointed out in this Answer, there is a problem in this:

int searchIndex = Arrays.binarySearch(fps[0], "Java");

Since you sorted using a custom comparator, you need to use the same custom comparator to do the binary search. Use binarySearch(T[] a, T key, Comparator<? super T> c). (If you use the 2-arg version, you should get an exception because String[] doesn't implement Comparable.)

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Would you mind showing where you got this from? Or (if possible) you are able to show what each of the parameters in the binarySearch are for. Much thanks for the suggestion. Also to note the second part, i am a bit confused, if i do use binary search on the array (when the array is in the correctly sorted order) the `Arrays.binarySearch(fps[0], query);` worked. Again if you have any resources where you can point me to, it would be greatly appreciated. – MagikEh Mar 09 '13 at 05:02
  • @MagikEh - I got this information from the standard Java API documentation which is part of every JDK distribution, and also publicly available and easy to find on the Oracle website. If your lecturer didn't explain how to find the Javadocs in your first Java lecture, COMPLAIN! – Stephen C Mar 10 '13 at 14:33
  • Here is the URL for the online copy of the Java 7 SE documentation tree: http://docs.oracle.com/javase/7/docs/ – Stephen C Mar 10 '13 at 14:36