I'm designing a program to split data stored in a text file into two separate files based on the label of that data.
Here is a small version of that data.
0,1,2,normal.
5,5,5,strange.
2,1,3,normal.
I use a class to store each line as a sample. The class parses the line to store the last value as the label. I encapsulated each line as an object, because I intend to add features later.
Here is code for the Sample class
import java.util.Scanner;
public class Sample {
String[]str_vals = new String[3];
String label;
Sample(Scanner line) {
for (int i=0; i<3; i++) {
str_vals[i] = line.next();
}
label = line.next();
}
String getValsForCSV() {
StringBuilder retval = new StringBuilder();
for (int i=0; i<3; i++) {
retval.append(str_vals[i]).append(",");
}
retval.append(label).append(".");
return retval+"";
}
String getLabel() {
return label;
}
}
Below is the code in question. My Separator class.
import java.io.*;
import java.util.Scanner;
public class Separator {
public static final String DATAFILE = "src/etc/test.txt";
public static void main(String[] args) throws FileNotFoundException {
runData();
}
public static void runData() throws FileNotFoundException {
try (Scanner in = new Scanner(new File(DATAFILE))) {
// kddcup file uses '.\n' at end of each line
// setting this as delimiter which will consume the period
in.useDelimiter("[.]\r\n|[.]\n|\n");
Sample curr;
while(in.hasNext()) {
// line will hold all fields for a single sample
Scanner line = new Scanner(in.next());
line.useDelimiter(", *");
curr = new Sample(line);
try (
PrintWriter positive = new PrintWriter(new File(DATAFILE+"-pos"));
PrintWriter negative = new PrintWriter(new File(DATAFILE+"-neg"));
) {
if (curr.getLabel().equals("normal")) {
positive.println("GOOD");
} else {
negative.println("BAD");
}
}
}
}
}
}
This issue that I am experiencing is that the code only saves the last Sample seen to its respective file. So with above data the test.txt-neg will be empty and test.txt-pos will have a single line GOOD; it does not have two GOOD's as expected.
If I modify the test.txt data to include only the first two lines, then the files states are reversed (i.e. test.txt-neg has BAD and test.txt-pos is empty). Could someone please explain to me what is going on, and how to fix this error?
Because the error was pointed out in a comment. I wanted to give credit to KevinO and Elliott Frisch for the solution.
As mentioned, I'm creating a new PrintWriter each time and creating the PrintWriter in it's default mode of overwriting a file. As a result it always saves both files based on a single sample.
To correct this error, I have pulled out the instantiations of the PrintWriter to be in the try-with-resource block of the Scanner object
import java.io.*;
import java.util.Scanner;
public class Separator {
public static final String DATAFILE = "src/etc/test.txt";
public static void main(String[] args) throws FileNotFoundException {
runData();
}
public static void runData() throws FileNotFoundException {
try (
Scanner in = new Scanner(new File(DATAFILE));
PrintWriter positive = new PrintWriter(new File(DATAFILE+"-pos"));
PrintWriter negative = new PrintWriter(new File(DATAFILE+"-neg"));
) {
// kddcup file uses '.\n' at end of each line
// setting this as delimiter which will consume the period
in.useDelimiter("[.]\r\n|[.]\n|\n");
Sample curr;
while(in.hasNext()) {
// line will hold all fields for a single sample
Scanner line = new Scanner(in.next());
line.useDelimiter(", *");
curr = new Sample(line);
if (curr.getLabel().equals("normal")) {
positive.println("GOOD");
} else {
negative.println("BAD");
}
}
}
}
}
Related
I have to do a program and unfortunately I have no idea where to start. It's like we were doing very basic coding and then my teacher went on maternity leave and our substitute thinks we are further along then we actually are. I know how to ready from a file, but I do not know how to put the line into a stack from there.
These are the instructions
1) Read a line and push into a line-stack until the end of file 2) While line_stack is not empty a. Pop one element out and process the following i. Split elements in this line (i.e. numbers) using StringTokenzier ii. Push all numbers into number-stack iii. While number_stack is not empty 1. Pop a number 2. Print a character using that ascii number
If I understand the problem correctly you need to:
Represent a line as a java.lang.String.
Then using java.util.Stack create a Stack< String> and put all the lines there.
Use java.util.StringTokenizer to split each line into multiple parts. Each part will be a String itself.
Turn each part of the line into a number using Integer.valueOf(String)
Put all the numbers into a Stack< Integer>.
Print the right character for each number by casting integer value to char.
I think this may be the solution for your problem:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Stack;
import java.util.StringTokenizer;
public class LinesProcessor {
private static Stack<String> readLinesFromFile(String fileName) throws IOException {
Stack<String> lines = new Stack<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)))) {
String line = null;
while ((line = br.readLine()) != null) {
lines.push(line);
}
}
return lines;
}
private static void processNumbers(Stack<Integer> stackOfNumbers) {
while (!stackOfNumbers.empty()) {
Integer number = stackOfNumbers.pop();
System.out.print((char) number.intValue());
}
}
private static void processLine(String line) {
StringTokenizer tokenizer = new StringTokenizer(line, " ");
Stack<Integer> stackOfNumbers = new Stack<>();
while (tokenizer.hasMoreTokens()) {
Integer number = Integer.valueOf(tokenizer.nextToken());
stackOfNumbers.push(number);
}
processNumbers(stackOfNumbers);
}
private static void processLines(Stack<String> stackOfLines) {
while (!stackOfLines.empty()) {
String currentLine = stackOfLines.pop();
processLine(currentLine);
}
}
public static void main(String[] args) throws IOException {
if (args.length < 1) {
System.out.println("Name of file missing");
System.exit(1);
}
String fileName = args[0];
Stack<String> stackOfLines = readLinesFromFile(fileName);
processLines(stackOfLines);
}
}
Sometimes i solve problems in 'codeforces.org' and after every solve i see the solution of others.But most of the others solution contains so many codes.
For example:
I have written a code for the problem Domino Piling like following.
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int m = in.nextInt(), n = in.nextInt();
int count = n*(m/2);
if(m%2 == 1)
count += n/2;
System.out.println(count);
in.close();
}
}
But petr who ranked in 2nd in codeforces wrote this solution like
import java.io.*;
import java.util.*;
public class Template implements Runnable {
private void solve() throws IOException {
int n = nextInt();
int m = nextInt();
writer.println(n * m / 2);
}
public static void main(String[] args) {
new Template().run();
}
BufferedReader reader;
StringTokenizer tokenizer;
PrintWriter writer;
public void run() {
try {
reader = new BufferedReader(new InputStreamReader(System.in));
tokenizer = null;
writer = new PrintWriter(System.out);
solve();
reader.close();
writer.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
int nextInt() throws IOException {
return Integer.parseInt(nextToken());
}
long nextLong() throws IOException {
return Long.parseLong(nextToken());
}
double nextDouble() throws IOException {
return Double.parseDouble(nextToken());
}
String nextToken() throws IOException {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
}
Here what we see that he used thread and his own customized input/output technique.But i am not understanding why he solved this solution like this and what's the need of own customized i/o technique??
There's one thing which impressed me most is,besides his long code his code execution time is better than me.His code execution time is only '90 milliseconds' and mine is '248 milliseconds'.
Can anyone explain me the reason behind it??
Many coders actually have predefined templates for competitions. On codeforces, usually, they just copy that template into a file before even reading the problem they want to code and then code into that.
That bunch of code is actually fast input for Java. Some problems on codeforces require that. Petr must have just copied his usual template and coded that problem there, even if it wasn't necessary. The actual code Petr wrote specifically for this problem was the 3 lines function called Solve.
I saw this on a book called "算法竞赛入门经典" and the author said that this code is about 5~10 times faster than scanf.
Since I don't know java, I can't explain what this code means, but I'm sure you can understand it.
/** Class for buffered reading int and double values */
class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
/** call this method to initialize reader for InputStream */
static void init(InputStream input) {
reader = new BufferedReader(
new InputStreamReader(input) );
tokenizer = new StringTokenizer("");
}
/** get next word */
static String next() throws IOException {
while ( ! tokenizer.hasMoreTokens() ) {
//TODO add check for eof if necessary
tokenizer = new StringTokenizer(
reader.readLine() );
}
return tokenizer.nextToken();
}
static int nextInt() throws IOException {
return Integer.parseInt( next() );
}
static double nextDouble() throws IOException {
return Double.parseDouble( next() );
}
}
I am trying to use lists for my first time, I have a txt file that I am searching in it about string then I must write the result of searching in new file.
Check the image attached
My task is to retrieve the two checked lines of the input file to the output files.
And this is my code:
import java.io.*;
import java.util.Scanner;
public class TestingReport1 {
public static void main(String[] args) throws Exception {
File test = new File("E:\\test2.txt");
File Result = new File("E:\\Result.txt");
Scanner scanner = new Scanner(test);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if(line.contains("Visit Count")|| line.contains("Title")) {
System.out.println(line);
}
}
}
}
What should I do?!
Edit: How can I write the result of this code into text file?
Edit2:
Now using the following code:
public static void main(String[] args) throws Exception {
// TODO code application logic here
File test = new File("E:\\test2.txt");
FileOutputStream Result = new FileOutputStream("E:\\Result.txt");
Scanner scanner = new Scanner(test);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if(line.contains("Visit Count")|| line.contains("Title")) {
System.out.println(line);
Files.write(Paths.get("E:\\Result.txt"), line.getBytes(), StandardOpenOption.APPEND);
}
}
}
I got the result back as Visit Count:1 , and I want to get this number back as integer, Is it possible?
Have a look at Files, especially readAllLines as well as write. Filter the input between those two method calls, that's it:
// Read.
List<String> input = Files.readAllLines(Paths.get("E:\\test2.txt"));
// Filter.
String output = input.stream()
.filter(line -> line.matches("^(Title.*|Visit Count.*)"))
.collect(Collectors.joining("\n"));
// Write.
Files.write(Paths.get("E:\\Result.txt"), output.getBytes());
I have to write code that will reverse the order of the string and write it in a new file. For example :
Hi my name is Bob.
I am ten years old.
The reversed will be :
I am ten years old.
Hi my name is Bob.
This is what I have so far. Not sure what to write for the outWriter print statement. Any help will be appreciated. Thanks!
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
public class FileRewinder {
public static void main(String[] args) {
File inputFile = new File("ascii.txt");
ArrayList<String> list1 = new ArrayList<String>();
Scanner inputScanner;
try {
inputScanner = new Scanner(inputFile);
} catch (FileNotFoundException f) {
System.out.println("File not found :" + f);
return;
}
while (inputScanner.hasNextLine()) {
String curLine = inputScanner .nextLine();
System.out.println(curLine );
}
inputScanner.close();
File outputFile = new File("hi.txt");
PrintWriter outWriter = null;
try {
outWriter = new PrintWriter(outputFile);
} catch (FileNotFoundException e) {
System.out.println("File not found :" + e);
return;
}
outWriter.println(???);
outWriter.close();
}
}
My suggestion is read entire file first and store sentences(you can split by .) in a LinkedList<String>(this will keep insertion order)
Then use Iterator and get sentences in reverse order. and write them into a file. make sure to put . just after each sentence.
After System.out.println(curLine ); add list1.add(curline); that will place your lines of text into your list.
At the end create a loop over list1 backwards:
for(int i = list1.size() - 1 , i > 0, --i) {
outWriter.println(list1[i]);
}
If the file contains an amount of lines which can be loaded into the memory. You can read all lines into a list, reverse the order of the list and write the list back to the disk.
public class Reverse {
static final Charset FILE_ENCODING = StandardCharsets.UTF_8;
public static void main(String[] args) throws IOException {
List<String> inLines = Files.readAllLines(Paths.get("ascii.txt"), FILE_ENCODING);
Collections.reverse(inLines);
Files.write(Paths.get("hi.txt"), inLines, FILE_ENCODING);
}
}
I just started to code a while back and I'm in the process of dealing with arrays on my own, I understand them in theory but I need some help when it comes to getting practical. I asked my instructor to give me a couple of practices problems and he gave me the following.
using this as your main:
public static void main(String[] args) {
DatosPalabras datos = new DatosPalabras( "words.txt" );
JOptionPane.showMessageDialog(null, datos );
datos.sort();
JOptionPane.showMessageDialog(null, datos);
}
(its in spanish so bear with me) create a class named DatosPalabras and words.txt and make sure your code can:
Read and display words.txt
Display the words in "words.txt" in alphabetical order
I really appreciate the help, I'm a bit stumped but I'm curious to know how I can accomplish this. Thank you!
EDIT:
public class DatosPalabras {
public DatosPalabras(String string) {
// read and display the content of words.txt
}
public void sort() {
// need info on what to use in order to sort words instead of doubles and integers.
}
}
In this example I have 1 file named Q19505617.java. Java only allows you to have 1 public class per file. It is the class that defines the main method. So this example works only because the DatosPalabras class is contained in that file. If you need DatosPalabras to be its own class then put the DatosPalabras in its own file named DatosPalabras.java and change the class signature to be public class DatosPalabras.
import java.io.InputStream;
import java.util.Arrays;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Q19505617 {
public static void main(String[] args) {
DatosPalabras datos = new DatosPalabras("words.txt");
JOptionPane.showMessageDialog(null, datos);
datos.sort();
JOptionPane.showMessageDialog(null, datos);
}
}
class DatosPalabras {
private String[] lines;
public DatosPalabras(String filename) {
lines = new String[1];
int lineCounter = 0;
InputStream in = Q19505617.class.getResourceAsStream(filename);
Scanner scanner = new Scanner(in);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
if(lineCounter == lines.length) {
lines = Arrays.copyOf(lines, lines.length * 2);
}
lines[lineCounter] = line;
lineCounter++;
}
}
public void sort() {
// put your real sort algorithm here. until then use this:
}
public String toString() {
StringBuilder b = new StringBuilder();
for (String line : lines) {
b.append(line).append("\n");
}
return b.toString();
}
}
You can create a reading Array like this:
String[] Array = new String[number of lines in you txt file];
int i = 0;
// Selecting the txt file
File theFile = new File("bla.txt");
//Creating a scanner to read the file
scan = new Scanner(theFile);
//Reading all the words from the txt file
while (scan.hasNextLine()) {
line = scan.nextLine();
Array[i] = line; // gets all the lines
i++;
Then you create a method for sorting.