A. O'Mary
A. O'Mary

Reputation: 71

How to break up an ArrayList<String> by searching for a given character and creating new ArrayList?

I am trying to break up an String ArrayList by searching each String for a given character. Separating the lists into new lists according to the common position of the character.

If the array is

list1 = new String[] {"fish", "look", "flow", "fowl", "cool"}; 

and the given character is 'l' then I would get 4 new arrays no l "----"(fish), "l---"(look), "-l--"(flow), "---l"(fowl, cool). The arraylists would have the corresponding strings in them. The error I get is:

java.lang.AssertionError
ArrayList<String> ret = f.familiesOf('l');
        assertTrue(ret.contains("----"));


    public Family_2(String[] w)
    {
        words = w;
    }

    /**
     * Given a single character, return an ArrayList of
     * all the word families. Each family should
     * appear only once in the ArrayList and there should be none
     * that aren't needed. The returned list can be in any order.
     */

    public ArrayList<String> familiesOf(char c)
    {
        String fam = "";
        ArrayList<String> wordList = new ArrayList<String>();
        ArrayList<String> wordList2 = new ArrayList<String>();
        Collections.addAll(wordList, words);
        String longestString = wordList.get(0);

        // when I added the below code I stopped getting an out of bounds exception.

        for (String element : wordList)
        {
            if (element.length() > longestString.length()) {
                longestString = element;
            }
        }   

        // This is where I'm struggling with checking and separating the ArrayList.

        for(int i = 0; i < words.length; i++)
        {
            if(words[i].indexOf(c) != c)
            {
                fam += '-'; 
                wordList2 = wordList;
            }
            else if(words[i].indexOf(c) == c)
            {
                fam += c;
                wordList2 = wordList;
            }
        }
        return wordList;
    }

This is a precursor to a hangman game being created.

Upvotes: 1

Views: 60

Answers (1)

Abra
Abra

Reputation: 20913

I think the key to implementing your algorithm is choosing the correct data structure. I think the correct data structure would be a Map. The Map key would be Integer (since the key cannot be a primitive, so it cannot be int) which would be the index of the letter, and the value would be a List of the words that have the relevant letter at that index.

Here is my code that implements the algorithm, according to the specifications and limitations you detailed.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HangsMan {

    public static void main(String[] args) {
        String[] words = new String[]{"fish", "look", "flow", "fowl", "cool", "eel", "poll", "fill"};
        char letter = 'l';
        Map<Integer, List<String>> theMap = new HashMap<>();
        Integer key;
        List<String> value;
        for (String word : words) {
            int ndx = word.indexOf(letter);
            int last = word.lastIndexOf(letter);
            if (last == ndx + 1) {
                ndx += 1_000_000;
            }
            key = Integer.valueOf(ndx);
            if (theMap.containsKey(key)) {
                value = theMap.get(key);
            }
            else {
                value = new ArrayList<String>();
                theMap.put(key, value);
            }
            value.add(word);
        }
        theMap.forEach((k, v) -> System.out.println(v));
    }
}

Note that words with double letters have 1_000_000 (one million) added to the index so as to keep them separate from single letter words. Hence the index for the word poll would be 1,000,002 and the index for the word cold would be just 2.

Why do I add one million, you ask? Because, according to Wikipedia, the longest word in the English language contains 189,819 letters.

Upvotes: 1

Related Questions