Link to home
Start Free TrialLog in
Avatar of gudii9
gudii9Flag for United States of America

asked on

wordcount challenge fix, improvement

http://codingbat.com/prob/p117630
public Map<String, Integer> wordCount(String[] strings) {
  Map<String, Integer> map=new HashMap<String, Integer>();
  for(String str: strings){
    int i=0;
    if(str.equals(str)){
      i++;
    }
    map.put(str,i);
  }
  return map;
}

Open in new window

Expected      Run            
wordCount(["a", "b", "a", "c", "b"]) → {"a": 2, "b": 2, "c": 1}      {"a": 1, "b": 1, "c": 1}      X      
wordCount(["c", "b", "a"]) → {"a": 1, "b": 1, "c": 1}      {"a": 1, "b": 1, "c": 1}      OK      
wordCount(["c", "c", "c", "c"]) → {"c": 4}      {"c": 1}      X      
wordCount([]) → {}      {}      OK      
wordCount(["this", "and", "this", ""]) → {"": 1, "and": 1, "this": 2}      {"": 1, "and": 1, "this": 1}      X      
wordCount(["x", "y", "x", "Y", "X"]) → {"x": 2, "X": 1, "y": 1, "Y": 1}      {"x": 1, "X": 1, "y": 1, "Y": 1}      X      
wordCount(["123", "0", "123", "1"]) → {"0": 1, "1": 1, "123": 2}      {"0": 1, "1": 1, "123": 1}      X      
wordCount(["d", "a", "e", "d", "a", "d", "b", "b", "z", "a", "a", "b", "z", "x", "b", "f", "x", "two", "b", "one", "two"]) → {"a": 4, "b": 5, "d": 3, "e": 1, "f": 1, "one": 1, "x": 2, "z": 2, "two": 2}      {"a": 1, "b": 1, "d": 1, "e": 1, "f": 1, "one": 1, "x": 1, "z": 1, "two": 1}      X      
wordCount(["apple", "banana", "apple", "apple", "tea", "coffee", "banana"]) → {"banana": 2, "apple": 3, "tea": 1, "coffee": 1}      {"banana": 1, "apple": 1, "tea": 1, "coffee": 1}      X      
other tests
X      

how to fix and improve my code for above challenge?
please advise
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

if(str.equals(str)){

Open in new window

How could a variable NOT equal itself?
ASKER CERTIFIED SOLUTION
Avatar of HainKurt
HainKurt
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

map.get(str)

what it returns
as per api it says
map.get(key) -- retrieves the stored value for a key, or null if that key is not present in the map.

how this fits here?
Avatar of gudii9

ASKER

https://www.tutorialspoint.com/java/util/hashmap_get.htm
as per this example it map.get(key) returns value as object right which they are appending to String as below to print
public class HashMapDemo {
   public static void main(String args[]) {
   // create hash map
   HashMap newmap = new HashMap();
      
   // populate hash map
   newmap.put(1, "tutorials");
   newmap.put(2, "point");
   newmap.put(3, "is best");
      
   // get value of key 3
   String val=(String)newmap.get(3);
      
   // check the value
   System.out.println("Value for key 3 is: " + val);

Open in new window

Avatar of gudii9

ASKER

package app;

import java.util.HashMap;
import java.util.Map;

public class MapCount {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(wordCount(["a", "b", "a", "c", "b"]));

	}
	
	public Map<String, Integer> wordCount(String[] strings) {
		  Map<String, Integer> map=new HashMap<String, Integer>();

		  for (String str: strings){
		    if (map.containsKey(str)) {
		      map.put(str, map.get(str)+1);
		    } else {
		      map.put(str,1);
		    }
		  }

		  return map;
		}

}

Open in new window

why above give error at line 10 as
Multiple markers at this line
      - Syntax error on token "[", delete this token
      - Syntax error on token "]", delete this token
      - The method wordCount(String[]) in the type MapCount is not applicable for the
       arguments (String, String, String, String, String)
Avatar of gudii9

ASKER

package app;

import java.util.HashMap;
import java.util.Map;

public class MapCount {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String ar[]={"a", "b", "a", "c", "b"};
		System.out.println(wordCount(ar));

	}
	
	public static Map<String, Integer> wordCount(String[] strings) {
		  Map<String, Integer> map=new HashMap<String, Integer>();

		  for (String str: strings){
		    if (map.containsKey(str)) {
		      map.put(str, map.get(str)+1);
		    } else {
		      map.put(str,1);
		    }
		  }

		  return map;
		}

}

Open in new window

above gives below result
{a=2, b=2, c=1}
Picked up _JAVA_OPTIONS: -Xmx512M
Avatar of gudii9

ASKER

public Map<String, Integer> wordCount(String[] strings) {
  Map<String, Integer> map=new HashMap<String, Integer>();

  for (String str: strings){
    if (map.containsKey(str)) {
      map.put(str, map.get(str)+1);
    } else {
      map.put(str,1);
    }
  }

  return map;
}

Open in new window

so for looping all array values and checking t see any of those values are key to the map if yes then putting that as the key and incrementing value by 1(but what is the initial value before incrementing by 1)
else
map puttint that str as key and 1 as value(where in description they gave to take 1 as value?
the solution @ ID: 42248515 gives what you ask for...

is there anything wrong here?
Avatar of gudii9

ASKER

public Map<String, Integer> wordCount(String[] strings) {
  Map<String, Integer> map=new HashMap<String, Integer>();

  for (String str: strings){
    if (map.containsKey(str)) {
      map.put(str, map.get(str)+1);
    } else {
      map.put(str,1);
    }
  }

  return map;
}

Open in new window


nothing wrong in above solution. But i did not understood solution specifically below line and bolded part

 map.put(str, map.get(str)+1);


what is map.get(str) returns? does it return int value?
is int value it returns is 0 for the first time search of str value?
can you please elaborate how this solution is designed and coded and working?
map.get(str) returns the int value of str

in case it exists, we use

map.put(str, map.get(str)+1)

Open in new window


to replace the key, with new value which is old value+1
in case it does not exists, we insert with value 1

map.put(str, 1);

Open in new window

Avatar of gudii9

ASKER

map.get(str) returns the int value of str

in case it exists, we use

map.put(str, map.get(str)+1)

Select all
 
Open in new window

to replace the key, with new value which is old value+1
in case it does not exists, we insert with value 1

map.put(str, 1);

But as per challenge we need to find number of times that string appears in the array right not the int value of string?(when you say int value of string you mean index of string in the given array position??) i am still confused. please advise

The classic word-count algorithm: given an array of strings, return a Map<String, Integer> with a key for each different string, with the value the number of times that string appears in the array.

wordCount(["a", "b", "a", "c", "b"]) → {"a": 2, "b": 2, "c": 1}
wordCount(["c", "b", "a"]) → {"a": 1, "b": 1, "c": 1}
wordCount(["c", "c", "c", "c"]) → {"c": 4}
when you get a string first time, say "a", we insert "a,1"
after that, if we get another "a", then we put "a,2" and it replaces old one...
so, every time, there is one object per key, say "a", and value is 1 stored initially, then with each put, we increment existing value, and put it back or replace...
now, lets look at this example

wordCount(["a", "b", "a", "c", "b"]) → {"a": 2, "b": 2, "c": 1}

  1. a > {"a": 1} - does not contain "a", insert {"a":1}
  2. b > {"a": 1, "b":1} - does not contain "b", insert {"b":1}
  3. a > {"a": 2, "b":1} - contains "a", insert {"a": current_value of "a" + 1}, ie {"a":2}, will replace {"a":1}, same key
  4. c > {"a": 2, "b":1, "c":1} - does not contain "c", insert {"c":1}
  5. b > {"a": 2, "b":2, "c":1} - contains "b", insert {"b": current_value of "b" + 1}, ie {"b":2}, will replace {"b":1}, same key
Avatar of gudii9

ASKER

a > {"a": 1} - does not contain "a", insert {"a":1}

how we got here from below bolded code?

public Map<String, Integer> wordCount(String[] strings) {
  Map<String, Integer> map=new HashMap<String, Integer>();

  for (String str: strings){
    if (map.containsKey(str)) {
      map.put(str, map.get(str)+1);//do you mean map.get("a") is 0 then we add 1 so it becomes 1 as the final value for given "a" at start?
    } else {
      map.put(str,1);
    }
  }

  return map;
}
Avatar of gudii9

ASKER

i think i got it now


map.get(key) -- retrieves the stored value for a key, or null if that key is not present in the map.

for below 1,2 scenarios we go through else part and set a, b key values to 1 using below code
else {
      map.put(str,1);
    }
1.a > {"a": 1} - does not contain "a", insert {"a":1}
2. b > {"a": 1, "b":1} - does not contain "b", insert {"b":1}

for scenario 3 and 5 we go through if loop and increment a,b key value 1  to 2 as we got one more a/b as key

if (map.containsKey(str)) {
      map.put(str, map.get(str)+1);
    }

3.a > {"a": 2, "b":1} - contains "a", insert {"a": current_value of "a" + 1}, ie {"a":2}, will replace {"a":1}, same key
5.b > {"a": 2, "b":2, "c":1} - contains "b", insert {"b": current_value of "b" + 1}, ie {"b":2}, will replace {"b":1}, same key
map.get(key) -- retrieves the stored value for a key, or null if that key is not present in the map.

but before that, we are checking existence of that key with "map.containsKey(str)"
if it contains, we put a new one with value = value + 1, ie replace
if it does not contain, we put that with value = 1, ie insert

insert and replace is done with same command, ie, "map.put(key, value)"
My version of it
public Map<String, Integer> wordCount(String[] strings) {
  return Arrays.stream(strings)
                 .collect(Collectors.toMap(s -> s, s -> 1, Integer::sum));
}

Open in new window

Avatar of gudii9

ASKER

public Map<String, Integer> wordCount(String[] strings) {
  return Arrays.stream(strings)
                 .collect(Collectors.toMap(s -> s, s -> 1, Integer::sum));

Open in new window


can you please elaborate this code. not clear to me.
Avatar of gudii9

ASKER

but before that, we are checking existence of that key with "map.containsKey(str)"
if it contains, we put a new one with value = value + 1, ie replace
if it does not contain, we put that with value = 1, ie insert

insert and replace is done with same command, ie, "map.put(key, value)"

this is very clear now. Thank you.
can you please elaborate this code. not clear to me.

gudii9 - this is something for you to work up to. I would ignore it but revist it when you're fully skilled in functional programming.
accepted solution should be

ID: 42248515

that code is tested and satisfies all requirements...
all discussion here is based on the logic and how that code works...
provided solution works and satisfies all requirements...
tested @ http://codingbat.com/prob/p117630