Splitting tokens into tokens using delimiters in Java - java

I have the following txt file that I need to split with tokens and save to an object:
1,Harry Potter,4,3,11,14,20
2,Matrix,3,1,8,12
3,Batman,3,39,9,42
Structure is: id, name, length, movieIds
Where length is reference to how many movieIds there are.
Not sure how to split movieIds separately or to set multiple values to the object as they override one another.
Scanner inputFile = new Scanner(playlistLibrary);
String str;
String[] tokens;
for (int i = 1; i < playlist.length; i ++) {
playlist[i] = new Playlist_17967352();
if (inputFile.hasNext()) {
str = inputFile.nextLine();
tokens = str.split(",");
for (int a = 0; a < tokens.length; a ++) {
playlist[i].setId(tokens[0]);
playlist[i].setName(tokens[1]);
playlist[i].setLength(tokens[2]);
if (tokens.length > 3) {
int length = Integer.parseInt(playlist[i].getLength());
String movieIds;
for (int b = 0, c = 3 ; b < length; b++, c++) {
movieIds = tokens[c];
playlist[i].setMovies(movieIds);
}
}
} // end for tokens.length
System.out.println(playlist[i].getMovies());
Code output:
20
12
42
What I need is:
3,11,14,20
1,8,12
39,9,42

You can just do one split. You know that the first movie id is at tokens[3], so you only need one counter in your loop and then add 3 when indexing tokens.

Related

How do I split a string into even parts then populate an array with those new strings?

I am working on a program and I will be asking the user to input a string full of characters with no spaces. I will then be splitting this string up into parts of three characters each, and I would like to populate an array with these new strings of three characters. So basically what I am asking is how would I create a method that takes an input string, splits it up into separate parts of three, then populates an array with it.
while (i <= DNAstrand.length()-3) {
DNAstrand.substring(i,i+=3));
}
This code will split the string up into parts of three, but how do I assign those values to an array in a method?
Any help is appreciated thanks!
Loop through and add all the inputs to an array.
String in = "Some input";
//in.length()/3 is automatically floored
String[] out = new String[in.length()/3];
int i=0;
while (i<in.length()-3) {
out[i/3] = in.substring(i, i+=3);
}
This will ignore the end of the String if it's length isn't a multiple of 3. The end can be found with:
String remainder = in.substring(i, in.length());
Finally, if you want the remainder to be part of the array:
String in = "Some input";
//This is the same as ceiling in.length()/3
String[] out = new String[(in.length()-1)/3 + 1];
int i=0;
while (i<in.length()-3) {
out[i/3] = in.substring(i, i+=3);
}
out[out.length-1] = in.substring(i, in.length());
Try this:
private static ArrayList<String> splitText(String text)
{
ArrayList<String> arr = new ArrayList<String>();
String temp = "";
int count = 0;
for(int i = 0; i < text.length(); i++)
{
if(count < 3)
{
temp += String.valueOf(text.charAt(i));
count++;
if(count == 3)
{
arr.add(temp);
temp = "";
count = 0;
}
}
}
if(temp.length() < 3)arr.add(temp);//in case the string is not evenly divided by 3
return arr;
}
You can call this method like this:
ArrayList<Strings> arrList = splitText(and the string you want to split);

Extract words from an array of Strings in java based on conditions

I am trying to do an assignment that works with Arrays and Strings. The code is almost complete, but I've run into a hitch. Every time the code runs, it replaces the value in the index of the output array instead of putting the new value in a different index. For example, if I was trying to search for the words containing a prefix "b" in the array of strings, the intended output is "bat" and "brewers" but instead, the output comes out as "brewers" and "brewers". Any suggestions? (ps. The static main method is there for testing purposes.)
--
public static void main(String[] args) {
String[] words = {"aardvark", "bat", "brewers", "cadmium", "wolf", "dastardly", "enigmatic", "frenetic",
"sycophant", "rattle", "zinc", "alloy", "tunnel", "nitrate", "sample", "yellow", "mauve", "abbey",
"thinker", "junk"};
String prefix = "b";
String[] output = new String[wordsStartingWith(words, prefix).length];
output = wordsStartingWith(words, prefix);
for (int i = 0; i < output.length; i++) {
System.out.println("Words: " + i + " " + output[i]);
}
}
public static String[] wordsStartingWith(String[] words, String prefix) {
// method that finds and returns all strings that start with the prefix
String[] returnWords;
int countWords = 0;
for (int i = 0; i < words.length; i++) {
// loop to count the number of words that actually have the prefix
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
countWords++;
}
}
// assign length of array based on number of words containing prefix
returnWords = new String[countWords];
for (int i = 0; i < words.length; i++) {
// loop to put strings containing prefix into new array
for (int j = 0; j < returnWords.length; j++) {
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
returnWords[j] = words[i];
}
}
}
return returnWords;
}
--
Thank You
Soul
Don't reinvent the wheel. Your code can be replaced by this single, easy to read, bug free, line:
String[] output = Arrays.stream(words)
.filter(w -> w.startsWith(prefix))
.toArray(String[]::new);
Or if you just want to print the matching words:
Arrays.stream(words)
.filter(w -> w.startsWith(prefix))
.forEach(System.out::println);
Its because of the code you have written. If you would have thought it properly you would have realized your mistake.
The culprit code
for (int j = 0; j < returnWords.length; j++) {
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
returnWords[j] = words[i];
}
}
When you get a matching word you set whole of your output array to that word. This would mean the last word found as satisfying the condition will replace all the previous words in the array.
All elements of array returnWords gets first initialized to "bat" and then each element gets replaced by "brewers"
corrected code will be like this
int j = 0;
for (int i = 0; i < words.length; i++) {
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
returnWords[j] = words[i];
j++;
}
}
Also you are doing multiple iterations which is not exactly needed.
For example this statement
String[] output = new String[wordsStartingWith(words, prefix).length];
output = wordsStartingWith(words, prefix);
can be rectified to a simpler statement
String[] output = wordsStartingWith(words, prefix);
The way you're doing this is looping through the same array multiple times.
You only need to check the values once:
public static void main(String[] args) {
String[] words = {"aardvark", "bat", "brewers", "cadmium", "wolf", "dastardly", "enigmatic", "frenetic",
"sycophant", "rattle", "zinc", "alloy", "tunnel", "nitrate", "sample", "yellow", "mauve", "abbey",
"thinker", "junk"};
String prefix = "b";
for (int i = 0; i < words.length; i++) {
if (words[i].toLowerCase().startsWith(prefix.toLowerCase())) {
System.out.println("Words: " + i + " " + words[i]);
}
}
}
Instead of doing two separate loops, try just having one:
String[] returnWords;
int[] foundWords = new int[words.length];
int countWords = 0;
for (int i = 0; i < words.length; i++) {
// loop to count the number of words that actually have the prefix
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
foundWords[index] = words[i];
countWords++;
}
}
// assign length of array based on number of words containing prefix
returnWords = new String[countWords];
for (int i = 0; i < countWords; i++) {
returnWords[i] = foundWords[i];
}
My method has another array (foundWords) for all the words that you found during the first loop which has the size of words in case every single word starts with the prefix. And index keeps track of where to place the found word in foundWords. And lastly, you just have to go through the countWords and assign each element to your returnWords.
Not only will this fix your code but it will optimize it so that it will run faster (very slightly; the bigger the word bank is, the greater fast it will search through).

Displaying a string with hidden characters

I have a test for a class that displays a word randomly chosen from an array.
I'm trying to display the word with several chars hidden
I have taken the string, then converted it to an array of chars, but I'm confused as to where to go from here.
import java.util.Scanner;
public class wordTest {
public static void main (String args[])
{
Scanner scanner = new Scanner(System.in);
String readString = scanner.nextLine();
char[] stringArray;
String [] gamewords = { "dog", "cat", "coffee", "tag", "godzilla", "gamera", "lightning", "flash", "spoon", "steak", "moonshine", "whiskey", "tango", "foxtrot", "ganymede"
, "saturn", "enterprise", "reliant", "defiant", "doom", "galapagos", "jidai", "sengoku"};
arrayWords wl = new arrayWords();
// Words w = new Words();
Word n = new Word();
int a = 0;
int b = gamewords.length;
RandNum rand = new RandNum(a,b);
n.setWord(gamewords[rand.nextRandomIntegerInRange()]);
stringArray = n.getWord().toCharArray();
int blank1 = 1;
int blank2 = 4;
RandNum blanks = new RandNum(blank1,blank2);
n.setWord(gamewords[rand.nextRandomIntegerInRange()]);
do{
int i = 0;
//scanner.nextLine();
for( i = 0; i < stringArray.length; i++){
for( i = 0 ; i < blanks.nextRandomIntegerInRange() ; i++ ){
stringArray[i] = '*';
}
System.out.println(stringArray[i]);
}
}while(scanner.nextLine().equals(""));
}
}
Since you haven't given clear definition on what you want to do, here I assume for every string, you are randomly masking 2 characters, in pseudo code, it looks like:
if inputString.length < 2 {
mask all character
} else {
loop until 2 character masked {
r = random from 0 to inputString.length-1
if (inputString[r] is not masked) {
set inputString[r] to mask character
}
}
}
some hints:
to make "inputString" modifiable, make use of a StringBuilder
Way to check if certain position is masked, you can either simply check if the character in the string == mask character, or you can use a Set to keep all masked position
In order to find out number of position masked, you can keep a counter, or simply use the size of the Set in 2 if you choose to use a Set.
Okay, so I think I've found the solution:
for (int i = 0; i < stringArray.length ; i++) {
stringArray[blanks.nextRandomIntegerInRange()] = '_';
System.out.print(stringArray[i] + " " );
}

an oops to making space sub string

I want to have a program that takes a string, splits it at a space, and prints the length of the smallest substring.
I wrote this but it just prints the length of the first string. What is my problem ?
Scanner input = new Scanner(System.in);
String inp = input.nextLine();
int counter = 0;
String[]helper =new String[inp.length()];
int minlength = Integer.MAX_VALUE;
for (int i = 0; i < inp.length(); i++)
{
if (inp.charAt(i) != ' ')
{
counter++;
continue;
}
minlength = Math.min(counter, minlength);
counter = 0;
}
System.out.println(minlength);
Use .split method to split a string by spaces.
String[] stringArray = input.split("\\s+");
Generally you could do:
String[] stringArray = input.split(" ");
But this source explains why the first option is better: How do I split a string with any whitespace chars as delimiters?
Once you have the String[] stringArray, then you can loop through it and find the smallest length.
int minlength = Integer.MAX_VALUE;
for(int i = 0; i < stringArray.length; i++){
if(stringArray[i].length() < minlength){
minlength = stringArray[i].length();
}
}
System.out.println(minlength);

equality between two strings

I have a text file with this structure:
CRIM:Continuius
ZN:Continuius
INDUS:Continuius
CHAS:Categorical
NOX:Continuius
I inserted it into a two dimensional array:
BufferedReader description = new BufferedReader(new FileReader(fullpath2));
String[][] desc;
desc = new String[5][2];
String[] temp_desc;
String delims_desc = ":";
String[] tempString;
for (int k1 = 0; k1 < 5; k1++) {
String line1 = description.readLine();
temp_desc = line1.split(delims_desc);
desc[k1][0] = temp_desc[0];
desc[k1][1] = temp_desc[1];
}
and then tried to identify which attribute is Categorical:
String categ = "Categorical";
for (int i=0; i<5; i++){
String temp1 = String.valueOf(desc[i][1]);
if ("Categorical".equals(desc[i][1])){
System.out.println("The "+k1+ " th is categorical.");
}
}
Why doesn't it return true, although one of the attributes is categorical?
Looking at the input you posted (in the edit perspective), I saw there is a lot of trailing whitespace on almost every line of the textfile. Your problem will disappear if you replace
desc[k1][1] = temp_desc[1];
with
desc[k1][1] = temp_desc[1].trim();
You could even shorten your code to
for (int k1 = 0; k1 < 5; k1++) {
String line1 = description.readLine().trim();
desc[k1] = line1.split(delims_desc);
}
Clarification:
You are trying to compare
"Categorical" // 11 characters
with
"Categorical " // more than 11 characters
and those are not equal strings.

Categories

Resources