What I'm trying to do is add a substring from a String to an ArrayList. basically adding every letter in the string to an index in the ArrayList. After that i have a print statement just to see if the letters were added to the ArrayList (thats the second for loop under makearraylisOfChosenWord). However, when i run this with or without the print statement, it gives me a NullPointerException. Is it because I'm adding the letters to the arraylist in a wrong way in the first for loop?
thanks for the help
heres the code:
String[] wordList = {"apple", "orange", "strawberry", "banana"};
String chosenWord;
//Make an array list to hold one letter of the chosen word at each index
void makeArrayListOfChosenWord(){
ArrayList<String> lettersOfChosenWord = new ArrayList<String> ();
for (int i = 0; i < chosenWord.length(); i++) {
lettersOfChosenWord.add(chosenWord.substring(i, i+1));
}
for (int i = 0; i < lettersOfChosenWord.size(); i++) {
System.out.println((lettersOfChosenWord.get(i)).toString());
}
}
//Let the game pick a random word from the word list
void setRandomWord(){
int wordListLength = wordList.length;
int pickRandomWord = (int) (Math.random() * wordListLength);
String createRandomWord = wordList[pickRandomWord];
chosenWord = createRandomWord;
System.out.printf("the word is %s letters long", chosenWord.length());
}
I was just thinking about your problem and would try to use an ArrayList of Character instead of String. This is imo ok, because you mentioned that you are splitting up a String into single Characters, so ArrayList<Character>() seems a reasonable approach.
For splitting up the String I would make use of the method toCharArray():
String str = "abcd...";
ArrayList<Character> chars = new ArrayList<Character>();
for (char c : str.toCharArray()) {
chars.add(c);
}
If you call your setRandomWord method before you call makeArrayListOfChosenWord method no NullPointerException will be thrown. No if-check is needed in your code for this condition.
Related
I am required to write up a static method named getSuccessiveLetters(words) that takes a string array and returns a single String. If the String array is {"hello", "world"}, then the program should return "ho". "h" is from the first word, "o" is the 2nd letter from the 2nd word and so on.
I managed to get the correct return value for {"hello", "world"}, but if the String array contains, for example,{"1st", "2nd", "3rd", "4th", "fifth"} it goes out of range it struggles.
public class Template01 {
public static void main(String[] args) {
System.out.println(getSuccessiveLetters(new String[]{"1st", "2nd", "3rd", "4th", "fifth"}));
}
public static String getSuccessiveLetters(String[] words) {
char Str[] = new char[words.length];
String successive;
for(int i = 0; i < words.length; i++){
successive = words[i];
if (i < successive.length()){
Str[i] = successive.charAt(i);
}
else
{
break;
}
}
successive = new String(Str);
return successive;
}
I expected the return value to be 1nd, but the actual output is 1nd\x00\x00.
This is happening because when you initialize a char array, it fills the array with the default char value.
You can use StringBuilder or List<Character> to grow your "array" with each addition.
Change
char[] str = new char[words.length];
to
StringBuilder str = new StringBuilder();
and
str[i] = successive.charAt(i);
to
str.append(successive.charAt(i));
and then at the end successive = str.toString();.
This is because when you ignore the strings in the original array that are not long enough, you are not setting some of the char array elements as a result. This means that some elements will have the char value of \0 (default value of char). The resulting string therefore has these extra \0 characters as well.
I think it is more suitable to use a StringBuilder rather than a char[] here:
public static String getSuccessiveLetters(String[] words) {
StringBuilder builder = new StringBuilder();
String successive;
for(int i = 0; i < words.length; i++){
successive = words[i];
if (i < successive.length()){
builder.append(successive.charAt(i));
}
// you should not break here, because there might be a longer string in the array later on.
// but apparently you don't want the "h" in "fifth"? Then I guess you should break here.
}
successive = builder.toString();
return successive;
}
I recommend using Unit-Tests here. This could help you to improve.
you are creating a charArray here:
char Str[] = new char[words.length];
this array has the length of your string-array
new String[]{"1st", "2nd", "3rd", "4th", "fifth"}
which is 5
you create 3 entries for your new array (because you break at the first word, which is too short)
therefor you get 3 letters "1nd" and the 2 other slots in your array are filled with blanks when calling
successive = new String(Str);
1st: think about the break statement
2nd: think about using a StringBuilder / StringBuffer instead of a char[] for your matches
imho the most correct result should be 1nd h - but this depends on your given task
package com.db;
public class CountAlpha {
public static void main(String[] args) {
String str[] = {"aaaa4bbb3c"};
int count =0;
for(int i =0;i<str.length;i++) {
for(int j = i+1;j<str.length;j++) {
if(str[i] == str[j]) {
count++;
System.out.println(str[i]+" "+count);
}
else {
System.out.println(str[i]);
}
}
}
}
}
What is wrong in this code? I want to count the occurance of alphabete
Here, str is an array with only one element in it. So str.length is 1.
So the only value that i ever takes is 0. And the inner loop is never entered at all, because j starts at 1, which is already not < str.length.
You are trying to iterate over an string array that has just one element. You can either use charAt() or you can convert your string to a char array and iterate over it:
String string = "aaaa4bbb3c";
char str[] = string.toCharArray();
As mentioned by Dawood, the inner for-loop is never executed and therefore you don't see any output. If you want to count the occurrences of letters in a given string you can do the following
// Store the input string in a variable of type String rather than storing in an array of String
String s = "aaaa4bbb3c";
// Convert the String to a character array so that you can loop over it easily
char[] carray = s.toCharArray();
// Declare an array to store count of each alphabet in the string
int countArray[] = new int[MAX_CHAR];
Loop over the characters of carray and increment count of corresponding alphabet in the countArray.
You can find complete implementation of the problem here
The Str is an array with a length of 1, so the inner for loop will not be excuted.
To count the occurance of characters, you can creat an array with length of 26, and iterate the String while update the count array.
I'm a bit of a Java noob, so any help is appreciated. I have a method that is supposed to take a char value and an Arraylist of words in alphabetical order, and return all of the strings in the list that start with the same letter as the char. I'm not getting any error messages, but my method keeps returning an empty ArrayList. Why isn't my List being filled?
public String singlePhrase(char c, ArrayList<String> wordList){
ArrayList<String> words = new ArrayList<String>();
for (int i = 0; i < wordList.size(); i++) {
if (wordList.get(i).charAt(0) == c){
words.add(wordList.get(i));
}
}
return "Size: "+words.size() + " "+c;
}
If you wanted to return an ArrayList of words use the following:
public ArrayList<String> singlePhrase(char c, ArrayList<String> wordList) {
ArrayList<String> words = new ArrayList<String>();
for (int i = 0; i < wordList.size(); i++) {
if (Character.toLowerCase(wordList.get(i).charAt(0)) == Character.toLowerCase(c)) {
words.add(wordList.get(i));
}
}
return words;
}
Note that it compares the lowercase version of both characters.
Thank you guys for all the help, but the answer was way too simple. In the .txt file that was being parsed, all the strings began with uppercase letters. The test input was all lowercase, resulting in the '==' being false and the if() statement never being triggered.
I have an input like this in an ArrayList<String>:
cat eats mouse
mouse eats cheese
cheese is tasty
(blank lines should be ignored since I will be reading this input from a file)
and I want to convert it into a 2-d array of String which will have dimensions [no. of elements in ArrayList][3].
The no. 3 is fixed i.e. each sentence will have 3 words.
like this:
"cat" "eats" "mouse"
"mouse" "eats" "cheese"
"cheese" "is" "tasty"
here's what I have tried:
public static int processData(ArrayList<String> array)
{
String str[]=new String[array.size()];
array.toArray(str);
String str1[][]=new String[str.length][5];
for(int i=0;i<str.length;i++)
{
str1[i][]=str.split("\\s+"); //i want to do something like this, but this is showing errors.
}
return 0; //this is temporary, I will be modifying it
}
Tell me if I am not clear.
You are close. In Java, you can't put new elements at the end of an array by using empty brackets []. The following code does the thing. Note that number of elements in the second array is limited by 5. So, after the first 5 words, the rest of the line will be ignored. If the line is shorter, there will be nulls in the end of the array.
public static int processData(ArrayList<String> array) {
String[] str = new String[array.size()];
array.toArray(str);
String[][] str1 = new String[str.length][3];
for(int i=0; i < str.length; i++) {
String[] parts = str[i].split("\\s+");
for(int j = 0; j < parts.length || j < 3; j++) {
str1[i][j] = parts[j];
}
}
// do something next
}
A shorter, and slightelly more efficient version:
static int processData(ArrayList<String> array)
{
String str[][] = new String[array.size()][3];
for(int i = 0; i < str.length; ++i) {
str[i] = array.get(i).split("\\s+");
}
return 0;
}
There is no reasion for the first array called str in your code, since you cann access the Strings directly from the ArrayList.
Also you can don't have to copy the Strings, you can just put the arrays of Strings into the array of arrays, like in my code
Plus, if you have a fixed size of 3, and don't need to add any more to the arrays, why do you allocate space for 5 strings?
As you mentioned "arraylist" in Subject:
try{
BufferedReader br = new BufferedReader(new FileReader("filename"));
Arraylist<String[]> l = new ArrayList<String[]>();
String line;
while((line = br.readline) != null)
l.add(line.split("\\s+");
br.close();
}catch(Exception e){e.printStackTrace();}
Change your for loop to:
String str1[][] = new String[str.length][3];
for(int i = 0; i < str.length; i++) {
str1[i] = str[i].split("\\s+");
}
You don't need to have 5 elements if you know that you have only 3 words, do not waste your resources.
str is a String[], str[i] is a String, str[i].split() is a String[] and so is str1[i]. The types match.
Also, this way the code is clearer and easier to understand. I agree with Ongy to remove str if you do not need it, but I can't tell now because you said you are going to change this method later (at least the return value)
Bonus: Btw, the names array, str, str1 are not the best choice for that piece of code, it is really easy to be confused what is what. Try finding better name such as lines, linesArray, words or something like that
I am kind of stuck on this java problem involving returning the number of isomorphic pairs in an array of Strings. The code I have written keeps returning incorrect number of isomorphic word pairs.
The definition of isomorphic words is given as follows: Two words are called isomorphic if the letters in one word can be remapped to get the second word. Remapping a letter means replacing all occurrences of it with another letter. The ordering of the letters remains unchanged. No two letters may map to the same letter, but a letter may map to itself.
For example, the words "abca" and "zbxz" are isomorphic because we can map 'a' to 'z', 'b' to 'b' and 'c' to 'x'.
I am not inlcuding the getMap method which I call in the function. The getMap method take any string as input, and returns a map where the keys are the letters in the string, and the corresponding values are the number of times the letter appears in the string.
public class IsomorphicWords {
public int countPairs(String[] words) {
Set <String> pairs = new HashSet<String>();
for (String word:words){
Map noOfOccurencesOfEachLetter= getMap(word);
ArrayList<Integer> valuesFromFirstWord = new ArrayList<Integer>(noOfOccurencesOfEachLetter.values());
Collections.sort(valuesFromFirstWord);
java.util.List<String> list = new ArrayList<String>(Arrays.asList(words));
list.remove(word);
String[] oneLessWord = list.toArray(new String[words.length-1]);
for(String secondWord:oneLessWord){
Map secondNoOfOccurencesOfEachLetter = getMap(secondWord);
ArrayList<Integer> valuesFromSecondWord = new ArrayList<Integer>(secondNoOfOccurencesOfEachLetter.values());
Collections.sort(valuesFromSecondWord);
if (valuesFromFirstWord.equals(valuesFromSecondWord)){
pairs.add(""+word+","+secondWord+"");
}
else{
continue;
}
}
}
return pairs.size()/2;
public Map getMap(String word){
HashMap<String,Integer> noOfOccurencesOfEachLetter= new HashMap<String,Integer>();
for (int i=0;i<word.length();i++){
char letter = word.charAt(i);
String letterInDictionary= Character.toString(letter);
if (noOfOccurencesOfEachLetter.containsKey(letterInDictionary)==true){
int count= noOfOccurencesOfEachLetter.get(letterInDictionary);
noOfOccurencesOfEachLetter.put(letterInDictionary, count+1);
}
else{
noOfOccurencesOfEachLetter.put(letterInDictionary, 1);
}
}
return noOfOccurencesOfEachLetter;
}
}
I'd really appreciate any feedback you can give me on this code.
Thanks,
Junaid
The reason why it gives the incorrect answer probably comes from you take the letter count, and don't look at the position that they have in both words. The first solution that comes up in me, is to create a new array in which you translate the letters to the index of the first occurrence of this letter for each word. For example: "abcd" would be "0123", "abca" would be "0120" and "fhjf" would be "0120" as well. Then you can simply compare the results. I hope this helps...
public int countPairs(String[] words) {
int isomorphicPairs = 0;
for (int i = 0; i < words.length; i++) {
for (int j = i+1; j < words.length; j++) {
if (words[i].length() == words[j].length()) {
String tmp = new String(words[j]);
for (int k = 0; k < tmp.length(); k++)
tmp = tmp.replaceAll("" + tmp.charAt(k), "" + words[i].charAt(k));
if (words[i].equals(tmp)) isomorphicPairs++;
}
}
}
return isomorphicPairs;
}