1

I have 2 files that each contain a series of ordered numbers, separated by spaces (" ").

Write a program that produces a third file that will contain the ascending sequence of numbers. When solving, you are not allowed to use any type of collection.

File 1: 1 18 40 100 File 2: 0 10 15 80 1001

I managed to convert the number to String, but in the output file I've got the only 2 first numbers sorted : 0 1

       FileWriter outputFile;
        Scanner sc1 = null;
        Scanner sc2 = null;
        try {

            sc1 = new Scanner(new FileReader("Numbers1.txt"));
            sc2 = new Scanner(new FileReader("Numbers2.txt"));
            outputFile = new FileWriter("NumbersMerge.txt");
            int c = sc1.nextInt();
            int d = sc2.nextInt();
            while (sc1.hasNext() && sc2.hasNext()) {
                if (c < d) {
                    outputFile.write(Integer.toString(c));
                    sc1.nextLine();
                } else if (c > d) {
                    outputFile.write(Integer.toString(d));
                    sc2.nextLine();
                } else {
                    outputFile.write(Integer.toString(c));
                    outputFile.write(Integer.toString(d));
                    sc1.nextLine();
                    sc2.nextLine();
                }
            }
             if (sc1.hasNext()) {
                outputFile.write(Integer.toString(c));
                sc1.nextLine();
            }
            if (sc2.hasNext()) {
                outputFile.write(Integer.toString(d));
                sc2.nextLine();
            }
            outputFile.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (sc1 != null && sc2 != null) {
                sc1.close();
                sc2.close();
            }
        }
bumbi007
  • 25
  • 5
  • This sounds like a homework question. Also, please do not post duplicate questions https://stackoverflow.com/questions/72078873/write-a-program-that-reads-2-numbered-files-and-produces-a-third-file-that-conta – Eris Cacigieri May 01 '22 at 18:55

1 Answers1

0

Within your code you're only reading and sorting the first two numbers from each file, simply because you've used the right method, nextInt(), only once per file (right before the while loop).

After that, you're trying to "iterate" the rest of the files, but instead you're only reading the rest of both files' lines with the nextLine() method not their numbers. Besides, what you're reading with the nextLine() is not even assigned to anything, discarding everything you've just read.

What you want to do is replacing those nextLine() with nextInt() and those hasNext() with hasNextInt(). Furthermore, a PrintWriter will be more helpful than just a basic FileWriter in writing the actual int value. You may find more about it in the documentation and here.

public static void main(String[] args) {
    Scanner sc1 = null;
    Scanner sc2 = null;
    PrintWriter pw = null;
    int c = 0, d = 0;
    boolean isLeftConsumed = true;
    boolean isRightConsumed = true;
    try {
        sc1 = new Scanner(new FileReader("Numbers1.txt"));
        sc2 = new Scanner(new FileReader("Numbers2.txt"));
        pw = new PrintWriter(new FileWriter("NumbersMerge.txt"));

        //Keep reading as long as both files have numbers left
        while (sc1.hasNextInt() && sc2.hasNextInt()) {

            //Reading the number from the first file only if this has been consumed or on the first read
            if (isLeftConsumed) {
                c = sc1.nextInt();
                isLeftConsumed = false;
            }

            //Reading the number from the second file only if this has been consumed or on the first read
            if (isRightConsumed) {
                d = sc2.nextInt();
                isRightConsumed = false;
            }

            if (c < d) {
                pw.print(String.format("%d ", c));
                isLeftConsumed = true;
            } else if (c > d) {
                pw.print(String.format("%d ", d));
                isRightConsumed = true;
            } else {
                pw.print(String.format("%d ", c));
                pw.print(String.format("%d ", d));
                isLeftConsumed = true;
                isRightConsumed = true;
            }
        }

        //Writing the remaining numbers from the first file
        while (sc1.hasNextInt()) {

            //Reading the number from the first file only if this has been consumed or on the first read
            if (isLeftConsumed) {
                c = sc1.nextInt();
                isLeftConsumed = false;
            }

            //If the last number from the second file hasn't been written yet, then we keep checking whether it can be added or not
            if (!isRightConsumed) {
                if (c < d) {
                    pw.print(String.format("%d ", c));
                    isLeftConsumed = true;
                } else if (c > d) {
                    pw.print(String.format("%d ", d));
                    isRightConsumed = true;
                } else {
                    pw.print(String.format("%d ", c));
                    pw.print(String.format("%d ", d));
                    isLeftConsumed = true;
                    isRightConsumed = true;
                }
            } else {
                //Case where the last number from the second file has been written and there are still numbers left from the first file
                pw.print(String.format("%d ", c));
                isLeftConsumed = true;
            }
        }

        //Writing the remaining numbers from the second file
        while (sc2.hasNext()) {

            //Reading the number from the second file only if this has been consumed or on the first read
            if (isRightConsumed) {
                d = sc2.nextInt();
                isRightConsumed = false;
            }

            //If the last number from the first file hasn't been written yet, then we keep checking whether it can be added or not
            if (!isLeftConsumed) {
                if (c < d) {
                    pw.print(String.format("%d ", c));
                    isLeftConsumed = true;
                } else if (c > d) {
                    pw.print(String.format("%d ", d));
                    isRightConsumed = true;
                } else {
                    pw.print(String.format("%d ", c));
                    pw.print(String.format("%d ", d));
                    isLeftConsumed = true;
                    isRightConsumed = true;
                }
            } else {
                //Case where the last number from the first file has been written and there are still numbers left from the second file
                pw.print(String.format("%d ", d));
                isRightConsumed = true;
            }
        }

        //Checking whether the last number from the first file hasn't been written yet (case of the greatest of all)
        if (!isLeftConsumed) {
            pw.print(String.format("%d ", c));
        }

        //Checking whether the last number from the second file hasn't been written yet (case of the greatest of all)
        if (!isRightConsumed) {
            pw.print(String.format("%d ", d));
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (sc1 != null) {
            sc1.close();
        }
        if (sc2 != null) {
            sc2.close();
        }
        if (pw != null) {
            pw.close();
        }
    }
}
Dan
  • 3,647
  • 5
  • 20
  • 26
  • 1
    Thank you so much Dan for your help and explanations! I understood why I was only printing the first two numbers in ascending order... – bumbi007 May 01 '22 at 19:58
  • @bumbi007 I had to make an edit to the code as the previous version couldn't work with files of different size. This version now keeps track of the latest number read and whether this has been "consumed" (written) or not, proceeding with the subsequent read only if this has been printed in the output file. Try it for example with, file1 => 1 18 40 99999 and file2 => 0 10 15 80 1001 2000 3000 4000 – Dan May 01 '22 at 20:56
  • For me it worked with the first version of the code, i changed the content of two files with what you gave me (1 18 40 99999 and 0 10 15 80 1001 2000 3000 4000). The output file contains all sorted numbers. – bumbi007 May 02 '22 at 07:02
  • @bumbi007 with the first version of the code I posted the last number within the first file (99999) is lost, as that code didn't keep track during the double read whether a number has been written or not. So if the smaller file (first or second) ends also with a higher number than the other, then this number is lost as the following while loops only focus on the remaining elements of the other file. With the previous code the output is sorted, but it's 0 1 10 15 18 40 1001 2000 3000 4000 **instead of** 0 1 10 15 18 40 1001 2000 3000 4000 99999 – Dan May 02 '22 at 08:14
  • Dan, with the last version , the outputfile contains just : 0 1 10 15 18 40 80 100. Do you have an idea why? – bumbi007 May 07 '22 at 10:26
  • @bumbi007 Yeah. I've Just noticed that this is a first version of my answer, I've copied the wrong one. There's a slip up where I forgot to add the var reset (isLeftConsumed = false and IsRightConsumed = false) within the first if of both while loops. Luckily, I still have your problem saved in a project. I'll update the answer right now! – Dan May 07 '22 at 11:06
  • 1
    It works now, thank you again Dan for your help and time :) – bumbi007 May 07 '22 at 13:06