I don't understand why my code is not working. I get an error: "cannot find symbol - method getLength()," which is defined in the Array class. Any suggestions about how to make this method better? Thank you!
/**
* getWordCount
*
* Get a count of how many times each word occurs in an input String.
*
* #param text a string containing the text you wish to analyze
* #return a map containing entries whose keys are words, and
* whose values correspond to the number of times that word occurs
* in the input String text.
*/
public Map<String,Integer> getWordCount(String text)
{
String[] parts = text.trim().split("('s|\\W)+");
Map<String, Integer> wordCountMap = new TreeMap<String, Integer>();
for(int i=0;i<parts.getLength();i++)
{
for(String text : parts[i].toString())
{
if(!wordCountMap.containsKey(text))
{
wordCountMap.put(text,1);
} else {
int freq = wordCountMap.get(text);
freq++;
wordCountMap.put(text,freq);
}
return wordCountMap;
}
return new TreeMap<String,Integer>();
}
}
There is more than one issue with your code.
The following changes might help
public Map<String,Integer> getWordCount(String text)
{
String[] parts = text.trim().split("('s|\\W)+");
Map<String, Integer> wordCountMap = new TreeMap<String, Integer>();
for (String part : parts)
{
if(!wordCountMap.containsKey(part))
{
wordCountMap.put(part,1);
} else {
int freq = wordCountMap.get(part);
freq++;
wordCountMap.put(part,freq);
}
}
return wordCountMap;
}
The following test code gives a size of 5 which seems to confirm what you looking to do in your code.
Map<String, Integer> map = getWordCount(" the fox jumped over the moon ");
System.out.println("size:" + map.size());
Related
I am implementing a Java based synonym finder, which will store the thesaurus of 250k words into a map and each associated googleWord into the txt file (1000 words in total) will be assigned as values for each of the thesaurus word if its the synonym of it.
Now, that I am doing that I am iterating over each Thesaurus word list and checking for its synonym using wordnet library and if the google word has one of those synonym word them I am assigning that value to Thesaurus map. Code block is provided below:
#SuppressWarnings("rawtypes")
public TreeMap fetchMap() throws IOException {
generateThesaurusList();
generateGoogleList();
/** loop through the array of Thesaurus Words..*/
for (int i=0; i<thesaurusList.size(); i++) {
SynonymFinder sf = new SynonymFinder();
// find the
ArrayList synonymList = sf.getSynonym(thesaurusList.get(i).toString().trim());
for (int j=0; j<synonymList.size(); j++) {
if (googleList.contains(synonymList.get(j)));
hm.put(thesaurusList.get(i).toString().trim(), synonymList.get(j).toString().trim());
}
}
return hm;
}
But, the iteration of the list and its insertion is taking very huge time. Can someone suggest something to cater it fast.
I have used HashMap for the same, but it was also slow..
Note: I must have to use some sort of map for storing data..
My change after suggestions, but nothing helped out.
#SuppressWarnings("rawtypes")
public TreeMap fetchMap() throws IOException {
generateThesaurusList();
generateGoogleList();
Set<String> gWords = new HashSet<>(googleList);
int record =1;
int loopcount=0;
ArrayList thesaurusListing = removeDuplicates(thesaurusList);
Map<String, Set<String>> tWordsWithSynonymsMatchingGoogleWords = new TreeMap<>();
/** loop through the array of Google Words..*/
for (int i=0; i<thesaurusListing.size(); i++) {
SynonymFinder sf = new SynonymFinder();
System.out.println(record);
// find the
ArrayList synonymList = sf.getSynonym(thesaurusListing.get(i).toString().trim());
for (int j=0; j<synonymList.size(); j++) {
if (googleList.contains(synonymList.get(j))) {
/**to avoid duplicate keys*/
tWords.put(thesaurusListing.get(i).toString().trim(), new HashSet<>(synonymList));
}
}
for (String tWord : tWords.keySet()) {
tWords.get(tWord).retainAll(gWords);
tWordsWithSynonymsMatchingGoogleWords.put(tWord, tWords.get(tWord));
}
record++;
}
return (TreeMap) tWordsWithSynonymsMatchingGoogleWords;
}
Your code was missing part of creation, entry which will consist of {key, set}, but was {key, value}. Based on what you want to achieve, you need to intersect two sets. Here is example how you can approach that:
public static Map<String, Set<String>> getThesaurusWordsWithSynonymsMatchingGoogleWords(
Map<String, Set<String>> tWordsWithSynonyms, Set<String> gWords) {
Map<String, Set<String>> tWordsWithSynonymsMatchingGoogleWords = new TreeMap<>();
for (String tWord : tWordsWithSynonyms.keySet()) {
tWordsWithSynonyms.get(tWord).retainAll(gWords);
tWordsWithSynonymsMatchingGoogleWords.put(tWord, tWordsWithSynonyms.get(tWord));
}
return tWordsWithSynonymsMatchingGoogleWords;
}
public static void main(String[] args) {
Map<String, Set<String>> tWords = new HashMap<>();
tWords.put("B", new HashSet<>(Arrays.asList("d")));
tWords.put("A", new HashSet<>(Arrays.asList("a", "b", "c")));
tWords.put("C", new HashSet<>(Arrays.asList("e")));
Set<String> gWords = new HashSet<>(Arrays.asList("a", "b", "e"));
System.out.println("Input -> thesaurusWordsWithSynonyms:");
System.out.println(tWords);
System.out.println("Input -> googleWords:");
System.out.println(gWords);
Map<String, Set<String>> result = getThesaurusWordsWithSynonymsMatchingGoogleWords(tWords, gWords);
System.out.println("Input -> thesaurusWordsWithSynonymsMatchingGoogleWords:");
System.out.println(result);
}
}
To make all things working, firstly you should trim you thesaurus words and find their matching synonyms.
I have to write a piece of code for a class that counts the occurrences of characters within an input file and then sorts them by that, and I chose to do that by creating an ArrayList where each object[] has two elements, the character and the number of occurrences.
I was trying to increment the integer representing the number of occurrences and I just couldn't get that to work
My current attempt looks like this:
for(int i=0;i<=text.length();i++) {
if(freqlist.contains(text.charAt(i))) {
freqlist.indexOf(text.charAt(i))[1]=freqlist.get(freqlist.indexOf(text.charAt(i)))[1]+1;
}
}
text is just a string containing all of the input file
freqlist is declared earlier as
List<Object[]> freqlist=new ArrayList<Object[]>();
So, I was wondering how one could increment or modify an element of an array that is inside of an arraylist
In General there are 3 mistakes in your program which prevent it from working. It cannot work because the for loop has i<=text.length() and it should be i < text.length(), otherwise you will have exception. Second mistake is that you use freqlist.contains(...) where you assume both elements of object arrays are the same, or in other words the array is the equal, which is wrong assumption. Third mistake is using freqlist.indexOf(...) which relies on array equality again. I made the example working although this data structure List<Object[]> is inefficient for the task. It is best to use Map<Character,Integer>.
Here it is:
import java.util.ArrayList;
import java.util.List;
class Scratch {
public static void main(String[] args) {
String text = "abcdacd";
List<Object[]> freqlist= new ArrayList<>();
for(int i=0;i < text.length();i++) {
Object [] objects = find(freqlist, text.charAt(i));
if(objects != null) {
objects[1] = (Integer)objects[1] +1;
} else {
freqlist.add(new Object[]{text.charAt(i), 1});
}
}
for (Object[] objects : freqlist) {
System.out.println(String.format(" %s => %d", objects[0], objects[1]));
}
}
private static Object[] find(List<Object[]> freqlist, Character charAt) {
for (Object[] objects : freqlist) {
if (charAt.equals(objects[0])) {
return objects;
}
}
return null;
}
}
The way I would do this is first parse the file and convert it to an array of characters. This would then be sent to the charCounter() method which would count the number of times a letter occurs in the file.
/**
* Calculate the number of times a character is present in a character array
*
* #param myChars An array of characters from an input file, this should be parsed and formatted properly
* before sending to method
* #return A hashmap of all characters with their number of occurrences; if a
* letter is not in myChars it is not added to the HashMap
*/
public HashMap<Character, Integer> charCounter(char[] myChars) {
HashMap<Character, Integer> myCharCount = new HashMap<>();
if (myChars.length == 0) System.exit(1);
for (char c : myChars) {
if (myCharCount.containsKey(c)) {
//get the current number for the letter
int currentNum = myCharCount.get(c);
//Place the new number plus one to the HashMap
myCharCount.put(c, (currentNum + 1));
} else {
//Place the character in the HashMap with 1 occurrence
myCharCount.put(c, 1);
}
}
return myCharCount;
}
You could use some Stream magic, if you are using Java 8 for the grouping:
Map<String, Long> map = dummyString.chars() // Turn the String to an IntStream
.boxed() // Turn int to Integer to use Collectors.groupingBy
.collect(Collectors.groupingBy(
Character::toString, // Use the character as a key for the map
Collectors.counting())); // Count the occurrences
Now you could sort the result.
My hashmap key returns this: MemorySection[path='rr', root='YamlCofiguration']=1
Is there anyway I can get the value of path=''. I know that I can get the value of the root='' using getValue(), although I only really use this for keeping track of the highest and lowest values to then order them from highest to lowest.
I have tried this thread although the answers presume that I would know what the pair's name is. Retrieving Key from the Hash Map
EDIT:
Here is how I'm setting the data and sorting it as well. I am accessing it through the likesList List
HashMap<String, Integer> likes = new HashMap<>();
for(String key: playersFile.getKeys(false)) {
likes.put(playersFile.getString(key), playersFile.getInt(key + ".likes"));
}
List<Entry<String, Integer>> likesList = new LinkedList<Entry<String, Integer>>(likes.entrySet());
Collections.sort(likesList, new Comparator<Entry<String, Integer>>() {
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return o2.getValue() - o1.getValue();
}
});
for (int i = 0; i<45; i++) {
try {
String name1 = cookiesList.get(i).getKey();
item = name(name1);
publicinv.setItem(i, item);
} catch (IndexOutOfBoundsException e) {
}
}
I still don't really know what you want, but here is a guess I made:
// your input
String name1 = "MemorySection[path='rr', root='YamlCofiguration']=1";
// this string indicates the start of the path
String start = "path='";
// where the path starts
int pathStart = name1.indexOf(start)+start.length();
// where the path ends
int pathEnd = name1.substring(pathStart).indexOf("'") + pathStart;
// get the path
System.out.println( name1.substring(pathStart, pathEnd) ); // prints: rr
This question already has answers here:
HashMap<String, Integer> Search for part of an key? [duplicate]
(8 answers)
Closed 8 years ago.
I have a hashmap with Key and Value being 'String'. I want to check if a particular key exists by ignoring string after '$' in the Key.
Hashmap contains keys as 'acctId$accountId', 'acctId$desc', 'acctId$crncyCode' etc.
Iterator itx = uiToSrvFldMapList.entrySet().iterator();
if(uiToSrvFldMapList.containsKey(cellId)){
String sSrvFld = (String) uiToSrvFldMapList.get("acctId");
System.out.println("sSrvFld :: " +sSrvFld);
public static void main(String[] args) {
String s = "acctId$accountId";
s = s.replaceAll("\\$.*", "");// remove everything after $
System.out.println(s);
// do hm.get(s) here
}
I hope this might help you
Map map = new HashMap();
map.put("abc$def","ABC");
map.put("ab","A");
map.put("de","b");
String key = "abc$def";
String s[] = key.split("$");
if(map.containsKey(s[0]))
System.out.println("Value is: "+map.get(key));
else
System.out.println("cannot find..");
Supposing that in "acctId$accountId" you will have the same String both as "acctId" and "accountId", you can search for it in the following way:
`Map<String, String> uiToSrvFldMapList = new HashMap<String, String>();
uiToSrvFldMapList.put("0000$0000", "test"); // just an example
uiToSrvFldMapList.put("0000$0001", "description"); // just an example
uiToSrvFldMapList.put("0001$0000", "2test"); // just an example
uiToSrvFldMapList.put("0001$0001", "2description"); // just an example
String acctId = "0000"; // the account id string
if(uiToSrvFldMapList.containsKey(acctId +"$" + acctId)){
String sSrvFld = (String) uiToSrvFldMapList.get(acctId + "$" + acctId);
System.out.println("sSrvFld :: " +sSrvFld);
}`
This is a test program, which shows a way to achieve this functionality:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Test {
public static void main(String[] args) {
Map<String, String> uiToSrvFldMapList = new HashMap<String, String>();
uiToSrvFldMapList.put("acctId$accountId", "accid");
uiToSrvFldMapList.put("acctId$desc", "accdesc");
uiToSrvFldMapList.put("acctId$crncyCode", "currencyCode");
uiToSrvFldMapList.put("smthElse$smthElse", "smthElse");
List<String> valuesContainingKey = valuesContainingKeys(
uiToSrvFldMapList, "acctId");
// Returns if the key is contained
if (valuesContainingKey.isEmpty()) {
System.out.println("The key is not contained in the map");
} else {
System.out.println("The part of the key is in the map");
}
System.out
.println("All values, where the corresponding key contains the subkey: ");
for (String s : valuesContainingKey) {
System.out.println(s);
}
}
/**
*
* #param map
* Map containing the key-value pairs
* #param searchString
* A String used as a subkey, for which is searched if it is
* contained as a substring at the beginning of a key in the map
* #return List of all Values from the map, whose corresponding key contains
* searchString
*/
private static List<String> valuesContainingKeys(Map<String, String> map,
String searchString) {
List<String> containingKeys = new ArrayList<String>();
for (Entry<String, String> e : map.entrySet()) {
if (e.getKey().startsWith(searchString)) {
containingKeys.add(e.getValue());
}
}
return containingKeys;
}
}
Simply write the method valuesContainingKeys (not needed to be static) where you want this functionality. This method will return a list of all values, whose corresponding key contains the string you are looking for. Simply checking valuesContainingKey.isEmpty() will return if there is no value, for which the corresponding key begins with the searched key.
i have this
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Scanner;
import static java.lang.System.*;
public class Relatives
{
private Map<String,Set<String>> map;
public Relatives()
{
map = new TreeMap<String,Set<String>>();
}
public void setPersonRelative(String line)
{
String[] personRelative = line.split(" ");
String person = personRelative[0];
String relative = personRelative[1];
if(map.containsKey(person))
{
map.get(person).add(relative);
}
else
{
Set<String> relatives = new TreeSet<String>();
relatives.add(relative);
map.put(person,relatives);
}
}
/**
* Returns the String version of the set containing person's relatives
* (see last line of sample output)
* #param person the person whose relative set should be returned as a String
* #param the string version of person's relative set
*/
public String getRelatives(String person)
{
return map.keySet();
}
how can i return a map as a string and make it look like this
Bob is related to John Tom
Dot is related to Chuck Fred Jason Tom
Elton is related to Linh
i have tried typecasting although i didnt think it would work and parse which also didnt work and taht is what i have currently
I'd start with something like this:
public String getRelatives(String person)
{
StringBuilder sb = new StringBuilder();
sb.append(person);
sb.append(" is related to ");
for(String relative : map.get(person))
{
sb.append(relative);
sb.append(' ');
}
return sb.toString();
}
Or if you want to get a little more complicated, and handle the case where someone isn't related to anyone nicely:
public String getRelatives(String person)
{
StringBuilder sb = new StringBuilder();
sb.append(person);
Set<String> relatives = map.get(person);
if(relatives == null || relatives.isEmpty())
{
sb.append("is not related to anyone.");
}
else
{
sb.append(" is related to ");
for(String relative : relatives)
{
sb.append(relative);
sb.append(' ');
}
}
return sb.toString();
}
Provided you initialized the map correctly, and the sets that the map maps to, you should be fine.
Basically you create a StringBuilder (which may be overkill for this, but it's still good practice), stuff it with the things you want, then call its .toString() method.
The for loop just iterates over the contents of the Set, and stuffs the relative's name in the StringBuilder, along with a space character to space things out.
Other notes:
private Map<String,Set<String>> map;
public Relatives()
{
map = new TreeMap<String,Set<String>>();
}
Can just be:
private Map<String, Set<String>> map = new TreeMap<String, Set<String>>();
or, if using Java 7, simply:
private Map<String, Set<String>> map = new TreeMap<>();
(Note that this way, there's no need for an explicit constructor if it was just for initializing the map)
I'd also change this:
if(map.containsKey(person))
{
map.get(person).add(relative);
}
else
{
Set<String> relatives = new TreeSet<String>();
relatives.add(relative);
map.put(person,relatives);
}
To:
if(!map.containsKey(person))
{
map.put(person, new TreeSet<String>());
}
map.get(person).add(relative);
Simpler, and avoids redundancy