Reading a text file in Java and printing backwards with recursion - java

Write a Java program that recursively reads ten names from a file, and then outputs the total number of characters in the names, the list of names, and the list of names in reverse order. All looping must be performed recursively.
Jay Walker
Erol Flintstone
C. Erol Madre
Billy Pilgrim
Mickey Angels
José Francisco de San Martín
Squarebob Sponge Pants
Mischa Ternoff
Chester Peak
Al Italia
Ben Dover
Pat Pending
I am 100% lost. I would like advice on where would be the first place to start. Thinking about the program, I wanted to build a main that would call a scanner that would read the file first. When reading the file, it would count the characters in the text (quick question, would a scanner count the spaces between the characters?).
Next I was thinking of just a simple print function that would display the entire names.txt file.
Finally, the part the I'm 110% lost...how the heck would I go about listing the names in reverse order? What would I use? How does recursion fit in all this?

Something like this:
Reader(Stream strm)
{
string line;
if(!strm.eof())
{
line = strm.ReadLine();
Reader(strm);
}
// Info - char counte etc
string parseResult = Parse(line);
Print(parseResult);
}
Recursion will stop at the end of file and will start to unroll. The last message will be printed first.

Pseudocode for the recursion part:
function printLines(lines):
if lines not empty:
print first line from lines // this prints lines in order
call printLines(remaining lines)
print first line again // this prints lines in reverse order
Example output for lines ["line1", "line2", "line3"]
line1 // 1st output for printLines(["line1", "line2", "line3"])
line2 // 1st output for printLines(["line2", "line3"])
line3 // 1st output for printLines(["line3"])
// no output for printLines([])
line3 // 2nd output for printLines(["line3"])
line2 // 2nd output for printLines(["line2", "line3"])
line1 // 2nd output for printines(["line1", "line2", "line3"])

You can read file with scanner.nextLine(). It would read an entire line includiing spaces.
For how to print a string backwards using recursion, imagine that as a way containing houses on sides. You want to visit houses backwards (although you entered the way forwards). So you decided to go ahead until the way's end, and then back step by step and print neighbour house names.
function print( i )
if i == wayEnd
return
print(i + 1) // go ahead
// after you return, print:
output house at i
ADD
The code of method should be then:
private static Scanner scanner;
private static void readFile() {
if (!scanner.hasNext()) return;
String line = scanner.nextLine();
readFile();
System.out.println(line);
}
Just you have to call readFile() from main:
public static void main(String[] args) {
scanner = new Scanner(new File("myText.txt"));
readFile();
}

Am not good at scanning but using Desolator's scanner you can do the rest of the part as follows,
private Scanner scanner;
static Map<String, Integer> counts = new HashMap<String, Integer>();
public static void main(String[] args) {
scanner = new Scanner(new File("myText.txt"));
readFile();
System.out.println(counts);
}
private void readFile() {
if (!scanner.hasNext()) return;
String line = scanner.nextLine();
String[] names = line.split("([\\W\\s]+)");
for(int i=0;i<names.length;i++) {
populateMap(names[i]);
}
readFile();
}
static void populateMap(String str) {
counts.put(reverse(str), str.length());
}
static String reverse(String s) {
if(s.length() == 0)
return "";
return s.charAt(s.length() - 1) + reverse(s.substring(0,s.length()-1));
}

To train my Java skills I wrote you the following code:
import java.util.*;
import java.io.*;
public class RecursiveReadNames{
public static final int MAXLINES = 10;
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(new File("listOfNames.txt"));
String[] names = new String[MAXLINES];
readNames(names, scan, 0);
printNames(names,0);
System.out.println();
printNamesReverse(names,0);
System.out.println(totalNumberOfCharsInNames(names, 0,0));
}
static String[] readNames(String[] names, Scanner scan, int curLine) {
if(curLine >= MAXLINES)
return names;
names[curLine] = scan.nextLine();
return readNames(names, scan, curLine+1);
}
static void printNames(String[] names, int cur) {
if(cur >= names.length)
return;
System.out.println(names[cur]);
printNames(names, cur+1);
}
static void printNamesReverse(String[] names, int cur) {
if(cur >= names.length)
return;
printNamesReverse(names, cur+1);
System.out.println(names[cur]);
}
static int totalNumberOfCharsInNames(String[] names, int cur, int sum) {
if(cur >= names.length)
return sum;
return totalNumberOfCharsInNames(names, cur+1, sum+names[cur].length());
}
}

do something like this
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Test {
public static void printname(String name,BufferedReader br)
{
if(name!=null && br!=null)
{
try {
Test.printname(br.readLine(), br);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name);
}
}
static Scanner scanner1 = new Scanner(System.in);
public static void main(String[] args)
{
//print the names and total character in each name
try {
FileInputStream fin=new FileInputStream("d:\\file.txt");
BufferedReader br=new BufferedReader(new InputStreamReader(fin));
String n;
while((n=br.readLine())!=null)
{
System.out.println(n+" length:"+n.length());
}
fin.close();
br.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//print names in reverse order
try {
FileInputStream f=new FileInputStream("d:\\file.txt");
BufferedReader br=new BufferedReader(new InputStreamReader(f));
try {
Test.printname(br.readLine(),br);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
f.close();
br.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
notice that I'm passing br object

import java.util.Scanner;
import java.io.*;
class Listnames{
public static void recursiveRead(Scanner scanner) {
String name;
if(scanner.hasNext())
{name=scanner.next();
recursiveRead(scanner);
System.out.println(name.length() +" "+ name);
}
}
public static void main(String[] args)
{
try{
Scanner scanner=new Scanner(new File("name.txt"));
scanner.useDelimiter(System.getProperty("line.separator"));
recursiveRead(scanner);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}

Related

How I can to skip some area of text, when reading file?

I reading a .txt file and want to skip a listing of code in this text, when putting result in StringBuilder.
The example of text:
The following Bicycle class is one possible implementation of a
bicycle:
/* The example of Bicycle class class Bicycle {
int cadence = 0;
int speed = 0; } */
So that's what I could come to:
public class Main {
public static BufferedReader in;
public static StringBuilder stringBuilder = new StringBuilder();
public static void main(String[] args) {
String input = "input_text.txt";
try {
in = new BufferedReader(new FileReader(input));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String inputText;
try {
while ((inputText = in.readLine()) != null) {
if (inputText.startsWith("/*")) {
// The problem is there:
while (!inputText.endsWith("*/")) {
int lengthLine = inputText.length();
in.skip((long)lengthLine);
}
}
stringBuilder.append(inputText);
}
} catch (IOException e) {
e.printStackTrace();
}
I got the infinity while loop and can't jump to next line.
You never reset the value of inputText in your while loop, so it will never not end with */ resulting in an infinite loop. Also you don't need to use the skip() method as simply reading the lines until you encounter a */ will work. Try changing your loop to:
while (!inputText.endsWith("*/")) {
String temp = in.readLine();
if(temp == null) {break;}
inputText = temp;
}
Output: (With printing the StringBuilder)
The following Bicycle class is one possible implementation of a bicycle:

Reverse lines in ArrayList Java

I'm working on a Java program in which I must read the contents of a file and then print each lines reverse. For example the text:
Public Class Helloprinter
Public static void
would print the following after running my reverse program:
retnirPolleh ssalc cilbup
diov citats cilbup
Here's what I got so far:
public static void main(String[] args) throws FileNotFoundException {
// Prompt for the input and output file names
ArrayList<String> list = new ArrayList<String>();
//String reverse = "";
Scanner console = new Scanner(System.in);
System.out.print("Input file: ");
String inputFileName = console.next();
System.out.print("Output file: ");
String outputFileName = console.next();
// Construct the Scanner and PrintWriter objects for reading and writing
File inputFile = new File(inputFileName);
Scanner in = new Scanner(inputFile);
PrintWriter out = new PrintWriter(outputFileName);
String aString = "";
while(in.hasNextLine())
{
String line = in.nextLine();
list.add(line);
}
in.close();
for(int i = 0; i <list.size(); i++)
{
aString = list.get(i);
aString = new StringBuffer(aString).reverse().toString();
out.printf("%s", " " + aString);
}
out.close();
}
}
EDIT:
With Robert's posting it helped put me in the right direction. The problem is that with that is that it doesn't keep the lines.
Public Class Helloprinter
Public static void
becomes after running my program:
retnirPolleh ssalc cilbup diov citats cilbup
it needs to keep the line layout the same. so it should be:
retnirPolleh ssalc cilbup
diov citats cilbup
Your problem is in the line
out.printf("%s", " " + aString);
This doesn't output a newline. I'm also not sure why you are sticking a space in there.
It should be either:
out.println( aString );
Or
out.printf("%s%n", aString);
In your last loop why don't you just iterate through the list backwards? So:
for(int i = 0; i <list.size(); i++)
Becomes:
for(int i = list.size() - 1; i >=0; i--)
It seems like you already know how to read a file, so then call this method for each line.
Note, this is recursion and it's probably not the most efficient but it's simple and it does what you want.
public String reverseString(final String s) {
if (s.length() == 0)
return s;
// move chahctrachter at current position and then put it at the end of the string.
return reverseString(s.substring(1)) + s.charAt(0);
}
Just use a string builder. You were on the right trail. Probably just needed a little help. There is no "one way" to do anything, but you could try something like this:
Note: Here is my output: retnirPolleh ssalc cilbup diov citats cilbup
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Scanner;
public class Reverse {
public static void main(String[] args) {
ArrayList<String> myReverseList = null;
System.out.println("Input file: \n");
Scanner input = new Scanner(System.in);
String fileName = input.nextLine();
System.out.println("Output file: \n");
String outputFileName = input.nextLine();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(fileName));
String text = null;
myReverseList = new ArrayList<String>();
StringBuilder sb = null;
try {
while ((text = br.readLine()) != null) {
sb = new StringBuilder();
for (int i = text.length() - 1; i >= 0; i--) {
sb.append(text.charAt(i));
}
myReverseList.add(sb.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Writer writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFileName), "utf-8"));
for (String s : myReverseList) {
writer.write("" + s + "\n");
}
} catch (IOException ex) {
// report
} finally {
try {
writer.close();
} catch (Exception ex) {
}
}
}
}

Integer.parseint exceptions

The question was :
Write a program that processes an input.txt file that contains data regarding ticket type followed by mileage covered and reports how many frequent-flier miles the person earns.
1 frequent flyer mile is earned for each mile traveled in coach.
2 frequent flyer miles are earned for each mile traveled in first class.
0 frequent flyer miles are earned on a discounted flight.
For example, given the data in input.txt below, your method must return 15600 (2*5000 + 1500 + 100 + 2*2000).
Input.txt:
firstclass 5000 coach 1500 coach
100 firstclass 2000 discount 300
My code gives me a problem with the parseint method. Any help would be appreciated :)
//InInteger class
import java.lang.NumberFormatException;
public class IsInteger {
public static boolean IsaInteger (String s)throws NumberFormatException
{
try
{
Integer.parseInt(s);//converts the string into an integer
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
}
//main class
import java.io.*;
import java.util.StringTokenizer;
public class LA5ex2 {
public static void main(String[] args) throws FileNotFoundException {
BufferedReader input= new BufferedReader (new InputStreamReader (new FileInputStream("C:/Users/user/workspace/LA5ex2/input.txt")));
String str;
int TotalMiles=0;
try {
int mileage,lines=0;
String check,copy=null;
String word=null;
boolean isString=false;
while ((str = input.readLine()) != null)
{
lines++;
StringTokenizer token = new StringTokenizer(str);
while (token.hasMoreTokens())
{
if ((lines>1) && (isString))
{
//do nothing
}
else
{word= token.nextToken();
copy=word;}
if (token.hasMoreTokens())
mileage= Integer.parseInt(token.nextToken());
else
{
if (!(IsInteger.IsaInteger(word)))
{
copy=word;
isString=true;
}
break;
}
if (copy.equals("firstclass"))
TotalMiles+= (2*mileage);
else if (copy.equals("coach"))
TotalMiles+= (1*mileage);
else if (copy.equals("discount"))
TotalMiles+= (0*mileage);
}
}
System.out.println("Frequent-flier miles the person earns: "+ TotalMiles);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
This is the stacktrace that I get when running your code:
Exception in thread "main" java.lang.NumberFormatException: For input string: "firstclass"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:481)
at java.lang.Integer.parseInt(Integer.java:514)
at LA5ex2.main(LA5ex2.java:30)
I assume this is the error that you mention in your comment. However, the NumberFormatException does not occur in your IsaInteger() method in the IsInteger class (where you try-catch it by returning true or false), but in the LA5ex2 class (where you also try-catch it, but if it crashes, only the stacktrace gets printed). The exception occurs when Integer.parseInt() tries to parse the string firstclass as an integer, which of course fails:
if(token.hasMoreTokens()) mileage = Integer.parseInt(token.nextToken());
I rewrote your code in LA5ex2.java with two ArrayLists (to keep track of the various flier classes and the various mileages) using your IsaInteger method:
import java.io.*;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class LA5ex2 {
public static void main(String[] args) throws FileNotFoundException {
BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
String str = null;
String token = null;
int totalMiles = 0;
int lines = 0;
ArrayList<String> flierClasses = new ArrayList<String>();
ArrayList<Integer> mileages = new ArrayList<Integer>();
try {
while((str = input.readLine()) != null) {
lines++; // Why are we counting the lines, anyway?
StringTokenizer tokenizer = new StringTokenizer(str);
while(tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
if(!(IsInteger.IsaInteger(token))) {
flierClasses.add(token); // if it's not an int, we assume it's a flier class
} else {
mileages.add(Integer.parseInt(token)); // if it's an int, it's a mileage
}
}
}
} catch(NumberFormatException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
} catch(IOException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
// Add everything up
for(int i = 0; i < flierClasses.size(); i++) {
totalMiles += calculateFlierMiles(flierClasses.get(i), mileages.get(i));
}
System.out.println("Frequent-flier miles the person earns: " + totalMiles);
}
private static int calculateFlierMiles(final String flierClass, final int mileage) {
if(flierClass.equals("firstclass")) return(2 * mileage);
else if(flierClass.equals("coach")) return(1 * mileage);
else if(flierClass.equals("discount")) return(0 * mileage);
return 0;
}
}
This code gives me the desired output: Frequent-flier miles the person earns: 15600
I'm assuming the problem is in IsaInteger (which should be stylized as isAnInteger). In that case, add a line that prints out the value of s before the try/catch and tell me what you get.
Also, why are you using tokens when you could use a BufferedReader and its nextLine() method?

Storing a text file of numbers into an array in java

Hi guys i have a text file in the following path C:/Users/Marc/Downloads/vector25 which contains comma-separated values in the following format
-6.08,70.93,-9.35,-86.09,-28.41,27.94,75.15,91.03,-84.21,97.84,
-51.53,77.95,88.37,26.14,-23.58,-18.4,-4.62,46.52,-19.47,17.54,
85.33,52.53,27.97,10.73,-5.82,
How would i read this text file and store those doubles in an array ?
I'm currently thinking of trying a buffered reader but so far the answer eludes me can anyone point me in the right direction ?
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class subvector {
public static void main(String[] args){
FileReader file = null;
try {
file = new FileReader("C:/Users/Marc/Downloads/vector25");
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ArrayList<Double> list = new ArrayList<Double>();
int i=0;
try {
Scanner input = new Scanner(file);
while(input.hasNext())
{
list.add(input.nextDouble());
i++;
}
input.close();
}
catch(Exception e)
{
e.printStackTrace();
}
for(double k:list){
System.out.println(k);
}
}
You should use a delimeter
Scanner input = new Scanner(file);
input.useDelimeter(",");
Scanner.nextDouble() uses whitespace as the delimiter by default. Your input has commas as delimiter. You should use input.useDelimiter(",") to set commas as the delimiter before calling input.hasNext(). Then it should work as expected.
I think your code snippet will not for the specified data i.e. -6.08,70.93,-9.35,-86.09,-28.41,27.94,75.15,91.03,-84.21,97.84, -51.53,77.95,88.37,26.14,-23.58,-18.4,-4.62,46.52,-19.47,17.54, 85.33,52.53,27.97,10.73,-5.82,
But your program will work fine these type of data :
19.60
63.0
635.00
896.63
47.25
I have modified your program and tested with your data also. It's working as expected.
public static void main(String[] args) {
FileReader file = null;
try {
file = new FileReader("D:\\log4j\\vector25.txt");
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ArrayList<Double> list = new ArrayList<Double>();
int i=0;
Double d= null;
try {
BufferedReader input = new BufferedReader(file);
String s=null;
while((s=input.readLine())!=null) {
StringTokenizer st = new StringTokenizer(s,",");
while(st.hasMoreTokens()) {
try {
d = Double.parseDouble(st.nextToken());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
list.add(i, d);
}
}
input.close();
} catch(Exception e) {
e.printStackTrace();
}
for(double k:list) {
System.out.println(k);
}
}
Please review it and let me know if you update anything.
This is my first POST on stackoverflow.
Thanks, Prasad

Writing to file with Java

I am trying to write a simple method to save my document to a file (overwriting any previous contents of the file.) Unfortunately, my implementation does not seem to work. I am calling it on my document, which is, for all intents and purposes, an array of String. What I'd like to do is to write the contents of my array, with a separate line for each value in the array, the value in position [0] on the first line, and the value for [1] on the second. How would I go about this ?
This is my implementation so far :
public void save()
{
try
{
PrintWriter outputFile =
new PrintWriter(new BufferedWriter(new FileWriter(docName)));
int lineNo = 1;
while (lineNo != lineNo) // CHANGE THIS!!!
{ outputFile.println(" ~ ");
lineNo++;
}
outputFile.flush();
}
catch (Exception e)
{
System.out.println("Document: Touble writing to "+docName);
System.exit(1);
}
}
If a is an array of strings,
for (String s : a)
outputFile.println(s);
will print the array line-by-line to outputFile.
Iterator over the array, and write the current element.
String document[] = {"String1","String2","String3"};
PrintWriter outputFile =
new PrintWriter(new BufferedWriter(new FileWriter(docName)));
int lineNo = 1;
for(int i = 0; i < document.length; i++)
{ outputFile.println(document[i]);
lineNo++;
}
// myDoc is the "array of string"
foreach (String line : myDoc) {
outputFile.println(line);
}
I might write it more like this:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
/**
* FileDemo
* #author Michael
* #since 2/26/11
*/
public class FileDemo
{
public static void main(String[] args)
{
try
{
FileDemo fd = new FileDemo();
fd.save("out/test.txt", args);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
public void save(String filePath, String [] lines) throws FileNotFoundException
{
PrintStream ps = null;
try
{
ps = new PrintStream(new FileOutputStream(filePath));
int lineNum = 1;
for (String line : lines)
{
ps.printf("%5d %s\n", lineNum++, line);
}
}
finally
{
close(ps);
}
}
public static void close(PrintStream ps)
{
if (ps != null)
{
ps.flush();
ps.close();
}
}
}
I didn't see any actual content in your code, so I added some. I didn't how a file with line numbers was very interesting. You'd be able to modify this to make it differently if you wish.

Categories

Resources