Parse lines with different number of string words [duplicate] - java

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 1 year ago.
I have a text file with the following format(the words at each line are seperated with tab):
stri1 stri2 stri3
stri4 stri5 stri6
stri7 stri8
stri9 stri0 stri5
As you can see i have some lines with only two words. I have a class to save the words of each line:
public class Entity{
private word1,word2,word3;
//constructor and getter/setter methods
}
I want to save the text values using the following code:
for(String i : filelines){
String[] line = i.split("\t");
if(line[2] == null){
listOfEntities.add(new Entity(line[0], line[1], null));
}
else{
listOfEntities.add(new Entity(line[0], line[1], line[2]));
}
When i try to execute this code i get an ArrayIndexOutOfBoundsException because some line have only 2 words. How can i handle this situation because i want also the null values in order to make some sql queries later.

Mod with length of array will return 0 if array exceed legth it will store zeroth index other than that you have to do multiple ifs as you have done for second index.
Another way I would suggest pass the whole array in Entity parameter and in Entity class run a for loop till array length which will run till available lines in array only.
for(String i : filelines){
String[] line = i.split("\t");
if(line[2 % line.length] == null){
listOfEntities.add(new Entity(line[0], line[1 % line.length], null));
}
else{
listOfEntities.add(new Entity(line[0], line[1 % line.length], line[2 % line.length]));
}

I have another option for you. You have to separate the options in the file with an element. This looks like this:
stri1-stri2-stri3
stri4-stri5-stri6
stri7-stri8
stri9-stri0-stri5
For this you have to change your entity class a little bit:
public static class Entity {
private String[] words;
public Entity(String[] words) {
this.words = words;
}
public String[] getWords() {
return words;
}
}
To read out the whole thing now, I wrote you a code.
List<Entity> array = new ArrayList<>();
Scanner scanner = new Scanner(new File("MyFile.txt"));
while (scanner.hasNext()) {
String line = scanner.next();
String[] options = line.split("-");
array.add(new Entity(options));
}
array.forEach(entity -> {
System.out.println("Entity Words > " + Arrays.toString(entity.getWords()));
});
I hope I could help you with this.

Related

How to allow empty strings in String.split()? [duplicate]

This question already has answers here:
Java String split removed empty values
(5 answers)
Closed 7 years ago.
I am using String.split() to split a string. The string I receive has this structure:
[data]<US>[data]<US>
where <US> is the ASCII unit separator (code 0x1F). The code to split is
String[] fields = someString.split(String.valueOf(0x1f));
This works fine, unless [DATA] is an empty string. In that case, data just gets skipped.
I want a string like [DATA]<US><US>[DATA]<US> to return an array with three elements: [DATA], null and [DATA].
How can I do that?
If you parametrize your split with -1 as a second argument, you'll get an empty String where [data] is missing (but not null).
someString.split(String.valueOf(0x1f), -1);
Explanation from the docs
If n is non-positive then the pattern will be applied as many times as possible and the array can have any length.
.. where n is the limit, i.e. the second argument.
You could simply loop through the array afterwards and assign empty strings as null:
public class StringSplitting {
public static void main(String[] args){
String inputs = "[data]<US><US>[data]<US>";
String[] fields = inputs.split("<US>");
//set empty values to null
for(int i = 0; i < fields.length; i++){
if(fields[i].length() == 0){
fields[i] = null;
}
}
//print output
for(String e: fields){
if(e == null){
System.out.println("null");
}else{
System.out.println(e);
}
}
}
}
This is a working code
String s="[DATA]<US><US>[DATA]<US>";
String arr []= s.split("<US>");
for(String str :arr) {
if(str.equals("")) {
System.out.println("null");
} else {
System.out.println(str);
}
}
Output::
[DATA]
null
[DATA]
To be more specific as per your requirement:
public String [] format(String s) {
String arr []= s.split("<US>");
for(int i=0;i<arr.length;i++)
{
if(arr[i].equals(""))
{
arr[i]=null;
}
}
return arr;
}

Splitting and saving data in Java

I'm trying to read a data file and save the different variables into an array list.
The format of the data file looks a little like this like this
5003639MATH131410591
5003639CHEM434111644
5003639PSYC230110701
Working around the bad formatting of the data file, I added commas to the different sections to make a split work. The new text file created looks something like this
5,003639,MATH,1314,10591
5,003639,CHEM,4341,11644
5,003639,PSYC,2301,10701
After creating said file, I tried to save the information into an array list.
The following is the snippet of trying to do this.
FileReader reader3 = new FileReader("example.txt");
BufferedReader br3 = new BufferedReader(reader3);
while ((strLine = br3.readLine())!=null){
String[] splitOut = strLine.split(", ");
if (splitOut.length == 5)
list.add(new Class(splitOut[0], splitOut[1], splitOut[2], splitOut[3], splitOut[4]));
}
br3.close();
System.out.println(list.get(0));
The following is the structure it is trying to save into
public static class Class{
public final String recordCode;
public final String institutionCode;
public final String subject;
public final String courseNum;
public final String sectionNum;
public Class(String rc, String ic, String sub, String cn, String sn){
recordCode = rc;
institutionCode = ic;
subject = sub;
courseNum = cn;
sectionNum = sn;
}
}
At the end I wanted to print out one of the variables to see that it's working but it gives me an IndexOutOfBoundsException. I wanted to know if I'm maybe saving the info incorrectly, or am I perhaps trying to get it to print out incorrectly?
You have a space in your split delimiter specification, but no spaces in your data.
String[] splitOut = strLine.split(", "); // <-- notice the space?
This will result in a splitOut array of only length 1, not 5 like you expect.
Since you only add to the list when you see a length of 5, checking the list for the 0th element at the end will result in checking for the first element of an empty list, hence your exception.
If you expect your data to have a comma or a space separating the characters then you would alter the split line to be:
String[] splitOut = strLine.split("[, ]");
The split takes a regular expression as an argument.
Rather than artificially adding commas I would look at String.substring in order to cut the line you have read into pieces. For example:
while ((strLine = br3.readLine())!=null) {
if (strLine.length() != 20)
throw new BadLineException("line length is not valid");
list.add(new Class(strLine.substring(0,1), strLine.substring(1,7), strLine.substring(7,11), strLine.substring(11,15), strLine.substring(15,19)));
}
[ Untested: my numbers might be out because I a bit knacked, but you get the idea ]

Split a string in Java and picking up a part of it

Say I got a string from a text file like
"Yes ABC 123
Yes DEF 456
Yes GHI 789"
I use this code to split the string by whitespace.
while (inputFile.hasNext())
{
String stuff = inputFile.nextLine();
String[] tokens = stuff.split(" ");
for (String s : tokens)
System.out.println(s);
}
But I also want to assign Yes to a boolean, ABC to another string, 123 to a int.
How can I pick them up separately? Thank you!
boolean b=tokens[0].equalsIgnoreCase("yes");
String name=tokens[1];
int i=Integer.parseInt(tokens[2]);
Could you clarify what the exact purpose of what you're doing is? You can refer to the separate Strings with tokens[i] with i being the index. You could throw these into a switch statement (since Java 7) and match for the words you're looking for. Then you can take further action, i.e. convert the Strings to Booleans or Ints.
You should consider checking the input to be valid too even if you are expecting the file to always have those 3 words separated by a space.
Create Class Line and List<Line> that will store all your file into list:
public class Line{
private boolean mFlag = false;
private int mNum = 0;
private String mStr;
public Line(String stuff) {
String[] tokens = stuff.split("[ ]+");
if(tokens.length ==3){
mFlag=tokens[0].equalsIgnoreCase("yes");
mNum=Integer.parseInt(tokens[1]);
mStr=tokens[3];
}
}
}
and call it:
public static void main(String[] args) {
List<Line> list = new ArrayList<Line>();
Line line;
while (inputFile.hasNext())
{
String stuff = inputFile.nextLine();
line = new Line(stuff);
list.add(line);
}
}
If your input String is going to be in the same format always i.e. boolean,String ,int then you can access the individual indices of token array and convert them to your specified format
boolean opinion = tokens[0].equalsIgnoreCase("yes");
String temp = token[1];
int i = Integer.parseInt(token[2])
But you might require to create an array or something that stores the values for consecutive inputs that user does otherwise these variables would be over ridden for every new input from user.

How to compare against a null element in an array in java?

I have a program where I need to store the results in an arraylist:-
public class ReseedingDBRandomElements {
public static void main(String[] args){
try {
// getting the field Keyword from the csv
String csvfile="/Users/dray/Downloads/ReseedingDBRandomKeywords.csv";
BufferedReader br =new BufferedReader(new FileReader(csvfile));
StringTokenizer st = null;
String line="";
int linenumber=0;
int columnnumber;
// initializing the parameter for each column
int free = 0;
int free1 = 0;
// create the ArrayList
ArrayList<String> Keyword = new ArrayList<String>();
ArrayList<String> Alternate = new ArrayList<String>();
// reading through the csv file
while((line=br.readLine())!=null){
linenumber++;
columnnumber = 0;
st = new StringTokenizer(line,",");
while(st.hasMoreTokens()){
columnnumber++;
String token = st.nextToken();
if("Keyword".equals(token)){
free=columnnumber;
System.out.println("The value of free :"+free);
}else if ("Alternate".equals(token)){
free1=columnnumber;
System.out.println("The value of free1 :"+free1);
}
if(linenumber>1){
if (columnnumber==free)
{
Keyword.add(token);
}else if (columnnumber==free1){
Alternate.add(token);
}
}
}
}
// converting the keyword ArrayList to an array
String[] keyword = Keyword.toArray(new String[Keyword.size()]);
for(int i=0;i<keyword.length;i++){
System.out.println(" The value of the keyword is :"+keyword[i]);
}
// converting the alternate ArrayList to an array
String[] alternate = Alternate.toArray(new String[Alternate.size()]);
for(int i=0;i<alternate.length;i++){
System.out.println("The value of the alternate is :"+alternate[i]);
}
ArrayList<String> AlternateNew = new ArrayList<String>();
for(int i=1;i<keyword.length;i++){
if(keyword[i].equals(keyword[i-1])){
AlternateNew.add(alternate[i-1]);
}else if(!(keyword[i]==(keyword[i-1]))){
AlternateNew.add(alternate[i]);
}
}
String[] alternatenew = AlternateNew.toArray(new String[AlternateNew.size()]);
System.out.println("The length of the array is :"+alternatenew.length);
for(int i=0;i<alternatenew.length;i++){
System.out.println("the value of the alternatenew :"+alternatenew[i]);
}
}catch (Exception e){
System.out.println("there is an error :"+e);
}
}
}
The following is the csv file
Keyword,Alternate
ego kit,baby doll
ego kit,garage park
ego kit,random beats
galaxy tab,venus
galaxy tab,earth
galaxy tab,sun
What I am trying to do is compare elements and store it in an arraylist and display the results, but when last element is getting compared i.e 'galaxy tab' is getting compared to an empty field after last 'galaxy tab', it is not storing the previous result in the arraylist which is 'sun'
The following is the result of the program :
The value of the alternate is :baby doll
The value of the alternate is :garage park
The value of the alternate is :random beats
The value of the alternate is :venus
The value of the alternate is :earth
The last element is not getting stored in the arraylist.
Do not understand why? New to Java programming.
This section has a few problems also present throughout
AlternateNew.add(alternate[0]);
for(int i=1;i<keyword.length;i++){
if(keyword[i]==(keyword[i-1])){
AlternateNew.add(alternate[i]);
}else if(!(keyword[i]==(keyword[i-1]))){
AlternateNew.add(alternate[i]);
}
}
The naming convention in Java is to start with a lowercase letter for a variable name (unless it is a constant), which is why object AlternateNew is highlighted as if it were a class name.
The else if block tests the opposite of the same condition as its if. You could comment out if(!(keyword[i]==(keyword[i-1])), delete, or replace it with a more readable reminder comment, and the result would be the same.
AlternateNew.add(alternate[i]); happens regardless of this condition, in either branch of the if, so either remove the if statement entirely or fix some typo.
As for your actual [edit: original] question, I can't find anything wrong. Are you sure you didn't forget to save the csv file? I ran it using a text file and got output contrary to your post!

permutation(orderings) of a string of words but separated by a comma in between

I'm having some difficulty having this code generate a number of permutations(orderings) on a string separated by commas ...I can do just a regular string and have the permutations work on just letters but it is a bit more difficult when doing it with words separated by the commas...
To have the program recognize the commas I used the StringTokenizer method and I'm putting it into an arrayList but that is really as far as I have gotten ...the problem again is I'm having trouble permuting each word...to give an example I'll post it below this and then my code below that...thank you for your help everyone! ...and by permutations I mean orderings of the words separated by the comma's
For example, if the input coming in on the BufferedReader looked like:
red,yellow
one,two,three
the output on the PrintWriter should look like:
red,yellow
yellow,red
one,two,three
one,three,two
two,one,three
two,three,one
three,one,two
three,two,one
Note that the input had 3 lines total, including the blank line after "one,two,three" while the output had 11 lines total, including one blank line after "yellow,red" and two blank lines after "three,two,one". It is vital that you get the format exactly correct as the testing will be automated and will require this format. Also note that the order of the output lines for each problem does not matter. This means the first two lines of the output could also have been:
yellow,red
red,yellow
here is the code I have so far ...I have commented some stuff out so don't worry about those parts
import java.io.*;
import java.util.*;
public class Solution
{
public static void run(BufferedReader in, PrintWriter out)
throws IOException
{
String str = new String(in.readLine());
while(!str.equalsIgnoreCase(""))
{
PermutationGenerator generator = new PermutationGenerator(str);
ArrayList<String> permutations = generator.getPermutations();
for(String str: permutations)
{
out.println(in.readLine());
}
out.println();
out.println();
}
out.flush();
}
public class PermutationGenerator
{
private String word;
public PermutationGenerator(String aWord)
{
word = aWord;
}
public ArrayList<String> getPermutations()
{
ArrayList<String> permutations = new ArrayList<String>();
//if(word.length() == 0)
//{
//permutations.add(word);
//return permutations;
//}
StringTokenizer tokenizer = new StringTokenizer(word,",");
while (tokenizer.hasMoreTokens())
{
permutations.add(word);
tokenizer.nextToken();
}
/*
for(int i = 0; i < word.length(); i++)
{
//String shorterWord = word.substring(0,i) + word.substring(i + 1);
PermutationGenerator shorterPermutationGenerator = new PermutationGenerator(word);
ArrayList<String> shorterWordPermutations =
shorterPermutationGenerator.getPermutations();
for(String s: shorterWordPermutations)
{
permutations.add(word.readLine(i)+ s);
}
}*/
//return permutations;
}
}
}
You can use String.split() ( http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#split(java.lang.String) ) to get the individual words into as an array. You can separately generate all the permutations on integers {1..N} where N is the size of the word array. Then just walk the word array using the numeric permutations as indices.
Parse your input line (which is a comma-separated String ow words) into array of Strings (String[] words).
Use some permutation generator that works on a array, you can easily find such generator using google. U want a generator that can be initialized with Object[], and has a method like Object[] nextPermutation().
Put it together into your solution.
PS U can also use a Integer permutation generator and generate all permutations from 0 to (words.length - 1); each such permutation will give you an array of indexes of words[] to be printed out.

Categories

Resources