java regular expression getting values from a txt file [duplicate] - java

I am new to Java. I have one text file with below content.
`trace` -
structure(
list(
"a" = structure(c(0.748701,0.243802,0.227221,0.752231,0.261118,0.263976,1.19737,0.22047,0.222584,0.835411)),
"b" = structure(c(1.4019,0.486955,-0.127144,0.642778,0.379787,-0.105249,1.0063,0.613083,-0.165703,0.695775))
)
)
Now what I want is, I need to get "a" and "b" as two different array list.

You need to read the file line by line. It is done with a BufferedReader like this :
try {
FileInputStream fstream = new FileInputStream("input.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
int lineNumber = 0;
double [] a = null;
double [] b = null;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
lineNumber++;
if( lineNumber == 4 ){
a = getDoubleArray(strLine);
}else if( lineNumber == 5 ){
b = getDoubleArray(strLine);
}
}
// Close the input stream
in.close();
//print the contents of a
for(int i = 0; i < a.length; i++){
System.out.println("a["+i+"] = "+a[i]);
}
} catch (Exception e) {// Catch exception if any
System.err.println("Error: " + e.getMessage());
}
Assuming your "a" and"b" are on the fourth and fifth line of the file, you need to call a method when these lines are met that will return an array of double :
private static double[] getDoubleArray(String strLine) {
double[] a;
String[] split = strLine.split("[,)]"); //split the line at the ',' and ')' characters
a = new double[split.length-1];
for(int i = 0; i < a.length; i++){
a[i] = Double.parseDouble(split[i+1]); //get the double value of the String
}
return a;
}
Hope this helps. I would still highly recommend reading the Java I/O and String tutorials.

You can play with split. First find the line in the text that matches "a" (or "b"). Then do something like this:
Array[] first= line.split("("); //first[2] will contain the values
Then:
Array[] arrayList = first[2].split(",");
You will have the numbers in arrayList[]. Be carefull with the final brackets )), because they have a "," right after. But that is code depuration and it is your mission. I gave you the idea.

Related

Why does the output read "null" when I am trying to do Java Binary I/O?

I am learning how to perform Java Binary Input/Output. So before starting my full assignment, I just wanted to make sure I knew how to perform basic I/O. I can do Text I/O, but I keep having problems with Binary I/O. My code simply writes a couple things to a binary file. And then more code simply reads the binary file and prints its data.
This is the code that writes data to the binary file. Don't worry about exactly what's written to the file. I just put random things.
import java.io.*;
public class Write
{
public static void main(String[] args)
{
DataOutputStream writer = null;
try
{
writer = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("writer.dat")));
writer.writeInt(8);
writer.writeChars("Monkey ");
writer.writeChars("Bottled Water");
writer.writeChars("Truth ");
writer.writeDouble(29.99);
writer.close();
}
catch (Exception e)
{
System.out.println("Error");
}
}
}
This is the code that reads the data from the binary file.
import java.io.*;
public class Read
{
public static void main(String[] args)
{
DataInputStream reader = null;
int integ = 0;
String [] names = new String[3];
double win = 0;
try
{
reader = new DataInputStream(
new BufferedInputStream(
new FileInputStream("writer.dat")));
integ = reader.readInt();
for ( int i = 0 ; i < 3 ; i++ )
{
for ( int j = 0 ; j < 13 ; j++ )
{
names[i] += reader.readChar();
}
}
win = reader.readDouble();
reader.close();
}
catch (Exception e)
{
System.out.println("Error");
}
System.out.println(integ);
for ( int e = 0 ; e < 3 ; e++)
{
System.out.println(names[e]);
}
System.out.println(win);
}
}
This is the output I get
Can someone explain why it says null in front of the words?
You should replace the names array declaration :
String [] names = new String[3];
with
String [] names = {"","",""};
or
String [] names = new String[3];
names[0] = "";
names[1] = "";
names[2] = "";
You have null at the beginning of the words because the individual values of the array names are null (you didn't initialize them).
So in your loop when i=0, j=0, the instruction names[i] += reader.readChar(); will be equivalent to :
names[0] += reader.readChar();
which is equivalent to :
names[0] = names[0] + reader.readChar();
but because the names array values are not initialized, names[0] is equal to null.
So the previous expression is equivalent :
names[0] = null + reader.readChar();
So names[0] is now equal to nullM in the first iteration of the loop and will be nullMonkey at the end.

Filling a double[][] from the CSV file

I have this CSV file:
World Development Indicators
Number of countries,4
Country Name,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014
Bangladesh,6.28776238,13.20573922,23.46762823,30.16828408,34.35334451,44.94535882,55.19256723,62.82023906,74.42964608,80.03535051
"Bahamas, The",69.21279415,75.37855087,109.340767,102.7875065,101.2186453,118.8292307,81.5628489,80.65383375,76.05187427,82.29635806
Brazil,46.31418452,53.11025849,63.67475185,78.5549801,87.54187651,100.8810115,119.0023853,125.0018521,135.3050481,138.9514906
Germany,94.55486999,102.2828888,115.1403608,126.5575074,126.2280577,106.4836959,109.6595675,111.5940398,120.9211651,120.4201855
I am trying to store countries' data(double once) into a matrix(double[][]). Here is the code that I have so far:
public double[][] getParsedTable() throws IOException {
double[][] table = new double[4][10];
String row;
int indexRow = 0;
int indexColumn = 0;
BufferedReader br = new BufferedReader(new FileReader(fileName));
br.readLine();
br.readLine();
String line = br.readLine();
while(line != null && !line.isEmpty()){
line = br.readLine();
String[] array = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
for(int i = 1; i < array.length; i++){
table[indexRow][indexColumn] = Double.parseDouble(array[i]);
indexColumn++;
}
indexColumn = 0;
indexRow++;
}
System.out.print(Arrays.deepToString(table));
return table;
}
I am getting an arror : NullPointerException at:
String[] array = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
I cant figure out why. I tried different combinations. nothing seems to work. It seems to pick up the numbers from the CSV file and store them, but when I call:
System.out.print(Arrays.deepToString(table));
it does not print out anything, hence I cant check if its stored properly or not. Could you tell me: 1. Why I am getting an error. 2. Why System.out.println does not print out an array. Thanks
If we assume that name of a country will not contain a digit and country name and numbers will be only comma separated, then following can be done without regex. I have changed file reading a little bit because it can run into issues.
public double[][] getParsedTable() throws IOException {
double[][] table = new double[4][10];
int indexRow = 0;
int indexColumn = 0;
BufferedReader br = new BufferedReader(new FileReader(fileName));
br.readLine(); // ignore first line
br.readLine(); // ignore second line
br.readLine(); // ignore third line (contains title)
String line;
while (true) {
line = br.readLine();
if (line == null) break; // end of file reading
int index = 0;
while (true) {
index = line.indexOf(",", index) + 1;
if (Character.isDigit(line.charAt(index))) {
break;
}
}
// from index, line is expected to contain comma separated numbers
String[] array = line.substring(index).split(",");
for (int i = 0; i < array.length; i++) {
table[indexRow][indexColumn] = Double.parseDouble(array[i]);
indexColumn++;
}
indexColumn = 0;
indexRow++;
}
System.out.print(Arrays.deepToString(table));
return table;
}
In the csv, first 3 lines are not real country's data. So read in line-4 before while loop starts.
In while loop, first finish the processing of line string first. Eg: regular expression check & assign split data into table.
Then only read in next line at end of while loop, to be processed in next iteration.
Feel free to try this out:
public double[][] getParsedTable() throws IOException {
double[][] table = new double[4][10];
int indexRow = 0;
int indexColumn = 0;
// check whether you need to handle any exception for this
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = null;
try {
// line 1-3 are not real country's data
br.readLine();
br.readLine();
br.readLine();
// first country data begin at line 4
line = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
while (line != null && !line.isEmpty()) {
String[] array = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
for (int i = 1; i < array.length; i++) {
table[indexRow][indexColumn] = Double.parseDouble(array[i]);
indexColumn++;
}
indexColumn = 0;
indexRow++;
// read next line only at end of loop, not beginning of loop
// line is ready to be processed at next iteration
try {
line = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.print(Arrays.deepToString(table));
return table;
}
Arrays.deepToString is wrong. You are passing in an array of primitives. When you pass it in, you pass in double[][]. This is interpeted as Object[] where the objects are double[], so it will try to print double[] objects, and not print doubles.
One solution is to create an array Double[][].
Change
double[][] table = new double[4][10];
to
Double[][] table = new Double[4][10];
Autoboxing will convert each double to a Double. Since Double is an object and not a primitive, deepToString will print out each Double individually. If you read the javadoc for deepToString it explains that it operates recursively on arrays of reference type, not on primitive arrays.
If you want to stick with double[][]
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
System.out.print(table[i][j]);
System.out.print(' ');
}
System.out.println();
}

Reading a text file into a 2D array

I need to read a text file into a 2D array, I can read files into the program perfectly fine (see my code below) however I cannot get my head around how to read them into a 2D array. The array the function is reading into is a global array hence why it's not in the function.
Also I won't know the amount of rows the array has at first (currently set at 300 as it won't be over this) and I know this could cause a problem, I've seen some people suggest using ArrayLists however I have to have a 2D array so I was also wondering if there was a way to change an ArrayList to a 2D array and if this would be more effective?
public static String readMaze(String fileName) {
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
for (int i = 0; i < mazeNew.length; i++) {
for (int j = 0; j < mazeNew[i].length; j++) {
// mazeNew[i][j] = ; - this is where I think something needs to be added
}
}
}
bufferedReader.close();
}
catch (FileNotFoundException ex) {
System.out.println("Unable to open file: " + fileName);
}
catch (IOException ex) {
System.out.println("Error reading file: " + fileName);
}
return fileName;
}
example text file:
11 4
5 6
4 6
0 5
3 5
8 7
1 4
There's a few options here, but generally you'll want to use the Java Scanner class as it's designed for exactly this kind of thing. Alternatively, use an existing structured data format (like JSON or XML) and an existing parser to go with it - the advantage being you can make use of a vast amount of tools and libraries which deal with those formats and don't have to re-invent anything.
However, following through with the scanner approach, it would be like so:
public static ArrayList<int[]> readMaze(String fileName) {
// Number of ints per line:
int width=2;
// This will be the output - a list of rows, each with 'width' entries:
ArrayList<int[]> results=new ArrayList<int[]>();
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
Scanner mazeRunner = new Scanner(bufferedReader);
// While we've got another line..
while (mazeRunner.hasNextLine()) {
// Setup current row:
int[] row = new int[width];
// For each number..
for (int i = 0; i < width; i++) {
// Read the number and add it to the current row:
row[i] = mazeRunner.nextInt();
}
// Add the row to the results:
results.add(row);
// Go to the next line (optional, but helps deal with erroneous input files):
if ( mazeRunner.hasNextLine() ) {
// Go to the next line:
mazeRunner.nextLine();
}
}
mazeRunner.close();
}
catch (FileNotFoundException ex) {
System.out.println("Unable to open file: " + fileName);
}
catch (IOException ex) {
System.out.println("Error reading file: " + fileName);
}
return results;
}
If you have fixed no. of columns you can use this, but make sure input file must follow the same no of coulmns.
FileReader fileReader = new FileReader(fileName);
Scanner sc = new Scanner(fileReader);
int row=0, col=0;
while ((sc.hasNext()) != null) {
if(col < colSize){ //colSize is size of column
mazeNew[row][col]= sc.nextInt();
}
else{
col=0;
row++;
}
}
Below is the core logic, you would probably also like to to handle some errors, such as how many elements is a line split into, are there empty lines, etc.
List<String[]> list = new ArrayList<>();
Pattern pattern = Pattern.compile("\\s+");
while ((line = bufferedReader.readLine()) != null) {
list.add(pattern.split(line, -1));
}
String[][] mazeNew = list.toArray(new String[0][0]);
Something like this would work
it wont only read 2d text files .. it should work fine with any dimensions
public class Utile{
public static ArrayList<int[]> readMaze(String path){
ArrayList<int[]> result = new ArrayList<>();
try{
Scanner sc = new Scanner(new File(path));
String[] temp;
String line;
while(sc.hasNextLine()){
line = sc.nextLine();
if (line.length() != 0){ //if the line is empty it will cause NumberFormatException
temp = line.split(" ");
int[] val = new int[temp.length];
for(int i = 0;i < temp.length;i++){
val[i] = Integer.pareseInt(temp[i]);
}
result.add(val);
}
}
sc.close();
}catch(Exception e){
e.printStackTrace(); //just log it for now
}
return result;
}
}
I am not a java expert, but in PHP I would do it with explode(). But I found an example how to do the same in java using string.split(). The result is the same ... an 2D Array of the content. If possible you should try to add an delimiter to the rows inside that text document. But you could split the rows on the space character either.
Example:
String foo = "This,that,other";
String[] split = foo.split(",");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < split.length; i++) {
sb.append(split[i]);
if (i != split.length - 1) {
sb.append(" ");
}
}
String joined = sb.toString();

Java replace characters in a TextFile - Alice In Wonderland

I'm trying to make a compressor for TextFiles and I get stuck at replacing characters.
This is my code:
compress.setOnAction(event ->
{
String line;
try(BufferedReader reader = new BufferedReader(new FileReader(newFile)))
{
while ((line = reader.readLine()) != null)
{
int length = line.length();
String newLine = "";
for (int i = 1; i < length; i++)
{
int c = line.charAt(i);
if (c == line.charAt(i - 1))
{
}
}
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
});
So what I want to do is: I want to find all the words where two characters are equal, if they are aside (Like 'Took'). When the if statement is true, I want to replace the first letter of the two equals characters, so it would look like: 'T2ok'.
I've tried a lot of things and I get an ArrayOutOfbounds, StringOutOfbounds, and so on, all the time...
Hope someone has a great answer :-)
Regards
Create a method that compress one String as follows:
Loop throu every character using a while loop. Count the duplicates in another nested while loop that increments the current index while duplicates are found and skips them from being written to output. Additionally this counts their occurence.
public String compress(String input){
int length = input.length(); // length of input
int ix = 0; // actual index in input
char c; // actual read character
int ccounter; // occurrence counter of actual character
StringBuilder output = // the output
new StringBuilder(length);
// loop over every character in input
while(ix < length){
// read character at actual index then inc index
c = input.charAt(ix++);
// we count one occurrence of this character here
ccounter = 1;
// while not reached end of line and next character
// is the same as previously read
while(ix < length && input.charAt(ix) == c){
// inc index means skip this character
ix++;
// and inc character occurence counter
ccounter++;
}
// if more than one character occurence is counted
if(ccounter > 1){
// print the character count
output.append(ccounter);
}
// print the actual character
output.append(c);
}
// return the full compressed output
return output.toString();
}
Now you can use this method to create a file input to output stream using java8 techniques.
// create input stream that reads line by line, create output writer
try (Stream<String> input = Files.lines(Paths.get("input.txt"));
PrintWriter output = new PrintWriter("output.txt", "UTF-8")){
// compress each input stream line, and print to output
input.map(s -> compress(s)).forEachOrdered(output::println);
} catch (IOException e) {
e.printStackTrace();
}
If you really want to. You can remove the input file and rename the output file afterwards with
Files.move(Paths.get("output.txt"), Paths.get("input.txt"),StandardCopyOption.REPLACE_EXISTING);
I think this is the most efficient way to do what you want.
try this:
StringBuilder sb = new StringBuilder();
String line;
try(BufferedReader reader = new BufferedReader(new FileReader(newFile)))
{
while ((line = reader.readLine()) != null)
{
if (!line.isEmpty()) {
//clear states
boolean matchedPreviously = false;
char last = line.charAt(0);
sb.setLength(0);
sb.append(last);
for (int i = 1; i < line.length(); i++) {
char c = line.charAt(i);
if (!matchedPreviously && c == last) {
sb.setLength(sb.length()-1);
sb.append(2);
matchedPreviously = true;
} else matchedPreviously = false;
sb.append(last = c);
}
System.out.println(sb.toString());
}
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
This solution uses only a single loop, but can only find occurrences of length 2

How to count the number of characters in a line in a csv file

I have a Justice_League.csv file that has four lines with commas between them. I want to count the number of characters there are in each line and convert that number to hex.
Below is the contents of Justice_League.csv:
Bruce Wayne,Batman,None,Gotham City,Robin,The Joker 43 2B
Oliver Queen,Green Arrow,None,Star City,Speedy,Deathstroke 50 32
Clark Kent,Superman,Flight,Metropolis,None,Lex Luthor 46 2E
Bart Allen,The Flash,Speed,Central City,Kid Flash,Professor Zoom 52 34
As you can see I have handcounted the characters and wrote the HEX value next to it. Now I need this done in Java. This is what I have so far. Can anybody help me out?
public String convertCSVToFlat (Exchange exchange) throws Exception {
String csv="Justice_League.csv";
BufferedReader bReader = new BufferedReader(new FileReader(csv));
String line = "";
int count = 0;
String str[] = new String[200];
int[] a = new int[24];
String[] hexNumber = new String[4];
try {
bReader.readLine();
int characterSum = 0;
int i = 0;
while((line = bReader.readLine()) != null) {
String[] f=line.split(",");
a[count]=Integer.parseInt(f[2]);
str[count]=f[1];
count++;
characterSum += line.length();
hexNumber[i] = Integer.toHexString(characterSum);
i++;
}
} catch (IOException e) {
e.printStackTrace();
}
bReader.close();
return hexNumber.toString();
I suggest you to read the javadoc of String.split. I think that you misunderstood the concept when you did this:
String[] f=line.split(",");
a[count]=Integer.parseInt(f[2]); //--> java.lang.NumberFormatException here!
Avoid using 'magic' numbers in your code like int[] a = new int[24];. Why 24?
Well, here comes a version that do what you want to do. Maybe it isn't the best way to do this but it works.
public void convertCSVToFlat () throws Exception {
String csv="Justice_League.csv";
BufferedReader bReader = new BufferedReader(new FileReader(csv));
//We're storing the values at this 3 arraylists,
//but a better approach is using an object to hold'em
ArrayList<String> lines = new ArrayList<String>();
ArrayList<Integer> chars = new ArrayList<Integer>();
ArrayList<String> hex = new ArrayList<String>();
String line = "";
try {
while((line = bReader.readLine()) != null) {
lines.add(line);
//I'm assuming that you don't want to count the commas and spaces.
//If you want to, comment the next line
line = line.replaceAll(",", "").replaceAll(" ", "");
int c = line.length(); //count remaining chars...
chars.add(c);
hex.add(Integer.toHexString(c));
}
} catch (IOException e) {
e.printStackTrace();
}
bReader.close();
//Just to show the results
for (int i = 0; i < lines.size(); i++) {
System.out.print(lines.get(i));
System.out.print("\t" + chars.get(i));
System.out.println("\t" + hex.get(i));
}
}
Like I said previously, this is a way to solve this. You should try another options to solve this in order to improve your knowledge...

Categories

Resources