0

I am to initialize what is called an LZWDictionary to have an initial set of entries taken from the set of unique characters in a provided string.

Unique characters are added to a map as they are encountered in the provided input string, with an increasing index value (beginning at index 0). At the same time, the characters are added to a list. The indices associated with each dictionary entry in the map thus relate to their index (position) in the list.

Here is the code that I tried with comments on my thought process.

// Initialising map
map = new LinkedHashMap<>();
// Initialising list
list = new ArrayList<>();
// Declaring String variable for holding character
String str;
// Declaring index variable for holding Value
int index;

// If block for checking empty string.
if (characters.length() == 0)
    // Throwing IllegealArgumentException if String is empty.
    throw new IllegalArgumentException("Input should not be empty!!!");
else {

    // Iterating over the String
    for (int i = 0; i < characters.length(); i++) {
        // Taking particular character in the Iteration
        str = "" + characters.charAt(i);
        // Checking value of a particular character in the map
        if (map.get(str) == null) {

            // If not present in map, then add that to the map and list
            map.put(str, 1);
            list.add(str);
        }

        else {

            index = map.get(str);
            map.replace(str, index + 1);
        }

    }
}

I am getting a java.lang.AssertionError where the index value for "a" is not correct in map expected<0> but was <5>. The sample code is:

LZWDictionary act = new LZWDictionary("ababababa");
List<String> exp = Arrays.asList("a","b");
1
  • FYI: str = "" + characters.charAt(i) is better written as str = characters.substring(i, i + 1) Commented Nov 4, 2019 at 14:29

2 Answers 2

1

EDITED@20191105: simplified the code by removing additional 'int' variable as suggested by @Andreas


So, the problem of your code is the duplicated handling of same input character (In case you only want to count the first encountered appearance).

Then as mentioned by @Andreas, the code should be changed as below for getting what you've described:

    // Declaring index variable for holding Value
    //int index = 0;

.

        // Iterating over the String
        for (int i = 0; i < characters.length(); i++) {
            // Taking particular character in the Iteration
            str = "" + characters.charAt(i);
            // Checking value of a particular character in the map

            /*
             * if (map.get(str) == null) {
             * 
             * // If not present in map, then add that to the map and list map.put(str, 1);
             * list.add(str); }
             * 
             * else {
             * 
             * index = map.get(str); map.replace(str, index + 1); }
             */
            // If not present in map, then add that to the map and list map.put(str, 1);
            if (map.get(str) == null) {
                //map.put(str, index++);
                map.put(str, map.size());
                list.add(str);
            }
        }

    // Below is just for testing what has been put to the collections ... 
    Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
    while (it.hasNext()) {
        Entry<String, Integer> e = it.next();
        System.out.println(e.getKey() + " ; " + e.getValue());
    }

    for (String a: list) {
        System.out.println(a);
    }
Sign up to request clarification or add additional context in comments.

2 Comments

You don't need index, just use the list size: map.put(str, list.size()) --- The current size is the index of the next element added.
It's true. I was just thinking to keep the code close to original version for allowing @Keeley to understand it easily. I've just revised it per your suggestion. Thank you.
1

This part of your code isn't at all what you described:

if (map.get(str) == null) {

    // If not present in map, then add that to the map and list
    map.put(str, 1);
    list.add(str);
}

else {

    index = map.get(str);
    map.replace(str, index + 1);
}

You expect input "ababababa" to return a list [a, b], i.e. the unique characters, and a map with {a: 0, b: 1}, right? And input "aaaabbbbbbbbbbbb" should give the same result, right?

So the result list and result maps are only updated the first time a characters is seen, right?

Which means your code above shouldn't have an else clause. Get rid of it.

Also, the map is supposed to have the index of the unique character. But you have map.put(str, 1). They can't all be at index 1, can they?

Re-think what you're doing.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.