I stuck on a problem. I have a String array which is consist of String[]={"eat", "tea", "tan", "ate", "nat", "bat"} Now, I should segregated those word which have same letter on it and make a group. eat,tea,ate they have same letter in each word so this is a group. Group 2 should be tan,nat and Group3 should be bat. So I have to make a list of list to store those groups.
My approach:
To solve this problem I first find out the ascii values of each letter and then add those ascii values for a word. Like eat find out the ascii values of e,a,t and add them. I take this approach because if the letters are repeated in the words then they must have same ascii sum. After that I group them same Ascii sums and find out which words have those sums then they belongs to same group.
My progress
I find out ascii sums and put them in a hashmap. But then I could not group the same values. As I failed to group the ascii values I cannot find out the words.I have no clue how to proceed.
I also follow this posts
post1
post2
But there approach and my approach is not same. Also the questions are different from mine. I am discussing here about a different approach which is depend upon ASCII values.
My code:
public List<List<String>> groupAnagrams(String[] strs) {
ArrayList<Character>indivistr=new ArrayList<>();
ArrayList<Integer>dup=new ArrayList<>();
HashMap<Integer,Integer>mappingvalues=new HashMap<>();
for(int i=0;i<strs.length;i++){
int len=strs[i].length();
int sum=0;
for(int j=0;j<len;j++){
indivistr.add(strs[i].charAt(j));
int ascii=(int)strs[i].charAt(j);
sum=sum+ascii;
}
mappingvalues.put(i,sum);
}
}
One more approach
I transfer the map keys in a Arraylist and map values in a ArrayList. Something like that,
ArrayList<Integer>key_con=new ArrayList<
(mappingvalues.keySet());
ArrayList<Integer>val_con=new ArrayList<>(mappingvalues.values());
Then using two loops and put the same values into another list.
for(int k=0;k<val_con.size();k++){
for(int k1=k+1;k1<val_con.size();k1++){
if(val_con.get(k).equals(val_con.get(k1))){
dup.add(val_con.get(k1));
}
}
Now if I print dup output will be [314, 314, 314, 323] which is partially correct. It should be 314,314,314,323,323,311
This should get you started.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Main {
public static void main(String args[]) throws Exception {
String[] words ={"eat", "tea", "tan", "ate", "nat", "bat"};
for(List<String> list : groupAnagrams(words))
System.out.println(list);
}
public static List<ArrayList<String>> groupAnagrams(String[] words) {
List<ArrayList<String>> wordGroups = new ArrayList<ArrayList<String>>();
HashMap<Integer, ArrayList<String>> map = new HashMap<Integer, ArrayList<String>>();
for(String word : words) {
int sum = 0;
for(char c : word.toCharArray())
sum += c;
if(map.containsKey(sum))
map.get(sum).add(word);
else {
ArrayList<String> list = new ArrayList<String>();
list.add(word);
map.put(sum, list);
}
}
for(ArrayList<String> list : map.values())
wordGroups.add(list);
return wordGroups;
}
}
This program will work for small scale things such as this but consider the following input data:
{"a", "#!"}
The sum of these Strings are both 97.
Since you're using ASCII values to find anagrams you might run into a case such as this. This isn't a particularly pressing matter until you start messing around with lowercase letters and capitals. Easy fix for that is just a String.ToUpperCase() and map the symbols to huge numbers and you're good to go.
For posterity:
public class anagrams {
public static void main(String args[]) {
int numberOfAnagrams = 0;
String[] stringArray = {"eat", "tea", "tan", "ate", "nat", "bat", "plate", "knot"};
List<String> stringList = Arrays.asList(stringArray);
for(int i = 0; i < stringList.size() - 1; i++) {
for(int j = i + 1; j < stringList.size(); j++) {
if(isAnagram(stringList.get(i), stringList.get(j))) {
System.out.println(stringList.get(i) + " " + stringList.get(j));
numberOfAnagrams += 2;
}
}
}
System.out.println(numberOfAnagrams);
}
private static boolean isAnagram(String s1, String s2) {
// In order for two String to be anagrams, they must have the same length.
if(s1.length() != s2.length()) {
return false;
}
// If s2 does not contain even one of s1's chars return false.
for(int i = 0; i < s1.length(); i++) {
if(!s2.contains("" + s1.charAt(i))) {
return false;
}
}
return true;
}
}
Based on the asci approach I have made a working code
public static void main(String[] args) {
String[] values ={"eat", "tea", "tan", "ate", "nat", "bat"};
Map<Integer, List<String>> resultMap = new HashMap<Integer, List<String>>();
for (String value : values) {
char[] caharacters = value.toLowerCase().toCharArray();
int asciSum = 0;
for (char character : caharacters) {
asciSum = asciSum + (int)character;
}
System.out.println(asciSum);
if(resultMap.containsKey(asciSum)) {
resultMap.get(asciSum).add(value);
}else {
List<String> list = new ArrayList<String>();
list.add(value);
resultMap.put(asciSum, list);
}
}
System.out.println(resultMap);
}
This will give result
{323=[tan, nat], 311=[bat], 314=[eat, tea, ate]}
but if we encounter diff characters with same asci value sum like 10+11 = 20+1
below code will work where based on the sorted string we make the result map
public static void main(String[] args) {
String[] values ={"eat", "tea", "tan", "ate", "nat", "bat"};
Map<String, List<String>> resultMap = new HashMap<String, List<String>>();
for (String value : values) {
char[] caharacters = value.toLowerCase().toCharArray();
Arrays.sort(caharacters);
String sortedValue = new String(caharacters);
System.out.println(sortedValue);
if(resultMap.containsKey(sortedValue)) {
resultMap.get(sortedValue).add(value);
}else {
List<String> list = new ArrayList<String>();
list.add(value);
resultMap.put(sortedValue, list);
}
}
System.out.println(resultMap);
}
This will return
{aet=[eat, tea, ate], abt=[bat], ant=[tan, nat]}
I have fixed the comments and edits provided.
Here's my idea, first I would create a class that will store the original string and it's sorted version:
class Anagram {
String s;
String sorted;
}
Then I map the input to my list of Anagram:
List<Anagram> collect = Arrays.stream(strs)
.map(a -> new Anagram(a, Arrays.stream(a.split(""))
.sorted()
.reduce(String::concat).get()))
.collect(Collectors.toList());
Then I just group the obtained list by sorted string:
Map<String, List<Anagram>> groupBy = collect
.stream()
.collect(Collectors.groupingBy(Anagram::getSorted));
Now you have the lists with grouped anagrams, just extract from them the original string:
List<List<String>> result = new ArrayList<>();
for(List<Anagram> list : collect1.values()) {
List<String> myList = list.stream().map(Anagram::getS).collect(Collectors.toList());
result.add(myList);
}
Related
I have a question about how to return the list of sorted anagrams that are placed adjacently in the indexes of a single array. To clarify this:
Array sortedAnagrams:
sortedAnagrams[0] = asp
sortedAnagrams[1] = pas
sortedAnagrams[2] = code
sortedAnagrams[3] = coed
sortedAnagrams[4] = deco
sortedAnagrams[5] = France
From this example, it is clear that my indices "2","3", & "4" have the highest occurring anagram. How do I write a method where I can say these indices contain the highest occurring anagram?
I started of doing this but I don't know how it should continue.
public static String[] getLargestAnagramGroup(String[] stringList){
for (int i = 0; i < stringList.length; i++) {
int j = i + 1;
if (AnagramUtil.areAnagrams(stringList[i],stringList[j]) == true) {
j++;
} else {
i = j;
}
}
return null; // for now
public static void main(String[] args) {
String[] ListOfSortedAnagrams = new String[] {"asp", "pas", "code", "coed", "deco" , "France" }
System.out.print("Most occurring anagrams are: " + AnagramUtil.getLargestAnagramGroup(String[] ListOfSortedAnagrams));
Results:
Most occurring anagrams are: code, coed, deco
You could normalize strings for example sort chars in string and group them by this normalized value.
Have a look at :
public class Anagram {
public static void main(String[] args) {
String[] listAnagrams = new String[]{"asp", "pas", "code", "coed", "deco", "France"};
Map<String, List<String>> countMap = new HashMap<>();
for (String str : listAnagrams) {
String normalized = normalize(str);
List<String> strings = countMap.getOrDefault(normalized, new ArrayList<>());
strings.add(str);
countMap.put(normalized, strings);
}
Optional<Map.Entry<String, List<String>>> max = countMap.entrySet().stream()
.max(Comparator.comparingInt(entry -> entry.getValue().size()));
System.out.print("Most occurring anagrams are: " + max.get().getValue());
}
private static String normalize(String inputString){
char[] tempArray = inputString.toCharArray();
Arrays.sort(tempArray);
return new String(tempArray);
}
}
Output:
Most occurring anagrams are: [code, coed, deco]
PS: It could be refactored with stream group but I think it will be less readable.
Update:
Here is stream group version:
public class Anagram {
public static void main(String[] args) {
String[] listAnagrams = new String[]{"asp", "pas", "code", "coed", "deco", "France"};
Optional<Map.Entry<String, List<String>>> maxNormalised = Arrays.stream(listAnagrams)
.collect(Collectors.groupingBy(Anagram::normalize))
.entrySet().stream()
.max(Comparator.comparingInt(entry -> entry.getValue().size()));
System.out.print("Most occurring anagrams are: " + maxNormalised.get().getValue());
}
private static String normalize(String inputString){
char[] tempArray = inputString.toCharArray();
Arrays.sort(tempArray);
return new String(tempArray);
}
}
I am working on 'Grouping Anagrams'.
Problem statement: Given an array of strings, group anagrams together.
I could group the anagrams but I am not able to avoid the ones which are already grouped. I want to avoid duplicates. An element can only belong to one group. In my code, an element belongs to multiple groups.
Here is my code:
public class GroupAnagrams1 {
public static void main(String[] args) {
String[] input = {"eat", "tea", "tan", "ate", "nat", "bat"};
List<List<String>> result = groupAnagrams(input);
for(List<String> s: result) {
System.out.println(" group: ");
for(String x:s) {
System.out.println(x);
}
}
}
public static List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> result = new ArrayList<List<String>>();
for(int i =0; i < strs.length; i++) {
Set<String> group = new HashSet<String>();
for(int j= i+1; j < strs.length; j++) {
if(areAnagrams(strs[i], strs[j])) {
group.add(strs[i]);
group.add(strs[j]);
}
}
if(group.size() > 0) {
List<String> aList = new ArrayList<String>(group);
result.add(aList);
}
}
return result;
}
Here comes the method to check if two string are anagrams.
private static boolean areAnagrams(String str1, String str2) {
char[] a = str1.toCharArray();
char[] b = str2.toCharArray();
int[] count1 = new int[256];
Arrays.fill(count1, 0);
int[] count2 = new int[256];
Arrays.fill(count2, 0);
for(int i = 0; i < a.length && i < b.length; i++) {
count1[a[i]]++;
count2[b[i]]++;
}
if(str1.length() != str2.length())
return false;
for(int k=0; k < 256; k++) {
if(count1[k] != count2[k])
return false;
}
return true;
}
}
expected output:
group:
tea
ate
eat
group:
bat
group:
tan
nat
actual output:
group:
tea
ate
eat
group:
tea
ate
group:
tan
nat
The order in which the groups are displayed does not matter. The way it is displayed does not matter.
Preference: Please feel free to submit solutions using HashMaps but I prefer to see solutions without using HashMaps and using Java8
I also would recommend using java Streams for that. Because you don't want that here is another solution:
public static List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> result = new ArrayList<>();
for (String str : strs) {
boolean added = false;
for (List<String> r : result) {
if (areAnagrams(str, r.get(0))) {
r.add(str);
added = true;
break;
}
}
if (!added) {
List<String> aList = new ArrayList<>();
aList.add(str);
result.add(aList);
}
}
return result;
}
The problem in your solution is that you are moving each iteration one step ahead, so you just generate the not full complete group ["tea", "ate"] instead of ["bat"].
My solution uses a different approach to check if you have a group where the first word is an anagram for the searched word. if not create a new group and move on.
Because I would use Java Streams as I said at the beginning here is my initial solution using a stream:
List<List<String>> result = new ArrayList<>(Arrays.stream(words)
.collect(Collectors.groupingBy(w -> Stream.of(w.split("")).sorted().collect(Collectors.joining()))).values());
To generate the sorted string keys to group the anagrams you can look here for more solutions.
The result is both my provided solutions will be this:
[[eat, tea, ate], [bat], [tan, nat]]
I would have taken a slightly different approach using streams:
public class Scratch {
public static void main(String[] args) {
String[] input = { "eat", "tea", "tan", "ate", "nat", "bat" };
List<List<String>> result = groupAnagrams(input);
System.out.println(result);
}
private static List<List<String>> groupAnagrams(String[] input) {
return Arrays.asList(input)
// create a list that wraps the array
.stream()
// stream that list
.map(Scratch::sortedToOriginalEntryFor)
// map each string we encounter to an entry containing
// its sorted characters to the original string
.collect(Collectors.groupingBy(Entry::getKey, Collectors.mapping(Entry::getValue, Collectors.toList())))
// create a map whose key is the sorted characters and whose
// value is a list of original strings that share the sorted
// characters: Map<String, List<String>>
.values()
// get all the values (the lists of grouped strings)
.stream()
// stream them
.collect(Collectors.toList());
// convert to a List<List<String>> per your req
}
// create an Entry whose key is a string of the sorted characters of original
// and whose value is original
private static Entry<String, String> sortedToOriginalEntryFor(String original) {
char c[] = original.toCharArray();
Arrays.sort(c);
String sorted = new String(c);
return new SimpleEntry<>(sorted, original);
}
}
This yields:
[[eat, tea, ate], [bat], [tan, nat]]
If you want to eliminate repeated strings (e.g. if "bat" appears twice in your input) then you can call toSet() instead of toList() in your Collectors.groupingBy call, and change the return type as appropriate.
I have 2 lists one for the sentence one for the keywords. The idea is to check if the sentence have the keywords. and put them in a list for each sentence in order.
I am sorry if this is already duplicated here in advance.
List <String> sentence= new ArrayList <>();
sentence.add("this is a good dog");
sentence.add("cats drink milk");
sentence.add("Animals are beautiful creatures");
List <String> keyword= new ArrayList <>();
keyword.add("dog");
keyword.add("cats");
keyword.add("beautiful");
keyword.add("good");
keyword.add("are");
keyword.add("this");
keyword.add("milk");
My idea was to create 2 nested loops for each list:
for (int b = 0; b < sentence.size(); b++) {
for (int c = 0; c < keyword.size(); c++) {
if (sentence.get(b).contains(keyword.get(c))) {
System.out.println(keyword.get(c));
}
}
}
The output of this is:
dog
good
this
cats
milk
beautiful
are
The desired output would be:
[this,good,dog]
[cats,milk]
[are,beautiful]
So it is like getting all the existing keywords, in the order of the sentence,not related to keywords order.
and then group the existing keywords for each sentence, as in the order of existence.
Hope it is clear. Would really appreciate any ideas. doesnt have to follow the same method.
Iterate over your sentence list. For each sentence iterate over your keyword list. Add each found keyword found in a tempList, sort the tempList by the index of keyword in sentence and finally add each tempList to a list of lists. Example:
public static void main(String[] args) {
List <String> sentence= new ArrayList <>();
sentence.add("this is a good dog");
sentence.add("cats drink milk");
sentence.add("Animals are beautiful creatures");
List <String> keyword= new ArrayList <>();
keyword.add("dog");
keyword.add("cats");
keyword.add("beautiful");
keyword.add("good");
keyword.add("are");
keyword.add("this");
keyword.add("milk");
List<List<String>> result = new LinkedList<>();
for(String sen: sentence){
List<String> tempList = new ArrayList<>();
for(String key: keyword){
if(sen.contains(key)){
tempList.add(key);
}
}
tempList.sort(new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return sen.indexOf(o1) - sen.indexOf(o2) ;
}
});
result.add(tempList);
}
for(List<String> r : result){
System.out.println(r);
}
}
You need a slight modification in your looping
for (int i = 0; i < sentence.size(); i++) {
String[] matchArray = new String[sentence.get(i).split(" ").length];
for (int j = 0; j < keyword.size(); j++) {
if (sentence.get(i).contains(keyword.get(j))) {
matchArray[Arrays.asList(sentence.get(i).split(" ")).indexOf(keyword.get(j))] = keyword.get(j);
}
}
List<String> matchList = new ArrayList<String>();
for(String match: matchArray) {
if(match != null) {
matchList.add(match);
}
}
System.out.println(matchList);
}
For every sentence create an array with size same as the sentence (just to ensure size). Now when matches are found get the index of the match from sentence and add element to that particular index of the array. So at the end of keyword iteration you will have all matches in array with null values if some words are not matching.
Now declare a new List of String into which add the elements from array which are not null. At last print the list.
I think Map would be a good choice here. Just make sentences keys for the map and keywords as value. Following is the code for the same.
Map <String, ArrayList<String>> sentences= new HashMap<>();
sentences.put("this is a good dog", new ArrayList<>());
sentences.put("cats drink milk", new ArrayList<>());
sentences.put("Animals are beautiful creatures", new ArrayList<>());
List <String> keyword= new ArrayList <>();
keyword.add("dog");
keyword.add("cats");
keyword.add("beautiful");
keyword.add("good");
keyword.add("are");
keyword.add("this");
keyword.add("milk");
keyword.forEach(word -> sentences.entrySet().stream()
.filter(map -> map.getKey().contains(word)).
forEach(map -> sentences.computeIfAbsent(map.getKey(), key->new ArrayList<>()).add(word)));
sentences.forEach((key, value) -> System.out.println(value));
Try something like this:
for (String sen: sentence) {
System.out.print("[");
boolean first = true;
for (String word: sen.split("[\\s\\p{Punct}]")) {
if (keyword.contains(word)) {
if (first) {
first = false;
} else {
System.out.print(",");
}
System.out.print(word);
}
}
System.out.println("]");
}
this should do it, printing exactly in the format you requested :
for (int b = 0; b < sentence.size(); b++) {
String arr[] = sentence.get(b).split("\\s+");
List result = new ArrayList<>();
for (int c = 0; c < arr.length; c++ ) {
if (keyword.contains(arr[c]))
result.add(arr[c]);
}
System.out.println(result);
}
I would use the following :
for(String currentSentence : sentence) {
List<String> keywordsInSentence = new ArrayList<>();
for (String word : currentSentence.split("\\s+")) {
if (keyword.contains(word)) {
keywordsInSentence.add(word);
}
}
System.out.println(keywordsInSentence);
}
You can try it here.
(and I'd rename sentence into sentences or sentenceList and similarly for keyword, otherwise it's just confusing)
If you need to do anything more to the keywords than immediately displaying them, you could insert the keywordsInSentence lists into a Map<String, List<String>> you would value by replacing the System.out.println by map.put(currentSentence, keywordsInSentence).
So let's say I have a 32 character string like this:
GCAAAGCTTGGCACACGTCAAGAGTTGACTTT
My goal is to count all occurrences of specific substrings, such as 'AA' 'ATT' 'CGG' and so on. For this purpose, the 3rd through 5th characters above contain 2 occurrences of 'AA'. There are a total of 8 of these substrings, 6 that are 3 characters in length and 2 that are 2 characters in length, and I would want counts for all eight.
What would be the most efficient way of doing this in Java? My thoughts follow a couple lines:
Scan through character by character, checking and flagging for each substring. This seems intensive and inefficient.
Find some existing function that would do the work (not sure of efficiency of what function it would be, String.contains is a boolean, not a count).
Scan through the string multiple times, each sweep checking for a different substring.
The implementation of 3 is trivial, but 1 might give a few extra headaches and won't be very clean code.
I think this should answer your question.
The naive approach (checking for substring at each possible index)
runs in O(nk) where n is the length of the string and k is the length
of the substring. This could be implemented with a for-loop, and
something like haystack.substring(i).startsWith(needle).
More efficient algorithms exist though. You may want to have a look at
the Knuth-Morris-Pratt algorithm, or the Aho-Corasick algorithm. As
opposed to the naive approach, both of these algorithms behave well
also on input like "look for the substring of 100 'X' in a string of
10000 'X's.
Taken from stackoverflow.com/questions/4121875/count-of-substrings-within-string
One approach is to essentially code up an NFA (http://en.wikipedia.org/wiki/Nondeterministic_finite_automaton)
and just run your input on the NFA.
Here's my attempt at coding an NFA. You'd probably want to convert to a DFA first before running it so that you don't have to manage a bunch of branches. With the branches it's basically as slow as O(nk), whereas if you convert to a DFA it would be O(n)
import java.util.*;
public class Test
{
public static void main (String[] args)
{
new Test();
}
private static final String input = "TAAATGGAGGTAATAGAGGAGGTGTAT";
private static final String[] substrings = new String[] { "AA", "AG", "GG", "GAG", "TA" };
private static final int[] occurrences = new int[substrings.length];
public Test()
{
ArrayList<Branch> branches = new ArrayList<Branch>();
// For each character, read it, create branches for each substring, and pass the current character
// to each active branch
for (int i = 0; i < input.length(); i++)
{
char c = input.charAt(i);
// Make a new branch, one for each substring that we are searching for
for (int j = 0; j < substrings.length; j++)
branches.add(new Branch(substrings[j], j, branches));
// Pass the current input character to each branch that is still alive
// Iterate in reverse order because the nextCharacter method may
// cause the branch to be removed from the ArrayList
for (int j = branches.size()-1; j >= 0; j--)
branches.get(j).nextCharacter(c);
}
for (int i = 0; i < occurrences.length; i++)
System.out.println(substrings[i]+": "+occurrences[i]);
}
private static class Branch
{
private String searchFor;
private int position, index;
private ArrayList<Branch> parent;
public Branch(String searchFor, int searchForIndex, ArrayList<Branch> parent)
{
this.parent = parent;
this.searchFor = searchFor;
this.position = 0;
this.index = searchForIndex;
}
public void nextCharacter(char c)
{
// If the current character matches the ith character of the string we are searching for,
// Then this branch will stay alive
if (c == searchFor.charAt(position))
position++;
// Otherwise the substring didn't match, so this branch dies
else
suicide();
// Reached the end of the substring, so the substring was found.
if (position == searchFor.length())
{
occurrences[index] += 1;
suicide();
}
}
private void suicide()
{
parent.remove(this);
}
}
}
output for this example is
AA: 3
AG: 4
GG: 4
GAG: 3
TA: 4
Do you want to find all possible substrings that are longer than 1 character?
In that case one approach is to use HashMaps.
This example outputs:
{AA=3, TT=4, AC=3, CTT=2, CAA=2, GCA=2, CAC=2, AG=3, TTG=2, AAG=2, GT=2, CT=2, TG=2, GA=2, GC=3, CA=4}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Test {
public static void main(String[] args) {
String str = "GCAAAGCTTGGCACACGTCAAGAGTTGACTTT";
HashMap<String, Integer> map = countMatches(str);
System.out.println(map);
}
private static HashMap<String, List<Integer>> findOneLetterMatches(String str) {
ArrayList<Integer> list = new ArrayList<>();
for(int i = 0; i < str.length(); i++) list.add(i);
return extendMatches(str, list, 1);
}
private static HashMap<String, List<Integer>> extendMatches(String str, List<Integer> indices, int targetLength) {
HashMap<String, List<Integer>> map = new HashMap<>();
for(int index: indices) {
if(index+targetLength <= str.length()) {
String s = str.substring(index, index + targetLength);
List<Integer> list = map.get(s);
if(list == null) {
list = new ArrayList<>();
map.put(s, list);
}
list.add(index);
}
}
return map;
}
private static void addIfListLongerThanOne(HashMap<String, List<Integer>> source,
HashMap<String, List<Integer>> target) {
for(Map.Entry<String, List<Integer>> e: source.entrySet()) {
String s = e.getKey();
List<Integer> l = e.getValue();
if(l.size() > 1) target.put(s, l);
}
}
private static HashMap<String, List<Integer>> extendAllMatches(String str, HashMap<String, List<Integer>> map, int targetLength) {
HashMap<String, List<Integer>> result = new HashMap<>();
for(List<Integer> list: map.values()) {
HashMap<String, List<Integer>> m = extendMatches(str, list, targetLength);
addIfListLongerThanOne(m, result);
}
return result;
}
private static HashMap<String, Integer> countMatches(String str) {
HashMap<String, Integer> result = new HashMap<>();
HashMap<String, List<Integer>> matches = findOneLetterMatches(str);
for(int targetLength = 2; !matches.isEmpty(); targetLength++) {
HashMap<String, List<Integer>> m = extendAllMatches(str, matches, targetLength);
for(Map.Entry<String, List<Integer>> e: m.entrySet()) {
String s = e.getKey();
List<Integer> l = e.getValue();
result.put(s, l.size());
}
matches = m;
}
return result;
}
}
I want to get the smallest match of strings in the list. Though I'm successful doing so but the problem is i want to count that how many match counts have been made so:
List<String> mylist=new LinkedList<String>();
Set<String> result=new LinkedHashSet<String>();
mylist.add("interpreter");
mylist.add("interprete");
mylist.add("interpret");
mylist.add("developed");
mylist.add("develops");
mylist.add("develop");
mylist.add("interpret");
String small="";
Collections.sort(mylist);
Collections.reverse(mylist);
for(int i=0;i<mylist.size();i++)
{
small=mylist.get(i);
for(int j=i;j<mylist.size();j++)
{
if(small.contains(mylist.get(j)))
{
small=mylist.get(j);
}
}
result.add(small);
}
for (String string : result) {
System.out.println(string);
}
So that the output should be:
interpret=4
develop=4
Problem occurs with the following code i am trying:
List<String> mylist=new LinkedList<String>();
Set<String> result=new LinkedHashSet<String>();
mylist.add("interpreter");
mylist.add("interprete");
mylist.add("interpret");
mylist.add("developed");
mylist.add("develops");
mylist.add("develop");
mylist.add("interpret");
mylist.add("crawler");
mylist.add("crawl");
mylist.add("mobile");
mylist.add("mob");
mylist.add("juni");
mylist.add("junis");
Collections.sort(mylist);
Collections.reverse(mylist);
String small="";
int c=0;
for(int i=0;i<mylist.size();i++)
{
c+=1;
small=mylist.get(i);
for(int j=i;j<mylist.size();j++)
{
if(small.contains(mylist.get(j)))
{
small=mylist.get(j);
c+=1;
}
}
result.add(small);
}
for (String string : result) {
System.out.println(string+"="+c);
}
can somebody help me please!
Putting #jambriz's answer in your code:
1.Use a HashMap
HashMap<String, Integer> result= new LinkedHashMap<String, Integer>();
2.Instead of result.add(small); now, add the value in hashmap only if the value is new or the count is less than the previous count. Also, set c=0 here
if (!result.containsKey(small) || result.get(small) < c)
result.put(small, c);
c = 0;
3.At Last print your results:
for (String key : result.keySet())
System.out.println(key + ": " + result.get(key));
ok, first of all, your first code would print
interpret
develop
because you arenĀ“t counting anything
and it should be
interpret=4
develop=3
anyway.
The second block only has one counter 'c'. You should have one counter per each found word.
I would suggest using a Map of Strings and Integers. When the String is nonexistent you put(small,1) and when it exists you get the Integer and add one to it.
Let us know if that worked
(btw, there's no regex in your code, it shouldn't be tagged as such)
String[] smallestStrings; //this has "interpret", "develop"
int[] matches = new int[smallestStrings.length];
for (int i = 0; i < matches.length; i++) {
matches[i] = 0;
for (String s : mylist) if (s.contains(smallestStrings[i])) matches[i]++;
}