problems with parsing a text file in Java - java

I have looked at all the links and cannot seem to get what I am looking for. I have a text file I need to read in. First the text file format:
3 STL NY Chi //all on one line
STL NY 575 //on its own line
NY Chi 550 //on its own line
STL Chi 225 //on its own line
I need to read the int into an int variable, say we call it count. Then the actual cities on that same line into an array. The next lines need to read into an array to where the mileage is associated with the array, such as [STL NY]=575. I can only use arrays. No hash tables, list, stacks or queues. Here is what I got so far and honestly it isn't much. I could really use some help for I am pretty stumped on the "howto" on this.
import java.io.*;
import java.util.*;
public class P3 {
/**
* #param args the command line arguments
*/
public static int count;
public static void main(String[] args) {
try {
FileInputStream dataFile = new FileInputStream("Data.txt");
//BufferedReader br = new BufferedReader(new InputStreamReader(dataFile));
String line = br.readLine();
}
catch (IOException e) {
System.err.println ("Unable to open file");
System.exit(-1);
}
}
}
I think I'm getting there, but I am getting an error code of: "non-static variable cities cannot be referenced from a static context." I am trying to test my code by printing. Can anyone help me with this printing? I would like to see what is in the arrays to make sure I did it correctly. Here is my code:
package p3;
import java.io.*;
import java.util.*;
class citiesDist {
String cityOne;
String cityTwo;
int miles;
}
class city {
String cityName;
int numberLinks;
citiesDist[] citiesDists;
}
public class P3 {
city[] cities;
void initCity(int len) {
for (int i = 0; i < len; i++) {
cities[i] = new city();
}
}
void initCitiesDist (int index, int len) {
for (int i = 0; i < len; i++) {
cities[index].citiesDists[i] = new citiesDist();
}
}
void parseFile() throws FileNotFoundException, IOException {
FileInputStream fstream = new FileInputStream("Data.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
int numberCities = Integer.parseInt(br.readLine());
cities = new city[numberCities];
initCity(numberCities);
for (int i = 0; i < numberCities; i++) {
String line = br.readLine();
int numberLink = Integer.parseInt(line.split(" ")[1]);
cities[i].cityName = line.split(" ")[0];
cities[i].numberLinks = numberLink;
initCitiesDist (i, numberLink);
for (int j = 0; j < numberLink; j++){
line = br.readLine();
cities[i].citiesDists[j].cityOne = line.split(" ")[0];
cities[i].citiesDists[j].cityTwo = line.split(" ")[1];
cities[i].citiesDists[j].miles = Integer.parseInt(line.split(" ")[2]);
}
}
}
public static void main(String args[]) {
System.out.println("city" + cities.city);
}
}

If you're ever stumped on code, don't think about the programming language; it only serves to further muddle your logic. (Separate the algorithm from the language.) When you have a clear idea of what you want to accomplish, add your language in (insofar as, "how do I accomplish this particular task?").
Ultimate Goal
From your design, your goal is to have a graph relating the distances between each city. It would appear something like this:
[STL][NY] [Chi]
[STL][0] [575][25]
[NY] [575][0] [550]
[Chi][25] [550][0]
This isn't too terribly difficult to accomplish, in terms of the file input and the Scanner class.
First Steps
You have to extract the dimensions of your graph (which is a 3 by 3). This is provided for you in the first line of your input file. Getting an integer from a Scanner with a File in it isn't too difficult, just make sure you have the proper classes imported, as well as the proper error handling (either try...catch or throwing the exception).
Scanner sc = new Scanner(new File("input.txt"));
You'll need two arrays - one for the cities, and one for the distances themselves. We don't know how large they are (you never assume the data in a file, you just assume the form of the data), so we have to get that from the file itself. Luckily, we are given an integer followed by the cities themselves. We will read this integer once and use it in multiple different locations.
String[] cities = new String[sc.nextInt()];
int[][] distances = new int[cities.length][cities.length];
for(int i = 0; i < cities.length; i++) {
// Surely there's a method in Scanner that returns String that reads the _next_ token...
}
The Exercise to the Reader
You now have your data structure set up and ready to go. What you would need to do from here is bridge the gap between the cities array and distances array. Consider the order in which they arrived in the file, and the order in which we're encountering them. You would be well-served with some methodology or way to answer the question, 'Which came first - STL or NY?'
Give it a whirl and see if you can get further.

Related

How to send a Java string to R? (rJava)

I am writing a game that revolves around guessing what words in other languages mean. For example, guessing what "hola" means in English. For this game, I am creating a scoring system that uses the frequency of the word (from Google N Gram) being guessed to assign points. Basically, less times showing up = more points. However, when trying to send over the Java String that holds the word to R, I came to the realization that I have no idea what to do.
So far I have experimented with rJava to send over the word, but I am having difficulty making it work. I would greatly appreciate if someone who has experience with R could help me with my problem.
Java Class that generates word:
import java.util.Scanner;
import java.util.Random;
import java.io.File;
import java.io.IOException;
//this program gathers the words to be translated
//for game 1
public class dictionary {
private String line;
public dictionary() {
this.line = "";
}
public dictionary (String line) {
//getting word
try {
this.line = line;
Random random = new Random();
Scanner in = new Scanner (System.in);
int count = 0;
int rand = 1 + random.nextInt(8110);
//read file name from standard input
File file = new File("words.txt");
//overwrite scanner to read file
in = new Scanner(file);
while (in.hasNextLine() && count != rand) {
this.line = in.nextLine();
count = count + 1;
}
in.close();
}
catch(IOException e) {
System.out.println("File does not exist.");
}
}
public String getLine() {
return this.line;
}
}
R code that I came up with. Goal is to ingest the word from Java word (line):
library("ngramr")
library("rJava")
.jinit(parameters = getOption("java.parameters")
.jcall("java/lang/String", returnSig = "S", method = "getLine", evalString = TRUE)
word <- .jclassString("string", "line")
ngram(word, year_start = 1800, smoothing = 0)
Bonus:
Also, if anyone is familiar with Google Ngram and knows how to record the amount of instances of a word in R and send it to Java, please let me know as it is a crucial part of the scoring system.
It’s been a few weeks since I originally posted this question. Since then I have found a solution to both problems listed by using Python sockets instead of R. If anyone is interested in how I did that, it’s in my GitHub. I am going to leave this question here however, in the hopes someone will answer it for others with a similar problem.

Java read integer arrays from multiple files

I'm relatively new to Java, so I have to look up how to do things constantly. I'm working on a project that involves analyzing a number of familiar sorts such as heap sort, merge sort, etc. I wrote a bit of code to produce a variety of different arrays, each in their own .txt file. Here is a portion of the code:
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
public class ArrayBuilder {
public static void main(String[] args) throws IOException {
for(int i = 2; i < 7; i++) {
int aLength = (int)Math.pow(10, i);
buildAscendingArray(aLength);
buildDescendingArray(aLength);
buildRandomArray(aLength);
}
}
public static void buildAscendingArray(int arrayLength) throws IOException {
File file = new File("arrays_" + arrayLength + "A.txt");
PrintWriter printWriter = new PrintWriter(file);
int[] array = new int[arrayLength];
for(int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
printWriter.println(Arrays.toString(array));
printWriter.close();
}
I didn't include the random and descending methods as they are more or less the same so trying to save room. So...
I already have all the sorts coded, I'm just trying to figure out how to read in the integer arrays so I can run them through the different sorts. I'm also trying to factor adding in System.nanoTime() to clock the time it takes to run each sort so I can compare them given the various inputs. Not sure if this needs to be added into the method for each sort or whether it can be implemented in the call ie. System.nanoTime(heapsort(array))) ?
Ultimately I'm looking for some help on getting the .txt files into a usable array in order to pass it through each sort. I output all to text files in the first place to make sure the exact same array is run through each sort.
I'm somewhat familiar with Scanner, but have also read about FileRead and/or BufferedReader and possibly some other approaches. I'm just not experienced enough to know what would work best in this situation and the best way to implement it. Help would be much appreciated.
If you just need to save arrays to file storage and construct them back you can use serialization.
This class is just to give you an idea of how it would work.
public class ArrayReaderWriter {
public static void main(String[] args) throws Exception {
writeArray(20);
readArray(20);
}
public static void writeArray(int arrayLength) throws IOException {
File file = new File("arrays_" + arrayLength + "A.ser");
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file));
int[] array = new int[arrayLength];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
os.writeObject(array);
}
public static void readArray(int arrayLength) throws IOException, ClassNotFoundException {
File file = new File("arrays_" + arrayLength + "A.ser");
ObjectInputStream is = new ObjectInputStream(new FileInputStream(file));
int[] array = (int[]) is.readObject();
// Printing here to verify
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
Note: I can understand saving the random array if you want to run the different sorts with the same array in different executions. But the ascending and descending arrays can always be constructed on every execution.
Regarding System.nanoTime()
See https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#nanoTime-- for a detailed explanation.
EDIT
If you have already generated the text files use #Antoniossss solution. You will only need to modify the delimiter as I mentioned in my comment since you are reading existing files.
Test
Scanner scanner = new Scanner("[1, 2, 3]");
scanner.useDelimiter("(\\s)*[\\[,\\]](\\s)*");
while(scanner.hasNextInt()) {
System.out.println(scanner.nextInt());
}
Output
1
2
3
Use some delimetered file format for such purposes and read it using scanner.
Lets say our delimeter is character is ;. Store your array like this
File file = new File("arrays_" + arrayLength + "A.txt");
PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter(file)));
printWriter.print(1);
for(int i = 1; i < array.length; i++) {
printWriter.print(';'); // delimeter
printWriter.print(i+1);
}
printWriter.close();
To read it back, use Scanner in simillar way to the following code;
ArrayList<Integer> arr=new ArrayList<>();
Scanner scan=new Scanener(new File("yourfile));
scan.useDelimeter(';');
while(scan.hasNextInt()){
arr.add(scan.nextInt());
}
Should work just fine. You can always use a newline as a delimeter as well.
EDIT: If you dont need to have array storred in human readable form, you can use serialization just like #Shire Resident explained in his answer.

Java: Read a text file into an array

I've a txt file composed by two columns like this:
Name1 _ Opt1
Name2 _ Opt2
Name3 _ Opt3
In each row there's a name, a tab delimiter, a _ and then another name; there are really many rows (about 150000) and i'm not even sure which one is the best constructor to use, i'm thinking about a two dimensional array but it could be also something else if it's a better choice. For me it's important that i can access to the elements with something like this a[x][y].
I've done this but i just know how to count the number of the lines or how to put each lines in a different position of an array.
Here's the code:
int countLine = 0;
BufferedReader reader = new BufferedReader(new FileReader(filename));
while (true) {
String line = reader.readLine();
if (line == null) {
reader.close();
break;
} else {
countLine++;
}
}
Since you don't know the number of lines ahead of time, I would use an ArrayList instead of an array. The splitting of lines into String values can easily be done with a regular expression.
Pattern pattern = Pattern.compile("(.*)\t_\t(.*)");
List<String[]> list = new ArrayList<>();
int countLine = 0;
BufferedReader reader = new BufferedReader(new FileReader(filename));
while (true) {
String line = reader.readLine();
if (line == null) {
reader.close();
break;
} else {
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
list.add(new String[] { matcher.group(1), matcher.group(2) });
}
countLine++;
}
The first thing you should do is to write a class that represents an entry in your file. It could be quite sophisticated but a really simple design will probably also do.
class Record {
final String name;
final String option;
Record(final String name, final String option) {
this.name = name;
this.option = option;
}
}
Using this class is much better than messing with arrays of strings.
The second thing to do is to use a more abstract data structure than an array structure to put your records into. This will free you from the burden of having to know the number of elements in advance. I recommend that you use an ArrayList for this. Then, you can read in one record at a time and add it to your collection.
List<Record> records = new ArrayList<Record>();
records.add(new Record("NameX", "OptionX"));
System.out.printf("There are %d records in the list.%n", records.size());
Of course, the second line in the above example should be done over and over again in your loop that reads the lines of the file.
Use ArrayList instead of array because the size is unknown. Use Scanner to read file, and to check existence of next line in file use hasNextLine() method,
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
class Test {
static Scanner userInput = new Scanner(System.in);
public static void main(String args[]) throws FileNotFoundException {
int countline = 0;
Scanner inp=new Scanner(new File("/home/nasir/Desktop/abc.txt"));
ArrayList<String> list=new ArrayList<String>();
while(inp.hasNextLine()){
list.add(inp.nextLine());// adding a row in ArrayList
countline++;// counting every line/row
}
System.out.println(countline+" "+list.get(2));
}// Main
}// Class
You can save the data on
HashMap>
The first String (key) is your name
The second String (key) is your opt and his value (reault) is the object result.
You can use it as:
result = youHashMap.get(name).get(opt);

find common words in multiple text files

I have 100 text files. 50 of them are called text_H and the other are called text_T. What I would like to do is the following open two text files text_T_1 and text_H_1 and find the number of common words and write it to a text file then open text_H_2 and text_T_2 and find the number of common words....then open text_H_50 and text_T_50 and find the number of common words.
I have written the following code that open two text files and find common words and return the the number of common words between the the two files. The results are written in text file
For whatever reason instead of giving me the number of common word for just the open text files, it gave me the number of of common words for all files. For the example if the number of common words between fileA_1 and fileB_1 is 10 and the number of common words between fileA_2 and fileB_2 is 5, then result I get for number of common word for the second two files is 10+5=15.
I'm hoping someone here can catch whatever it is that I'm missing, because I've been through this code many times now without success. Thanks ahead of time for any help!
The code:
package xml_test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class app {
private static ArrayList<String> load(String f1) throws FileNotFoundException
{
Scanner reader = new Scanner(new File(f1));
ArrayList<String> out = new ArrayList<String>();
while (reader.hasNext())
{
String temp = reader.nextLine();
String[] sts = temp.split(" ");
for (int i = 0;i<sts.length;i++)
{
if(sts[i] != "" && sts[i] != " " && sts[i] != "\n")
out.add(sts[i]);
}
}
return out;
}
private static void write(ArrayList<String> out, String fname) throws IOException
{
FileWriter writer = new FileWriter(new File(fname));
//int count=0;
int temp1=0;
for (int ss= 1;ss<=3;ss++)
{
int count=0;
for (int i = 0;i<out.size();i++)
{
//writer.write(out.get(i) + "\n");
//writer.write(new Integer(count).toString());
count++;
}
writer.write("count ="+new Integer(temp1).toString()+"\n");
}
writer.close();
}
public static void main(String[] args) throws IOException
{
ArrayList<String> file1;
ArrayList<String> file2;
ArrayList<String> out = new ArrayList<String>();
//add for loop to loop through all T's and H's
for(int kk = 1;kk<=3;kk++)
{
int count=0;
file1 = load("Training_H_"+kk+".txt");
file2 = load("Training_T_"+kk+".txt");
//int count=1;
for(int i = 0;i<file1.size();i++)
{
String word1 = file1.get(i);
count=0;
//System.out.println(word1);
for (int z = 0; z <file2.size(); z++)
{
//if (file1.get(i).equalsIgnoreCase(file2.get(i)))
if (word1.equalsIgnoreCase(file2.get(z)))
{
boolean already = false;
for (int q = 0;q<out.size();q++)
{
if (out.get(q).equalsIgnoreCase(file1.get(i)))
{
count++;
//System.out.println("count is "+count);
already = true;
}
}
if (already==false)
{
out.add(file1.get(i));
}
}
}
//write(out,"output_"+kk+".txt");
}
//count=new Integer(count).toString();
//write(out,"output_"+kk+".txt");
//write(new Integer(count).toString(),"output_2.txt");
//System.out.println("count is "+count);
}//
}
}
Let me show you what your code is doing and see if you can spot the problem.
List wordsInFile1 = getWordsFromFile();
List wordsInFile2 = getWordsFromFile();
List foundWords = empty;
//Does below for each compared file
for each word in file 1
set count to 0
compare to each word in file 2
if the word matches see if it's also in foundWords
if it is in foundWords, add 1 to count
otherwise, add the word to foundWords
//Write the number of words
prints out the number of words in foundWords
Hint: The issue is with foundWords and where you are adding to count. arunmoezhi's comment is on the right track, as well as board_reader's point #3 in his answer.
As it stands now, your code is doing nothing meaningful with any of the count variables
use more meaningful variable names in loops, makes code readable.
use HashMap-s instead of ArrayList-s, will make code smaller, faster and a lot easier. will use less memory too in case words are repeated several times in files.
should not you increase count in already==false case?
could not figure out point of calculating count 3 times in write method, is not count equal to out.size()?
probably there are more too...

Reading two lines from an input file using Scanner

Hi I'm in a programming class over the summer and am required to create a program that reads input from a file. The input file includes DNA sequences ATCGAGG etc and the first line in the file states how many pairs of sequences need to be compared. The rest are pairs of sequences. In class we use the Scanner method to input lines from a file, (I read about bufferedReader but we have not covered it in class so not to familiar with it) but am lost on how to write the code on how to compare two lines from the Scanner method simultaneously.
My attempt:
public static void main (String [] args) throws IOException
{
File inFile = new File ("dna.txt");
Scanner sc = new Scanner (inFile);
while (sc.hasNextLine())
{
int pairs = sc.nextLine();
String DNA1 = sc.nextLine();
String DNA2 = sc.nextLine();
comparison(DNA1,DNA2);
}
sc.close();
}
Where the comparison method would take a pair of sequences and output if they had common any common characters. Also how would I proceed to input the next pair, any insight would be helpful.. Just stumped and google confused me even further. Thanks!
EDIT:
Here's the sample input
7
atgcatgcatgc
AtgcgAtgc
GGcaAtt
ggcaatt
GcT
gatt
aaaaaGTCAcccctccccc
GTCAaaaaccccgccccc
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
gctagtacACCT
gctattacGcct
First why you are doing:
while (sc.hasNextLine())
{
int pairs = sc.nextLine();
While you have pairs only in one line not pairs and two lines of input, but number of lines once? Move reading pairs from that while looop and parse it to int, then it does not matter but you could use it to stop reading lines if you know how many lines are there.
Second:
throws IOException
Might be irrelevant but, really you don't know how to do try catch and let's say skip if you do not care about exceptions?
Comparision, if you read strings then string has method "equals" with which you can compare two strings.
Google will not help you with those problems, you just don't know it all, but if you want to know then search for basic stuff like type in google "string comparision java" and do not think that you can find solution typing "Reading two lines from an input file using Scanner" into google, you have to go step by step and cut problem into smaller pieces, that is the way software devs are doing it.
Ok I have progz that somehow wokrked for me, just finds the lines that have something and then prints them out even if I have part, so it is brute force which is ok for such thing:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class program
{
public static void main (String [] args) throws IOException
{
File inFile = new File ("c:\\dna.txt");
Scanner sc = new Scanner (inFile);
int pairs = Integer.parseInt(sc.nextLine());
for (int i = 0; i< pairs-1; i++)
{
//ok we have 7 pairs so we do not compare everything that is one under another
String DNA1 = sc.nextLine();
String DNA2 = sc.nextLine();
Boolean compareResult = comparison(DNA1,DNA2);
if (compareResult){
System.out.println("found the match in:" + DNA1 + " and " + DNA2) ;
}
}
sc.close();
}
public static Boolean comparison(String dna1, String dna2){
Boolean contains = false;
for (int i = 0; i< dna1.length(); i++)
{
if (dna2.contains(dna1.subSequence(0, i)))
{
contains = true;
break;
}
if (dna2.contains(dna1.subSequence(dna1.length()-i,dna1.length()-1 )))
{
contains = true;
break;
}
}
return contains;
}
}

Categories