Link to home
Start Free TrialLog in
Avatar of luna621
luna621

asked on

Read from file, store to array, sort array

Hi again,

Okay, I basically got my code to read from the input file.  Check if the input file contains valid data.  Print to an output file.  Now, I need to sort the data using QuickSort.

Example: "_" represents spaces, and <tab> represents tabs

  input: 23 _ 4 _ _ 15 <tab> _ 8
output: 4 _ 8 _ 15 _ 23


---------------------------------------------------------------------------------

 import java.io.*;
 import java.util.*;

 public class ReadInputArray {

      public static void main (String[] arg) throws Exception {

        BufferedReader readFile = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
        String input = "";

        File output = new File("output.txt"); // writes to output.txt
        FileOutputStream outFromFile = new FileOutputStream(output);
        PrintStream ps = new PrintStream(outFromFile);

        ArrayList digitsList = new ArrayList(); // create new ArrayList for ints

        try {
            // Read input from input.txt
            while((input = readFile.readLine())!=null) { // reads until there are no characters left

                // separates the ints from the spaces

                StringBuffer sbDigits = new StringBuffer(); // create new string
                int len = input.length(); // length of input

                for(int i=0; i<len; i++) {
                    char c = input.charAt(i);
                    if(c == ' ' || c == '\t') { // if the character is space or tab
                        if(sbDigits.length()>0) {
                            Integer num = new Integer(sbDigits.toString());
                            digitsList.add(num + " ");
                            sbDigits = new StringBuffer();
                        } // END if
                    } // END if
                    else {
                        sbDigits.append(c);
                    } // END else

                    if(sbDigits.length()>0){
                        Integer num = new Integer(sbDigits.toString());
                        digitsList.add(num + " ");
                        sbDigits = new StringBuffer();
                    } // END if
                } // END for

                // Output the resulting array
                for(int i=0; i<digitsList.size(); i++){
                    System.out.print(digitsList.get(i));
                    ps.print(digitsList.get(i)); // writes what was read to output.txt
                } // END for
                System.out.println("\n\nProcess complete.  Please check your output.txt.\n");
            } // END while
        } // END try

        // checks for data in correct format - integers, spaces, and tabs only
        catch(NumberFormatException notInt) {
             System.out.println("Input not in correct format.  Integers, spaces, or tabs only please.");
             System.out.println("Program will now exit.\n");
        } // END catch
    } // END main()
} // END class ReadInputArray
Avatar of luna621
luna621

ASKER

public class QuickSort {

// ---------------------------------------------------------
// Sorts the items in an array into ascending order.
// Precondition: theArray[first..last] is an array.
// Postcondition: theArray[first..last] is sorted.
// Calls: partition.
// ---------------------------------------------------------

    public static void quickSort(Comparable[] theArray, int first, int last) {

        int pivotIndex;

        if (first < last) {
            // create the partition: S1, Pivot, S2
            pivotIndex = partition(theArray, first, last);
            // sort regions S1 and S2
            quickSort(theArray, first, pivotIndex-1);
            quickSort(theArray, pivotIndex+1, last);
        }  // END if

    }  // END quickSort

// ---------------------------------------------------------
// Partitions an array for quicksort.
// Precondition: theArray[first..last] is an array;
// first <= last.
// Postcondition: Returns the index of the pivot element of
// theArray[first..last]. Upon completion of the method,
// this will be the index value lastS1 such that
//    S1 = theArray[first..lastS1-1] <  pivot
//         theArray[lastS1]          == pivot
//    S2 = theArray[lastS1+1..last]  >= pivot
// Calls: choosePivot.
// ---------------------------------------------------------

    private static int partition(Comparable[] theArray, int first, int last) {

        // tempItem is used to swap elements in the array
        Comparable tempItem;
        // place pivot in theArray[first]
        choosePivot(theArray, first, last);
        Comparable pivot = theArray[first];   // reference pivot

        // initially, everything but pivot is in unknown
        int lastS1 = first;          // index of last item in S1

        // move one item at a time until unknown region is empty

        for (int firstUnknown = first + 1; firstUnknown <= last; ++firstUnknown) {
        // Invariant: theArray[first+1..lastS1] < pivot
        //            theArray[lastS1+1..firstUnknown-1] >= pivot
        // move item from unknown to proper region
            if (theArray[firstUnknown].compareTo(pivot) < 0) {
                // item from unknown belongs in S1
                ++lastS1;
                tempItem = theArray[firstUnknown];
                theArray[firstUnknown] = theArray[lastS1];
                theArray[lastS1] = tempItem;
            }  // end if
            // else item from unknown belongs in S2
        }  // end for

        // place pivot in proper position and mark its location
        tempItem = theArray[first];
        theArray[first] = theArray[lastS1];
        theArray[lastS1] = tempItem;
        return lastS1;
    }  // end partition

// ---------------------------------------------------------
// Chooses a pivot for quicksort's partition algorithm and
// swaps it with the first item in an array.
// Precondition: theArray[first..last] is an array;
// first <= last.
// Postcondition: theArray[first] is the pivot.
// ---------------------------------------------------------

private static void choosePivot(Comparable[] theArray, int first, int last) {

     int pivotIndex;
     int mid = (first + last)/2;
         if (theArray[first].compareTo(theArray[mid])<=0) {
               if (theArray[mid].compareTo(theArray[last])<=0) {
                    pivotIndex = mid;
               }
               else {
                    pivotIndex = (theArray[first].compareTo(theArray[last])<=0 ? last : first);
               }
          }
          else if(theArray[mid].compareTo(theArray[last])<=0) {
               pivotIndex = mid;
          }
          else {
               pivotIndex = ((theArray[mid].compareTo(theArray[last])<=0) ? first:last);
               swap(theArray, first, pivotIndex);
          }

}  // end choosePivot


public static void swap(Comparable[] theArray, int left, int right) {

         Comparable temp = theArray[left];
         theArray[left] = theArray[right];
         theArray[right] = temp;

 } // end swap()


} // END QuickSort
Avatar of luna621

ASKER

               Comparable[] array = (Comparable[])digitsList.toArray(new Comparable[0]);
                QuickSort.quickSort(array, 0, array.length-1);

Let's see, I'm using the digitsList.  Then I typecasted it to be Comparable... the parameters fit my quicksort method, but some how it's not reading from the array.
Avatar of Mick Barry
i posted the call you need to make in the previous question

it needs to go after you have added all the numbers to your list.
ie. before the line:
   // Output the resulting array

and then output the contents of the array instead of digitsList
Avatar of luna621

ASKER

Maybe instead of Comparable, I need to use something else?  If that's the case, I guess I need to rewrite my QuickSort code.  So, instead of Comparable shoudl I just pass in my ArrayList?  But, then there's the problem with the .compareTo()...  


 
Avatar of luna621

ASKER

Oops!  Let me check the previous Q...
Avatar of luna621

ASKER

You're talking about this line, right?

        Comparable[] array = (Comparable[])digitsList.toArray(new Comparable[0]);
        QuickSort.quickSort(array, 0, array.length-1);


I put it right before I printed...

            while((input = readFile.readLine())!=null) { // reads until there are no characters left
                ...

                for(int i=0; i<len; i++) {
                    char c = input.charAt(i);
                    if(c == ' ' || c == '\t') { // if the character is space or tab
                        if(sbDigits.length()>0) {
                            Integer num = new Integer(sbDigits.toString());
                            digitsList.add(num + " ");
                            sbDigits = new StringBuffer();
                     } // END if
                     ...

 >>>         Comparable[] array = (Comparable[])digitsList.toArray(new Comparable[0]);         <<<
 >>>         QuickSort.quickSort(array, 0, array.length-1);         <<<

                // Output the resulting array
                for(int i=0; i<digitsList.size(); i++){
                    System.out.print(digitsList.get(i));
                    ps.print(digitsList.get(i)); // writes what was read to output.txt
                } // END for


yes

and change the output for loop to print the contents of the array
Avatar of luna621

ASKER

So... change:

                for(int i=0; i<arrayList.size(); i++){
                    System.out.print(digitsList.get(i));
                    ps.print(digitsList.get(i)); // writes what was read to output.txt
                } // END for
---------------------------------------------------------------------------------------------------------
To this??

                for(int i=0; i<array.size(); i++){
                    System.out.print(array.get(i));
                    ps.print(array.get(i)); // writes what was read to output.txt
                } // END for
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The code I posted goes well. Try it separately and then the only thing you must do to insert in your code is what I did in the main method.

Try.

Only Copy Paste Compile Run.


Bye, Giant.
Avatar of luna621

ASKER

Omg, I'm sorry!  I didn't catch that the first time.  array is with .length, and at position [].  The summer has been too long.  I apologize.  It works now.  
Avatar of luna621

ASKER

Thank you objects and Giant2.  My brain is slowly coming back to java :)
> The summer has been too long.

Mmmmm, summer. I'm looking forward to that :)
Avatar of luna621

ASKER

Oh, one more question.  My numbers are prints without spaces.  I tried putting the spaces here:

                    if(c == ' ' || c == '\t') { // if the character is space or tab
                        if(sbDigits.length()>0) {
                            Integer num = new Integer(sbDigits.toString());
                            digitsList.add(num + " "); <<------------------------------------
                            resultList.add(num + " "); <<------------------------------------
                            sbDigits = new StringBuffer();
                        } // END if

But if my input was:  16      23        99        5
The output would be: 1235699
Avatar of luna621

ASKER

I think what happened was it was storing the individual digits, and not the whole integer.
you convert your numbers to strings, so it does an alphabetic sort instead of numeric.

try:

digitsList.add(num);

and add your spacing when you output them.
try to use the code I referring. It sort using alphabetical order for String and numeric order for Integer.
Avatar of luna621

ASKER

See, I thought I converted it to a String when I did this:

                            Integer num = new Integer(sbDigits.toString());  <----------
                            digitsList.add(num); <----------

It's still printing: 1 2 3 5 6 9 9
Instead of: 5 16 23 99
Avatar of luna621

ASKER

Comment from Giant2  feedback
Date: 09/07/2004 08:09PM HST

try to use the code I referring. It sort using alphabetical order for String and numeric order for Integer.
-------------------------------------------------------------------------------------------------------------------------------

Okay, hold on  :)


Avatar of luna621

ASKER

Okay, tried this:

                Comparable[] array = (Comparable[])digitsList.toArray(new Comparable[0]);
                QuickSort qs = new QuickSort();
                qs.quicksort(array, 0, array.length-1);

It still didn't separate the integers.  Strange thing was when I ran your code by itself, it worked.  Maybe I'm not adding it correctly into the array?
Avatar of luna621

ASKER

Haha!  Figured it out... my ending } for the for loop was out of place :)
Avatar of luna621

ASKER

Okay, last thing I promise!!

My program kinda crashes when I have a blank input.txt.  I tried fixing the problem by checking if: input = null, "", etc.  But it still doesn't work.
Try to catch the exception raised up.
Avatar of luna621

ASKER

raised up?  This is what I tried:

        // checks for data in correct format - integers, spaces, and tabs only
        catch(FileNotFoundException e) {
            System.out.println("Can't open input.txt.  Please be sure that file exists before attempting");
            System.out.println("to run this program.");
            System.out.println("Program will now exit.\n");
            System.exit(0);
        } // END catch
        catch(NumberFormatException notInt) {
            System.out.println("Please be sure input.txt contains integers, spaces, and tabs only.");
            System.out.println("Program will now exit.\n");
            System.exit(0);
        } // END catch
        catch(IOException e) {
            System.out.println("I/O error while processing input.txt.  Please be sure the file is not blank.");
        } // END catch
        finally {
            if(readFile != null) {
                try {
                    readFile.close();
                } // END try
                catch (IOException e) {
                    System.out.println("An error occured while processing.  Please be sure you have a valid");
                    System.out.println("file named input.txt containing only integers, spaces, and tabs.");
                    System.out.println("Program will now exit.\n");
                    System.exit(0);
                } // END catch
            } // END if
        } // END finally
Avatar of luna621

ASKER

Oh, and my catch is not catching the FileNotFoundException either...
But the exception raised up is a FileNotFoundException??

To catch all the exception could raised up you can catch Exception (in general).

Avatar of luna621

ASKER

I tried that too, and it didn't work.  Here's my whole code again:

 import java.io.*;
 import java.util.*;

 public class ReadInputArray {

      public static void main (String[] arg) throws Exception {

        BufferedReader readFile = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
        String input = "";

        File output = new File("output.txt"); // writes to output.txt
        FileOutputStream outFromFile = new FileOutputStream(output);
        PrintStream ps = new PrintStream(outFromFile);

        ArrayList digitsList = new ArrayList(); // create new ArrayList for ints

        try {
            // Read input from input.txt

            while((input = readFile.readLine())!=null) { // reads until there are no characters left

                // separates the ints from the spaces

                StringBuffer sbDigits = new StringBuffer(); // create new string
                int len = input.length(); // length of input

                // runs through entire length of string
                for(int i=0; i<len; i++) {
                    char c = input.charAt(i);
                    if(c == ' ' || c == '\t') { // if the character is space or tab
                        if(sbDigits.length()>0) {
                            Integer num = new Integer(sbDigits.toString());
                            digitsList.add(num);
                            sbDigits = new StringBuffer();
                        } // END if
                    } // END if
                    else {
                        sbDigits.append(c);
                    } // END else
                } // END for

                if(sbDigits.length()>0){
                    Integer num = new Integer(sbDigits.toString());
                    digitsList.add(num);
                    sbDigits = new StringBuffer();
                } // END if

                // Sort input array in increasing order by calling on QuickSort class
                Comparable[] array = (Comparable[])digitsList.toArray(new Comparable[0]);
                QuickSort.quickSort(array, 0, array.length-1);

                // Below is the call for the freeware function Sort.java
                //Sort.quicksort_inner(array, 0, array.length-1);

                // Output the resulting array
                for(int i=0; i<array.length; i++){
                    System.out.print(array[i] + " ");
                    ps.print(array[i] + " "); // writes what was read to output.txt
                } // END for

                System.out.println("\n\nProcess complete.  Please check your output.txt.\n");

            } // END while
        } // END try

        // checks for data in correct format - integers, spaces, and tabs only
        catch(FileNotFoundException notFound) {
            System.out.println("Can't find input.txt.  Please be sure that file exists before attempting");
            System.out.println("to run this program.");
            System.out.println("Program will now exit.\n");
            System.exit(0);
        } // END catch
        catch(NumberFormatException notInt) {
            System.out.println("Please be sure input.txt contains integers, spaces, and tabs only.");
            System.out.println("Program will now exit.\n");
            System.exit(0);
        } // END catch
        catch(IOException e) {
            System.out.println("I/O error while processing input.txt.  Please be sure the file is not blank.");
        } // END catch
        finally {
            if(readFile != null) {
                try {
                    readFile.close();
                } // END try
                catch (IOException e) {
                    System.out.println("An error occured while processing.  Please be sure you have a valid");
                    System.out.println("file named input.txt containing only integers, spaces, and tabs.");
                    System.out.println("Program will now exit.\n");
                    System.exit(0);
                } // END catch
            } // END if
        } // END finally
/*
        catch(Exception invalidEntry) {
             System.out.println("An error occured while processing.  Please be sure you have a valid");
             System.out.println("file named input.txt containing only integers, spaces, and tabs.");
             System.out.println("Program will now exit.\n");
             System.exit(0);
        } // END catch
*/
      } // END main()


 } // END class ReadInputArray
I see 2 things:
1) The catch is commented.
2) The catch is not in the correct position (it maybe putted before finally and not after).
Could you post the full dump of the exception raised up?
Avatar of luna621

ASKER

Oh, I commented it out because that one wasn't working.  So, I tried it individually.  Basically, when I test for a blank input.txt I get nothing.  No message, no output.txt.  When I delete the input.txt then run the program, it throws the FileNotFoundException.

I'll post the dump for the FileNotFoundException:

Exception in thread "main" java.io.FileNotFoundException: input.txt (The system
cannot find the file specified)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(FileInputStream.java:106)
        at java.io.FileInputStream.<init>(FileInputStream.java:66)
        at ReadInputArray.main(ReadInputArray.java:23)
Press any key to continue . . .
Avatar of luna621

ASKER

And this is what happens when input.txt is blank:


Press any key to continue . . .

No error message.
Avatar of luna621

ASKER

I even tried:

            int len = input.length(); // length of input

            if(len == 0) {
                System.out.println("input.txt is blank.  Please be sure input.txt contains integers, spaces, and tabs only.");
                System.out.println("Program will now exit.\n");
                System.exit(0);
            } // END if
So they are 2 situation.
File not exist: you must intercept it only using catch FileNotFoundException
File empty: you can intercept it looking at the len of the Array read.
insert this line:
...
if (digitsList.size()==0) {System.out.println("There are no number to order");}
// Sort input array in increasing order by calling on QuickSort class
...
Avatar of luna621

ASKER

Nope, still nothing on System.out.println()...
Ok.
Now try to move the line I poste before between these lines:
            } // END while
//<---------------------put it here
        } // END try
Avatar of luna621

ASKER

Ah ha!  It worked.  Now for the FileNotFoundException... it's still giving that dump.
Avatar of luna621

ASKER

Ah, I fixed it.  Had to move my try { up a few lines :)
move the line:
BufferedReader readFile = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));

in the
try{
Avatar of luna621

ASKER

Thank you!!!!!!   =^^=
Ok.
Now is all working?
Avatar of luna621

ASKER

Yes thank you very much!!!  Do I need to give extra points for help after a question is closed?  I don't mind :)
Don't worry.
>Do I need to give extra points for help after a question is closed?
It's little complicated.
Don't worry.

Happy to be of some help for you.
:)
Bye, Giant.
Avatar of luna621

ASKER

Okay, thank you for being so nice  :)

-goodnight!!