Deduplication from text file using scanner without arrays (Java) - java

I'm trying to read a text file that contains integers on different lines that are already sorted from least to greatest. Said integers have to be transported to another text file but without any duplicates and without using any sort of arrays, array list, maps, sets, or any other sort of data structure.
Currently I've tried to read numbers from the first text file,and use a while loop to check if the next numbers are similar, with the Scanner. The only problem is that the loop gets the next integer in it as well so this algorithm only works if all numbers are duplicated. This'll make my day if somebody could at least point me in the right direction, thanks in advance!
Example Text File One (all integers are on a new line): 5 5 5 5 5 8 8 9 9 9 9 10 10 11
My output: 5 8 9 10
Expected Output: 5 8 9 10 11
public static void deduplicateFiles(String inputFileName,String outputFileName){
Scanner scan = null;
try{
scan = new Scanner(new FileInputStream(inputFileName) );
}catch(FileNotFoundException e){
System.out.println(e.getMessage() );
}
PrintWriter writer = null;
try{
writer = new PrintWriter(outputFileName);
}catch(FileNotFoundException e){
System.out.println(e.getMessage());
}
while(true){
int firstInt = scan.nextInt();
scan.nextLine();
//if(scan.nextInt() != firstInt)
int counter = 1;
while(scan.nextInt() == firstInt && scan.hasNext() != false){
System.out.println("counter" +counter);
counter++;
scan.nextLine();
}
System.out.println("The integers:" + firstInt);
writer.println(firstInt);
if(scan.hasNext() == false)
break;
}
writer.flush();
writer.close();
}

Read all the integers from the file first. Add them to a Set and then write from the set to a file. You can use LinkedHashSet to keep the order.

I've modified the second part of your code, adding a comparison between numbers to the variable 'nextInt'. It was mainly about entries in the right places, I hope it resolve your problem:
public void deduplicateFiles (String inputFileName, String outputFileName){
Scanner scan = null;
try {
scan = new Scanner(new FileInputStream(inputFileName));
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
PrintWriter writer = null;
try {
writer = new PrintWriter(outputFileName);
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
while (true) {
//this two lines are initial
int firstInt = scan.nextInt();
int counter = 1;
//next lines are compare adjacent values
while (scan.hasNextLine()) {
int nextInt = scan.nextInt();
if (nextInt == firstInt) {
counter++;
} else {
System.out.println("counter " + counter);
counter = 1;
System.out.println(firstInt);
writer.println(firstInt);
firstInt = nextInt;
}
}
//this three lines terminate adding
writer.print(firstInt);
System.out.println("counter " + counter);
System.out.println(firstInt);
break;
}
writer.flush();
writer.close();
}

Related

Summing the doubles from a file

I've got a .txt file and here's its content:
1.1, 1.2, 1.3, 2.0, 1.8
1.3, aa, 4.5, 6.7, 2.1
3.5, 7.7, 9.9, 4.1, 2.1
I've got to load all lines from it, and if there'a double, sum it and show at the end.
I've written this program:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main3 {
public static void main(String[] args) {
File main3File = new File("Main3.txt");
double sum = 0;
try {
Scanner scan = new Scanner(main3File);
scan.useDelimiter(", ");
while (scan.hasNextLine()) {
if (scan.hasNextDouble()) {
sum += scan.nextDouble();
System.out.println(sum);
}
}
} catch (FileNotFoundException ex) {
System.out.println("Blad");
}
System.out.println("Suma: " + sum);
}
}
Here's the output:
1.1
2.3
3.5999999999996
5.6
So it sum the first three numbers, then stop and the while loop doesn't stop (if I write something under 'if', it shows without stopping). It doesn't sum the last number (1.8) and it doesn't go to the next line.
I guess it's something wrong with delimeter, right? But I don't have idea how to change it. Do you have an idea?
The main problem is you are mixing up lines and numbers, it may be better to process them separately.
If you process the lines and numbers separately, it's easier to be sure your loop condition is correct:
Scanner lineScanner = new Scanner(file);
// Loop through lines
while (lineScanner.hasNextLine()) {
String line = scan.nextLine();
Scanner numberScanner = new Scanner(line);
numberScanner.useDelimiter(", ");
// Loop through numbers in each line
while (numberScanner.hasNextFloat()) {
float value = numberScanner.nextFloat();
// do something with each value
}
System.out.println(sum);
}
If you really need to process the file in a single loop, then you need to use a delimiter that caters for the comma and any whitespace:
Scanner scan = new Scanner(main3File);
scan.useDelimiter("\\s*,\\s*");
while (scan.hasNext()) {
String next = scan.next();
try {
float value = Float.valueOf(next);
// do something with each value
} catch (NumberFormatException e) {
// not a float
}
}
\\s* is a pattern meaning 0 or more repetitions of any whitespace character.
Read one line at a time and split with comma to get the values. Check further if value is a double or not.
File main3File = new File("Main3.txt");
double sum = 0;
try {
Scanner scan = new Scanner(main3File);
String line ;
while (scan.hasNextLine()) {
line = scan.nextLine();
String[] values = line.trim().split("\\s*,\\s*");
for (String value : values) {
try {
double num = Double.parseDouble(value);
sum = sum + num;
System.out.println(sum);
} catch (NumberFormatException e) {
// System.out.println("Value is not double. hence ignored");
}
}
}
} catch (FileNotFoundException ex) {
System.out.println("Blad");
}
System.out.println("Suma: " + sum);
Let me know if you have any doubts !
1 ) Your code has a algorithm problem.
//There is a infinite loop below. You are checking next scan and handling it if it's double
//But you keep continue to loop without passing next if it is not double, this causes infinite loop
while (scan.hasNextLine()) {
if (scan.hasNextDouble()) {
sum += scan.nextDouble();
System.out.println(sum);
}
}
You have to add else statement and pass next like stated blow;
else{
scan.next();
}
2 ) You can not delimit line using
numberScanner.useDelimiter(", ");
Because you have got a multi-lined text, which scanner sees your text's end of line as a special character ("\n"). Yoo better use another way to parse, may be splitting it with String's .split method.
Hope it helps.

How to write on a .txt file? [duplicate]

This question already has answers here:
Write to text file without overwriting in Java
(9 answers)
Closed 3 years ago.
I am new to java and I am working on a program that calculates a binary number to it's base 10 equivalent and saves each valid entry on a .txt file. Problem is that each entry is being overwritten that the only one that's saved is that last one entered. Can anyone point out what i'm doing wrong? and any tips on improving the syntax in general. Much appreciated.
import java.util.Scanner;
import java.io.*;
public class BinaryNum {
public static void main(String[] args) throws IOException //for file writing
{
Scanner keyboard = new Scanner(System.in);
String userEntry;// initial input by user for binary numbers
int ValidUserEntryNum;
int Decimal;
boolean decision = false; //bool to let user choose to continue
boolean bool; //variable to check if the valid string is a binary number
//loops for when the user names a choice
while(!decision)
{
//loops for when the user enters a binary number
do {
System.out.println("Please Enter a Binary Number: ");
userEntry = keyboard.nextLine();
//check to see if input is a string of numbers
userEntry = checkEntry (userEntry);
// convert string to int
ValidUserEntryNum = Integer.parseInt(userEntry);
//bool variable to see if the number is Binary
bool = CheckIsBinary (ValidUserEntryNum);
//check to see if the number is binary
if (!bool)
{
System.out.println("** Invalid.Input Must be a Binary number **");
}
} while(bool == false); //parameter for the loop (whether the number entered was binary)
//convert binary number to decimal number
Decimal = convert(ValidUserEntryNum);
//display on console
System.out.println("You Entered: " + ValidUserEntryNum);
System.out.println("It's base 10 equivilant is: " + Decimal);
System.out.println();
//creates the file name
File fileWR = new File("outDataFile.txt");
//creates the file object
fileWR.createNewFile();
BufferedWriter output = new BufferedWriter(new FileWriter(fileWR));
//to check if there is an existing file
if (fileWR.exists())
{
//writes in the file
output.write("You Entered: " + ValidUserEntryNum +"\r\n");
output.write("It's base 10 equivilant is " + Decimal +"\r\n");
output.close();
}
else //creates a new file if one doesnt already exist.
{
fileWR.createNewFile();
}
//option if the user wants to continue
System.out.println("Do you wish to continue?(yes or no):");
String st = keyboard.nextLine();
if (st.contentEquals("no"))
{
decision = true;
}
}
}
//to check if the user entered only a string of numbers (done)
public static String checkEntry (String userAnswer)
{
int UserLength = userAnswer.length();
int counter = 0;//to iterate through the string
// Create a Scanner object to read input.
Scanner keyboard = new Scanner(System.in);
while (UserLength == 0)
{
System.out.println("That is a blank");
System.out.println("Try again");
userAnswer = null;
userAnswer = keyboard.nextLine();
UserLength = userAnswer.length();
}
while (counter < UserLength)
{
if (!Character.isDigit(userAnswer.charAt(counter)))
{
System.out.println("That is not a binary number");
System.out.println("Try again");
userAnswer = null;
userAnswer = keyboard.nextLine();
UserLength = userAnswer.length();
counter = 0;
}
else
{
counter++;
}
while (UserLength == 0)
{
System.out.println("That is a blank, again");
System.out.println("Try again");
userAnswer = null;
userAnswer = keyboard.nextLine();
UserLength = userAnswer.length();
}
}
return userAnswer;
}
//method to check if the entered number is binary. (done)
public static boolean CheckIsBinary (int TrueBinary)
{
int temp;
while (TrueBinary > 0)
{
temp = (TrueBinary % 10);
if (temp != 1 && temp != 0)
{
return false;
}
TrueBinary = (TrueBinary/10);
}
return true;
}
//converts user binary to decimal
public static int convert(int ValidUserEntryNum)
{
//creating variables to convert binary to decimals
int temp = 0;
int Decimal = 0;
int power = 0;
//Convert the binary number to a decimal number
while (ValidUserEntryNum != 0)
{
temp = (ValidUserEntryNum % 10);
Decimal += temp * Math.pow(2, power++);
ValidUserEntryNum = (ValidUserEntryNum/10);
} return Decimal;
}
}
You are creating a new FileWriter and a new BufferedWriter each time inside the loop which is not necessary. You can move it outside the loop.
To make your existing code work, change
new FileWriter(fileWR)
to
new FileWriter(fileWR, true)
The second parameter passed is the append flag. From javadocs (emphasis mine)
boolean if true, then data will be written to the end of the file rather than the beginning.
It looks like you have fileWR.createNewFile(); both inside and outside the check.
//creates the file name
File fileWR = new File("outDataFile.txt");
//creates the file object
fileWR.createNewFile(); <--
BufferedWriter output = new BufferedWriter(new FileWriter(fileWR));
//to check if there is an existing file
if (fileWR.exists())
Change this line:
BufferedWriter output = new BufferedWriter(new FileWriter(fileWR));
To:
BufferedWriter output = new BufferedWriter(new FileWriter(fileWR), true);
Because the constructor you used for FileWriter defaults to overwriting.
http://tutorials.jenkov.com/java-io/filewriter.html#overwriting-vs-appending-the-file

Why doesn't my program read my file that was created using the same program?

I'm trying to create a program that makes a file that randomly generates numbers and I want the program to read those numbers off of the file and analyze it. If the randomly generated number doesn't equal 0, the program should keep generating numbers, but if it does equal 0, then the program will stop. However, it seems that my program is not reading those numbers.
I tried putting the outFile.close(); and inFile.close(); in a couple different places to see if that would fix anything, but it seems that didn't work out. I tried tracing my code with pen and paper, but I couldn't find anything wrong. Perhaps it could be my placement of outFile.close(); and inFile.close();, but I couldn't find anything wrong with it.
import java.util.*;
import java.io.*;
public class squirrel {
public static void main(String[] args) throws IOException{
Scanner in = new Scanner(System.in);
PrintWriter outFile = new PrintWriter(new File("squirrel.txt"));
Scanner inFile = new Scanner(new File("squirrel.txt"));
Random rand = new Random();
int squirrelNum;
int foxSquirrel = 0;
int squirrelsSeen = 0;
int trials = 0;
System.out.println("Welcome to the Fox Squirrel Simulator\n");
System.out.println("How many trials should be simulated?");
System.out.println("Enter a value greater than 1000: ");
trials = in.nextInt();
while(trials <= 1000)
{
System.out.println("Please try again. Enter a value greater than 1000: ");
trials = in.nextInt();
}
for(int i = 0; i <= trials; i ++)
{
squirrelNum = rand.nextInt(10);
outFile.println(squirrelNum);
while(inFile.hasNextInt())
{
int token = inFile.nextInt();
while(token != 0)
{
squirrelsSeen ++;
}
if(token == 0)
{
foxSquirrel ++;
squirrelsSeen ++;
}
outFile.close();
}
System.out.println("squirrelsSeen: " + squirrelsSeen);
System.out.println("foxSquirrel: " + foxSquirrel);
}
inFile.close();
System.out.println("\nsimulating trials now... one moment please...\n");
System.out.println("The results!");
System.out.println("The average number of squirrels until spotting a Fox Squirrel at the city park is: " + (((double)foxSquirrel / squirrelsSeen) * 100));
}
}
And here is how it is done using Scanner.
File file = new File("squirrel.txt");
try {
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
int i = sc.nextInt();
System.out.println(i);
}
sc.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
And it is like you said. You put the .close() inside your while loop in your code. Try putting it outside.
new PrintWriter(new File("squirrel.txt")) immediately erases the file. From the documentation:
If the file exists then it will be truncated to zero size; otherwise, a new file will be created.
It is not possible to read and write the same file simultaneously. (Actually there are some cases were it’s possible, but they don’t apply here.)
Do not create your PrintWriter until you have finished reading from the file and have called inFile.close(). Or, write to a different file, then when you’re done, rename it to match the original file.

Creating a program to read from a text file and count the number of 5's. output is off by one five

When I run the program everything seems to work fine except that it counts 8 fives when there are in fact 9 fives in the txt file.
import java.io.*;
import java.util.*;
public class FileIO2
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
String filename = "Input1.txt";
Scanner myFile = null;
try
{
myFile = new Scanner(new FileInputStream(filename));
}
catch(Exception e)
{
System.out.println("File not found.");
System.exit(0); //close the program
}
int countNums = 0;
while(myFile.hasNext())
{
if(myFile.hasNextInt(5))
{
countNums++;
}
myFile.next();
}
System.out.println("There were " + countNums + " fives in " + filename);
}
}
Input1.txt file contents:
5 9 3 2 0 5 3 0 8 5 5 5
5 9
4 3 0 6
5 5 5
I suggest you to do some refactor on your code.
This solution works fine:
public class FileIO2 {
private static final String PATH_TO_FILE = "/home/user/temp/Input1.txt";
private static final int NUMBER_TO_FIND = 5;
public static void main(String[] args) throws FileNotFoundException {
int counter = 0;
try (Scanner scanner = new Scanner(new File(PATH_TO_FILE))) {
while (scanner.hasNextInt()) {
int currentInt = scanner.nextInt();
if (currentInt == NUMBER_TO_FIND) {
counter++;
}
}
}
System.out.println("There were " + counter + " fives in " + PATH_TO_FILE);
}
}
The problematic line in your code is myFile.hasNextInt(5).
Here is your problem:
myFile.hasNextInt(5)
From the documentation of the hasNextInt(int) method:
Returns true if the next token in this scanner's input can be
interpreted as an int value in the specified radix (base) using the nextInt()
method.
So that doesn't return true if the next int value is 5 as you expect. It will return true if each digit in the number (and each number in this case has just one digit) is between 0-4 (radix 5)!.
So change your while loop to:
while(myFile.hasNext())
{
if(myFile.hasNextInt() && myFile.nextInt() == 5)
{
countNums++;
}
}
This time we validate that the number is actually 5 using hasNextInt() without arguments (which uses radix 10, i.e. the decimal system) and nextInt which returns the given number.

need help about reading numbers inside file

First I create a txt file (a.txt) -- DONE
create 10 random number from - to ( like from 5 -10 ) --DONE
I write this number in txt file --DONE
I want to check its written or not -- DONE
Now I need to find: how many number, biggest, smallest, sum of numbers
But I can not call that file and search in the file (a.txt). I am just sending last part. Other parts work. I need some help to understand. It is also inside another method. not main
Scanner keyboard = new Scanner(System.in);
boolean again = true;
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
int a = 0;
int count = 0;
System.out.println("Enter the filename to write into all analysis: ");
outputFileName = keyboard.nextLine();
File file2 = new File(outputFileName);
if (file2.exists()) {
System.out.println("The file " + outputFileName +
" already exists. Will re-write its content");
}
try {
PrintWriter yaz = new PrintWriter(file2);
// formulas here. created file a.txt need to search into that file biggest smallest and sum of numbers
yaz.println("Numeric data file name: " + inputFileName);
yaz.println("Number of integer: " + numLines);
yaz.println("The total of all integers in file: " + numLines); //fornow
yaz.println("The largest integer in the set: " + max);
yaz.println("The smallest integer in the set " + min);
yaz.close();
System.out.println("Data written to the file.");
} catch (Exception e) {
System.out.printf("ERROR reading from file %s!\n", inputFileName);
System.out.printf("ERROR Message: %s!\n", e.getMessage());
}
So you want a code to read a text file and give you the biggest, smallest and the average.
You can use Scanner class for that and use hasNextInt() to find integers
File f = new File("F:/some_text_file.txt"); // input your text file here
if(f.exists()){
try{
Scanner sc = new Scanner(f);
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
int temp=0, i=0;
double sum=0;
while(sc.hasNextInt()){
temp = sc.nextInt();
if(temp>max) max = temp;
if(temp<min) min =temp;
sum+=(double) temp;
i++;
}
System.out.println("average : " +sum/i);
System.out.println("large : "+max);
System.out.println("small :"+min);
sc.close();
}catch(Exception e){
e.printStackTrace();
}
}
See if this works
You need to read the file into memory. One way to do that is to move the text of the file into a String.
This post will help you: Reading a plain text file in Java
Here's the relevant code:
try(BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
}

Categories

Resources