Related
I have solved the problem but was unable to come up with the most efficient problem that passes all test cases. It times out in 5 test cases.
Determine sentences contain all of the words of a phrase
0: chris and jennifer had a fight this morning
1: chris went on a holiday
2: jennifer is in prison
Query Phrases are
0: chris jennifer
1: jennifer
2: prison
Goal is to find indexes of the matching sentences for each query or -1 if there are no matching sentence exists. Order of words does not matter.
Output :
0
0 2
2
i.e.
First query has matching words in sentence 0, second one in sentence 0 and 1. and so on.
Constraints
n: number of sentences
m: number of prases
n, m < 10^4
Number of words in any sentence or query phrase is in range [1-10]
Each word has at most 11 chars
No word appears in more than 10 sentences
Each word consists of upper and lower case alphabet only
Each word must match exactly - i.e. likes and like do not match.
Input Format:
3
chris and jennifer had a fight this morning
chris went on a holiday
jennifer is in prison
3
chris jennifer
jennifer
prison
each 3 represents number of sentences or queries.
The followings were what I tried...
1. My first solution :
Make HashMap per each sentence
For each splitted word in phrase :
2-1. check if all words exists in the sentence hashmap
2-2. If so store the index
2-3. If there is no matching sentences exist for all sentences, store -1.
Print result
let p = the largest number of words in a sentence
let k = the largest number of words in a query
Big O is O(npk)
public static void textQueries(List<String> sentences, List<String> queries) {
List<Map<String, Integer>> sentenceMaps = createMaps(sentences);
String results = queryMatcher(sentenceMaps, queries);
System.out.println(results);
}
private static String queryMatcher(List<Map<String, Integer>> sentenceMaps, List<String> queries) {
Map<String, Integer> wordCounter = new LinkedHashMap<>();
List<List<String>> results = new ArrayList<List<String>>();
for (String query : queries) {
List<String> result = new ArrayList<>();
for (int j = 0; j < sentenceMaps.size(); j++) {
if (isQueryFound(sentenceMaps.get(j), query, wordCounter)) {
result.add(j + "");
}
}
results.add(result);
}
return generateResultString(results);
}
/*
* StringBuilder used to reduce delays of calling multiple System.out.println();
*/
private static String generateResultString(List<List<String>> results) {
StringBuilder stringBuilder = new StringBuilder();
for (List<String> matchingSentenceIndexes : results) {
if (matchingSentenceIndexes.isEmpty()) {
stringBuilder.append("-1\n");
} else {
resultStringHelper(matchingSentenceIndexes, stringBuilder);
}
//stringBuilder.append("\n");
}
return stringBuilder.toString();
}
/*
* add " " for multiple indexes result
*/
private static void resultStringHelper(List<String> result, StringBuilder stringBuilder) {
for (int i = 0; i < result.size(); i++) {
stringBuilder.append(result.get(i));
if (i < result.size() - 1) {
stringBuilder.append(" ");
} else if (i == result.size() - 1) {
stringBuilder.append("\n");
}
}
}
private static boolean isQueryFound(Map<String, Integer> sentenceMap, String query, Map<String, Integer> wordCounter) {
String[] queryTokens = query.split(" ");
for (String queryToken : queryTokens) {
if (isMoreThan10Sentences(wordCounter, queryToken)) return false;
if (sentenceMap.containsKey(queryToken)) {
wordCounter.put(queryToken, wordCounter.getOrDefault(queryToken, 0) + 1);
} else {
return false;
}
}
return true;
}
private static boolean isMoreThan10Sentences(Map<String, Integer> wordCounter, String token) {
return wordCounter.getOrDefault(token, -1) > 10;
}
private static Map<String, Integer> initMap(String[] tokens) {
Map<String, Integer> map = new LinkedHashMap<>();
for (String token : tokens) {
map.put(token, 0);
}
return map;
}
private static List<Map<String, Integer>> createMaps(List<String> sentences) {
List<Map<String, Integer>> maps = new ArrayList<Map<String,Integer>>();
for (int i = 0; i < sentences.size(); i++) {
String[] tokens = sentences.get(i).split(" ");
maps.add(initMap(tokens));
}
return maps;
}
Timeout in the last 5 test cases.
For small test cases, the benchmark is the following on their online coding server:
Map creation time: 9.23954E-4
Query matching time: 3.85751E-4
Map generation is expensive.
2. My second try:
Similar logic but applied concurrency, as the platform supports up to 2 threads.
Multi-threading is done here :
1. Sentence -> Map generation (Concurrent map generation)
2. Query matching (Concurrent matching)
public static void textQueries(List<String> sentences, List<String> queries) {
List<Map<String, Integer>> sentenceMaps = createMaps(sentences);
startTime = System.nanoTime();
String results = queryMatcher(sentenceMaps, queries);
System.out.println(results);
private static String queryMatcher(List<Map<String, Integer>> sentenceMaps, List<String> queries) {
List<Future<String>> futures = new ArrayList<Future<String>>();
int threads = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(threads);
String[] results = new String[threads];
int length = queries.size() / threads;
for (int i = 0; i < threads; i++) {
int queryStart = length * i;
int queryEnd = length * (i+1);
if (i == threads -1 && queries.size() % threads != 0) queryEnd++;
Callable<String> worker = new QueryMatcher(sentenceMaps, queries, queryStart, queryEnd);
Future<String> submit = executor.submit(worker);
futures.add(submit);
}
for (int i = 0; i < futures.size(); i++) {
try {
results[i] = futures.get(i).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
String returnString = concaString(results);
executor.shutdown();
return returnString;
}
private static String concaString(String[] results) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < results.length; i++) {
stringBuilder.append(results[i]);
}
return stringBuilder.toString();
}
private static String generateResultString(List<List<String>> results) {
StringBuilder stringBuilder = new StringBuilder();
for (List<String> matchingSentenceIndexes : results) {
if (matchingSentenceIndexes.isEmpty()) {
stringBuilder.append("-1\n");
} else {
resultStringHelper(matchingSentenceIndexes, stringBuilder);
}
//stringBuilder.append("\n");
}
return stringBuilder.toString();
}
private static void resultStringHelper(List<String> result, StringBuilder stringBuilder) {
for (int i = 0; i < result.size(); i++) {
stringBuilder.append(result.get(i));
if (i < result.size() - 1) {
stringBuilder.append(" ");
} else if (i == result.size() - 1) {
stringBuilder.append("\n");
}
}
}
private static boolean isQueryFound(Map<String, Integer> sentenceMap, String query, Map<String, Integer> wordCounter) {
String[] queryTokens = query.split(" ");
for (String queryToken : queryTokens) {
if (isMoreThan10Sentences(wordCounter, queryToken)) return false;
if (sentenceMap.containsKey(queryToken)) {
wordCounter.put(queryToken, wordCounter.getOrDefault(queryToken, 0) + 1);
} else {
return false;
}
}
return true;
}
private static boolean isMoreThan10Sentences(Map<String, Integer> wordCounter, String token) {
return wordCounter.getOrDefault(token, -1) > 10;
}
private static boolean isQueryFound(Map<String, Integer> sentenceMap, String query) {
String[] queryTokens = query.split(" ");
//Map<String, Integer> duplicateChecker = new LinkedHashMap<String, Integer>();
for (String queryToken : queryTokens) {
if (sentenceMap.containsKey(queryToken)) {
//if (!duplicateChecker(duplicateChecker, sentenceMap, queryToken))
//return false;
} else {
return false;
}
}
return true;
}
/*
* this method checks for the case when there are duplicate words in query
* i.e. sentence containing 2 hello will return false of queries with 3 hello
*/
private static boolean duplicateChecker(Map<String, Integer> duplicateChecker, Map<String, Integer> sentenceMap, String queryToken) {
if (duplicateChecker.containsKey(queryToken)) {
if (duplicateChecker.get(queryToken) == 0) return false;
duplicateChecker.put(queryToken, duplicateChecker.get(queryToken) - 1);
} else {
duplicateChecker.put(queryToken, sentenceMap.get(queryToken) - 1);
}
return true;
}
private static List<Map<String, Integer>> createMaps(List<String> sentences) {
List<Map<String, Integer>> maps = new ArrayList<>();
int threads = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(threads);
List<Future<List<Map<String, Integer>>>> futures = new ArrayList<Future<List<Map<String, Integer>>>>();
int length = (sentences.size()) / threads;
for (int i = 0; i < threads; i++) {
int start = i * length;
int end = (i+1) * length;
if (i == threads - 1 && sentences.size() % threads != 0) end++;
List<String> splitSentence = new ArrayList(sentences.subList(start, end));
Callable<List<Map<String, Integer>>> worker = new MapMaker(splitSentence);
Future<List<Map<String, Integer>>> submit = executor.submit(worker);
futures.add(submit);
}
for (int i = 0; i < futures.size(); i++) {
try {
for (Map<String, Integer> map : futures.get(i).get()) {
maps.add(map);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
return maps;
}
private synchronized static Map<String, Integer> initMap(String[] tokens) {
Map<String, Integer> map = new LinkedHashMap<>();
for (String token : tokens) {
map.put(token, 0);
// map.put(token, map.getOrDefault(map.get(token), 1) + 1);
}
return map;
}
public static class MapMaker implements Callable<List<Map<String, Integer>>> {
private List<String> sentences;
#Override
public List<Map<String, Integer>> call() throws Exception {
List<Map<String, Integer>> maps = new ArrayList<Map<String,Integer>>();
for (int i = 0; i < sentences.size(); i++) {
String[] tokens = sentences.get(i).split(" ");
maps.add(initMap(tokens));
}
return maps;
}
public MapMaker(List<String> sentences) {
this.sentences = sentences;
}
}
public static class QueryMatcher implements Callable<String> {
private List<Map<String, Integer>> sentenceMaps;
private List<String> queries;
private int queryStart;
private int queryEnd;
#Override
public String call() throws Exception {
List<List<String>> results = new ArrayList<List<String>>();
for (int i = queryStart; i < queryEnd; i++) {
List<String> result = new ArrayList<>();
String query = queries.get(i);
for (int j = 0; j < sentenceMaps.size(); j++) {
if (isQueryFound(sentenceMaps.get(j), query)) {
result.add(j + "");
}
}
results.add(result);
}
return generateResultString(results);
}
public QueryMatcher(List<Map<String, Integer>> sentenceMaps, List<String> queries, int queryStart, int queryEnd) {
this.sentenceMaps = sentenceMaps;
this.queries = queries;
this.queryStart = queryStart;
this.queryEnd = queryEnd;
}
}
Although I hoped for some speedup for large test case, it still gave 5 test cases timeout.
And for small test cases, it increased map generation time due to additional overhead on creating pools.
Benchmark time:
Map time: 0.007669489
Query matching time: 3.22923E-4
3. My third solution - Coding the above in C++
I questioned whether it could be Java that gives the timeout.
The platform actually gives shorter computation time for C++, so to my suprise, it still gave same 5 timeouts.
4. My 4th approach Regex,
I knew it would be slower, but I still did in futile attempt.
The Big O is actually slower here, as I need to sort each sentences by words to avoid n! permutation of regex...
public static void textQueries(List<String> sentences, List<String> queries) {
stringSort(sentences);
stringSort(queries);
StringBuilder stringBuilder = new StringBuilder();
boolean isExist = false;
for (int index = 0; index < queries.size(); index++) {
String query = queries.get(index);
isExist = false;
for (int i = 0; i < sentences.size(); i++) {
if (Matcher(buildNaturalLanguage(query), sentences.get(i))) {
stringBuilder.append(i + " ");
isExist = true;
}
}
if (!isExist) stringBuilder.append("-1");
if (index != queries.size() - 1) stringBuilder.append("\n");
}
System.out.println(stringBuilder.toString());
}
private static void stringSort(List<String> strings) {
for (int i = 0; i < strings.size(); ++i) {
String string = strings.get(i);
String[] stringParts = string.split(" ");
StringBuilder stringBuilder = new StringBuilder();
Arrays.sort(stringParts);
for (int j = 0; j < stringParts.length; j++) {
stringBuilder.append(stringParts[j] + " ");
}
strings.set(i, stringBuilder.toString()); // sure I made it back to string for code cleaness but you can return String[] for efficiency.. But only minor improvement.
}
}
private static String buildNaturalLanguage(String query) {
// System.out.println("query " + query);
String[] stringParts = query.split(" ");
String regular = "(([a-zA-Z])*(\\s))*";
for (String word : stringParts) {
regular += word + "(\\s(([a-zA-Z])*(\\s))*)";
}
return regular;
}
private static boolean Matcher(String regular, String sentence) {
Pattern p = Pattern.compile(regular);
Matcher m = p.matcher(sentence);
return m.find();
}
Result :
Not only getting timeout, it is somehow causing error (wrong answer) on 2 additional undisclosed test cases.. I have no idea why..
Ω(nm^2 + plogp).. assuming regex matching is O(m)
I can only think of possibility of filtering some query or sentences before even runnning the main algorithm? (constraint : 10 max matching per word).
This constraint checking part is still implemented with my first and second solution however. So smarter filtering might be required.
The thing is I think the BCR - best conceivable rate is O(MNP), you would still need to go through each query and sentences, and also split them if not using regex.
I am totally lost here, how can I actually increase the speed further than this?
Many thanks in advance.
Maintain a HashMap that will map Strings to Set<Int>. The idea is to keep track of what sentences a given word appears in. We use a set instead of an array in order to support computing the intersection of two sets efficiently.
For each input sentence:
Tokenize it into words, and add the index of the current sentence to the Set corresponding to the current token.
For each query phrase:
Tokenize it into words.
Query for the Set of indices corresponding to each word
Take the intersection of all of these sets.
Time Complexity: Given that there are 10 words in each sentence, the cost of building the HashMap is O(10N log N). The cost of each query is O(10 * log(N)).
I have following idea that may speed up , it seems similar to what Rishav proposed:
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new FileInputStream("file.txt"));
int numberOfSentences = Integer.parseInt(sc.nextLine());
Set<Integer> sentences = new HashSet<Integer>();
Map<String, Set<Integer>> words2Sentences = new HashMap<String, Set<Integer>>();
for (int i = 0; i < numberOfSentences; i++) {
String words[] = sc.nextLine().split(" ");
for (int j = 0; j < words.length; j++) {
if (!words2Sentences.containsKey(words[j])) {
words2Sentences.put(words[j], new HashSet<Integer>());
}
words2Sentences.get(words[j]).add(i);
}
sentences.add(i);
}
int numberOfPhrases = Integer.parseInt(sc.nextLine());
List<Set<Integer>> phraseResults = new ArrayList<Set<Integer>>();
for (int i = 0; i < numberOfPhrases; i++) {
Set<String> phrases = new HashSet<String>(Arrays.asList(sc.nextLine().split(" ")));
Set<Integer> result = new HashSet(sentences);
for (String s : phrases) {
result.retainAll(words2Sentences.get(s));
}
phraseResults.add(result);
}
for (Set<Integer> set : phraseResults) {
for (Integer i : set) {
System.out.print(i);
}
System.out.println();
}
}
private static void printAllQeriesIndeicesInSentence(List<String> sentences,
List<String> queries) {
Map<Integer, List<String>> sentenceMap = new HashMap<>();
for(int i=0; i < sentences.size(); i++){
List<String> words = Arrays.asList(sentences.get(i).split("\\s+"));
sentenceMap.put(i, words);
}
for(String query: queries){
List<String> queryList = Arrays.asList(query.split("\\s+"));
for(Map.Entry<Integer, List<String>> e: sentenceMap.entrySet()){
List<String> wordsList = e.getValue();
if(wordsList.containsAll(queryList)){
System.out.print(e.getKey() + " ");
}
}
System.out.println();
}
}
This approach should work.
#include <bits/stdc++.h>
using namespace std;
vector<set<int>> getres(vector<string> sentences, vector<string> phrases, vector<set<int>> v){
map<string,set<int>> m;
map<string,set<int>> :: iterator itr;
for(int i=0;i<sentences.size();i++){
string temp = sentences[i];
temp.push_back(' ');
string word = "";
for(int j=0;j<temp.length();j++){
if(temp[j] == ' '){
itr = m.find(word);
if(itr == m.end()){
set<int> s;
s.insert(i);
m.insert({word,s});
}
else if(itr != m.end()){
itr->second.insert(i);
}
word = "";
}
else{
word.push_back(temp[j]);
}
}
}
// for(itr = m.begin();itr!= m.end();itr++){
// cout<<itr->first <<" ";
// for(auto f= itr->second.begin();f!= itr->second.end();f++){
// cout<<*f<<" ";
// }
// cout<<endl;
// }
for(int i=0;i<phrases.size();i++){
string temp = phrases[i];
temp.push_back(' ');
string word = "";
int flag = 0;
set<int> s1,s2,s3;
for(int j=0;j<temp.length();j++){
if(temp[j] == ' '){
// cout<<"yes";
itr = m.find(word);
if(itr == m.end()){
flag = 1;
break;
}
else if(itr != m.end()){
if(s1.empty()){
s1 = itr->second;
}
else{
set_intersection(s1.begin(),s1.end(),itr->second.begin(),itr->second.end(),inserter(s3,s3.begin()));
s1 = s3;
s3.clear();
if(s1.empty()){
flag = 1;
break;
}
}
// for(auto f=s1.begin();f!= s1.end();f++){
// cout<<*f<<" ";
// }
// cout<<endl;
}
word = "";
}
else{
word.push_back(temp[j]);
}
}
if(flag == 1){
s1.clear();
s1.insert(-1);
v[i] = s1;
flag = 0 ;
}
else{
v[i] = s1;
}
s1.clear();
s2.clear();
s3.clear();
}
return v;
}
int main() {
vector<string> sentences = {"chris and jennifer had a fight this morning", "chris went on a holiday", "jennifer is in prison"};
vector<string> phrases = {"chris jennifer", "jennifer", "prison"};
vector<set<int>> v(phrases.size());
v = getres(sentences,phrases,v);
for(int i=0;i<v.size();i++){
set<int> :: iterator itr;
for(itr = v[i].begin() ;itr != v[i].end();itr++){
cout<<*itr<<" ";
}
cout<<endl;
}
// cout<<"finish"<<endl;
}
The problem is that it must compare two Strings (example in a text file), and show the differences in it.
Should in the output also be printed out the equals Elements ?
Instead of using for loops, maybe there are different solutions to reach it.
How can it be done ?
Code
import java.util.ArrayList;
public class ParseTest {
String saR1 = "This is a Test for checking the content and a Test to compare it";
String saR2 = "This is the second Test for checking the seconds content and a second Test to compare it";
String diff1 = "";
String diff2 = "";
int o3;
int o4;
public static void main(String[] args) {
new ParseTest().parseMethod();
}
private void parseMethod() {
String[] sa1 = saR1.split("\\s");
String[] sa2 = saR2.split("\\s");
ArrayList<String> al1 = new ArrayList<String>();
ArrayList<String> al2 = new ArrayList<String>();
for(int o = 0; o<sa1.length; o++) {
al1.add(sa1[o]);
}
for(int o = 0; o<sa2.length; o++) {
al2.add(sa2[o]);
}
if(al1.size() <= al2.size()) {
for(int oi = 0; oi<al2.size()+al1.size(); oi++) {
for(o4 = 0; o4<al2.size(); o4++) {
for(o3 = 0; o3<al1.size(); o3++) {
if(al1.size() == al2.size() && al2.get(o4).equalsIgnoreCase(al1.get(o3))) {
al1.remove(al1.get(o3));
al2.remove(al2.get(o4));
}
if(al2.size() > al1.size() && al2.get(o4).equalsIgnoreCase(al1.get(o3))) {
al1.remove(al1.get(o3));
al2.remove(al2.get(o4));
}
}
}
}
}
for(String or1 : al1) {
diff1 += " " + or1;
} System.out.println("This is saR1 :" + saR1);
System.out.println("This is the difference in saR1 :" + diff1);
for(String or2 : al2) {
diff2 += " " + or2;
} System.out.println("This is saR2 :" + saR2);
System.out.println("This is the difference in saR2 :" + diff2);
}}
A possible solution :
package parsetest;
import java.util.ArrayList;
public class ParseTest {
String saR1 = "This is a Test for checking the content and a Test to compare it";
String saR2 = "This is the second Test for checking the seconds content and a second Test to compare it";
String diff1 = "";
String diff2 = "";
int o3;
int o4;
public static void main(String[] args) {
new ParseTest().parseMethod();
}
private void parseMethod() {
String[] sa1 = saR1.split("\\s"); // split into single words
String[] sa2 = saR2.split("\\s");
ArrayList<String> al1 = new ArrayList<String>(); // create ArrayList with more methods to manipulate, avaiable from the api
ArrayList<String> al2 = new ArrayList<String>();
for(int o = 0; o<sa1.length; o++) { // adding single elements of array[] to ArrayList
al1.add(sa1[o]);
}
for(int o = 0; o<sa2.length; o++) {
al2.add(sa2[o]);
}
if(al1.size() <= al2.size()) {
for(int oi = 0; oi<al2.size()+al1.size(); oi++) {
for(o4 = 0; o4<al2.size(); o4++) {
for(o3 = 0; o3<al1.size(); o3++) {
if(al1.size() == al2.size() && al2.get(o4).equalsIgnoreCase(al1.get(o3))) {
al1.remove(al1.get(o3));
al2.remove(al2.get(o4));
}
if(al2.size() > al1.size() && al2.get(o4).equalsIgnoreCase(al1.get(o3))) {
al1.remove(al1.get(o3));
al2.remove(al2.get(o4));
}
}
}
}
}
for(String or1 : al1) { // walking thru the arraylists with remaining elements and printing out results
diff1 += " " + or1;
} System.out.println("This is saR1 :" + saR1);
System.out.println("This is the difference in saR1 :" + diff1);
for(String or2 : al2) {
diff2 += " " + or2;
} System.out.println("This is saR2 :" + saR2);
System.out.println("This is the difference in saR2 :" + diff2);
}}
I am writing a very basic java program that calculates frequency of each word in a sentence so far i managed to do this much
import java.io.*;
class Linked {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Enter the sentence");
String st = br.readLine();
st = st + " ";
int a = lengthx(st);
String arr[] = new String[a];
int p = 0;
int c = 0;
for (int j = 0; j < st.length(); j++) {
if (st.charAt(j) == ' ') {
arr[p++] = st.substring(c,j);
c = j + 1;
}
}
}
static int lengthx(String a) {
int p = 0;
for (int j = 0; j < a.length(); j++) {
if (a.charAt(j) == ' ') {
p++;
}
}
return p;
}
}
I have extracted each string and stored it in a array , now problem is actually how to count the no of instances where each 'word' is repeated and how to display so that repeated words not get displayed multiple times , can you help me in this one ?
Use a map with word as a key and count as value, somthing like this
Map<String, Integer> map = new HashMap<>();
for (String w : words) {
Integer n = map.get(w);
n = (n == null) ? 1 : ++n;
map.put(w, n);
}
if you are not allowed to use java.util then you can sort arr using some sorting algoritm and do this
String[] words = new String[arr.length];
int[] counts = new int[arr.length];
words[0] = words[0];
counts[0] = 1;
for (int i = 1, j = 0; i < arr.length; i++) {
if (words[j].equals(arr[i])) {
counts[j]++;
} else {
j++;
words[j] = arr[i];
counts[j] = 1;
}
}
An interesting solution with ConcurrentHashMap since Java 8
ConcurrentMap<String, Integer> m = new ConcurrentHashMap<>();
m.compute("x", (k, v) -> v == null ? 1 : v + 1);
In Java 8, you can write this in two simple lines! In addition you can take advantage of parallel computing.
Here's the most beautiful way to do this:
Stream<String> stream = Stream.of(text.toLowerCase().split("\\W+")).parallel();
Map<String, Long> wordFreq = stream
.collect(Collectors.groupingBy(String::toString,Collectors.counting()));
import java.util.*;
public class WordCounter {
public static void main(String[] args) {
String s = "this is a this is this a this yes this is a this what it may be i do not care about this";
String a[] = s.split(" ");
Map<String, Integer> words = new HashMap<>();
for (String str : a) {
if (words.containsKey(str)) {
words.put(str, 1 + words.get(str));
} else {
words.put(str, 1);
}
}
System.out.println(words);
}
}
Output:
{a=3, be=1, may=1, yes=1, this=7, about=1, i=1, is=3, it=1, do=1, not=1, what=1, care=1}
Try this
public class Main
{
public static void main(String[] args)
{
String text = "the quick brown fox jumps fox fox over the lazy dog brown";
String[] keys = text.split(" ");
String[] uniqueKeys;
int count = 0;
System.out.println(text);
uniqueKeys = getUniqueKeys(keys);
for(String key: uniqueKeys)
{
if(null == key)
{
break;
}
for(String s : keys)
{
if(key.equals(s))
{
count++;
}
}
System.out.println("Count of ["+key+"] is : "+count);
count=0;
}
}
private static String[] getUniqueKeys(String[] keys)
{
String[] uniqueKeys = new String[keys.length];
uniqueKeys[0] = keys[0];
int uniqueKeyIndex = 1;
boolean keyAlreadyExists = false;
for(int i=1; i<keys.length ; i++)
{
for(int j=0; j<=uniqueKeyIndex; j++)
{
if(keys[i].equals(uniqueKeys[j]))
{
keyAlreadyExists = true;
}
}
if(!keyAlreadyExists)
{
uniqueKeys[uniqueKeyIndex] = keys[i];
uniqueKeyIndex++;
}
keyAlreadyExists = false;
}
return uniqueKeys;
}
}
Output:
the quick brown fox jumps fox fox over the lazy dog brown
Count of [the] is : 2
Count of [quick] is : 1
Count of [brown] is : 2
Count of [fox] is : 3
Count of [jumps] is : 1
Count of [over] is : 1
Count of [lazy] is : 1
Count of [dog] is : 1
From Java 10 you can use the following:
import java.util.Arrays;
import java.util.stream.Collectors;
public class StringFrequencyMap {
public static void main(String... args){
String[] wordArray = {"One", "One", "Two","Three", "Two", "two"};
var freq = Arrays.stream(wordArray)
.collect(Collectors.groupingBy(x -> x, Collectors.counting()));
System.out.println(freq);
}
}
Output:
{One=2, two=1, Two=2, Three=1}
You could try this
public static void frequency(String s) {
String trimmed = s.trim().replaceAll(" +", " ");
String[] a = trimmed.split(" ");
ArrayList<Integer> p = new ArrayList<>();
for (int i = 0; i < a.length; i++) {
if (p.contains(i)) {
continue;
}
int d = 1;
for (int j = i+1; j < a.length; j++) {
if (a[i].equals(a[j])) {
d += 1;
p.add(j);
}
}
System.out.println("Count of "+a[i]+" is:"+d);
}
}
package naresh.java;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class StringWordDuplicates {
static void duplicate(String inputString){
HashMap<String, Integer> wordCount = new HashMap<String,Integer>();
String[] words = inputString.split(" ");
for(String word : words){
if(wordCount.containsKey(word)){
wordCount.put(word, wordCount.get(word)+1);
}
else{
wordCount.put(word, 1);
}
}
//Extracting of all keys of word count
Set<String> wordsInString = wordCount.keySet();
for(String word : wordsInString){
if(wordCount.get(word)>1){
System.out.println(word+":"+wordCount.get(word));
}
}
}
public static void main(String args[]){
duplicate("I am Java Programmer and IT Server Programmer with Java as Best Java lover");
}
}
class find
{
public static void main(String nm,String w)
{
int l,i;
int c=0;
l=nm.length();String b="";
for(i=0;i<l;i++)
{
char d=nm.charAt(i);
if(d!=' ')
{
b=b+d;
}
if(d==' ')
{
if(b.compareTo(w)==0)
{
c++;
}
b="";
}
}
System.out.println(c);
}
}
public class wordFrequency {
private static Scanner scn;
public static void countwords(String sent) {
sent = sent.toLowerCase().replaceAll("[^a-z ]", "");
ArrayList<String> arr = new ArrayList<String>();
String[] sentarr = sent.split(" ");
Map<String, Integer> a = new HashMap<String, Integer>();
for (String word : sentarr) {
arr.add(word);
}
for (String word : arr) {
int count = Collections.frequency(arr, word);
a.put(word, count);
}
for (String key : a.keySet()) {
System.out.println(key + " = " + a.get(key));
}
}
public static void main(String[] args) {
scn = new Scanner(System.in);
System.out.println("Enter sentence:");
String inp = scn.nextLine();
countwords(inp);
}
}
Determine the frequency of words in a file.
File f = new File(fileName);
Scanner s = new Scanner(f);
Map<String, Integer> counts =
new Map<String, Integer>();
while( s.hasNext() ){
String word = s.next();
if( !counts.containsKey( word ) )
counts.put( word, 1 );
else
counts.put( word,
counts.get(word) + 1 );
}
The following program finds the frequency, sorts it accordingly, and prints it.
Below is the output grouped by frequency:
0-10:
The 2
Is 4
11-20:
Have 13
Done 15
Here is my program:
package com.company;
import java.io.*;
import java.util.*;
import java.lang.*;
/**
* Created by ayush on 12/3/17.
*/
public class Linked {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Enter the sentence");
String st = br.readLine();
st=st.trim();
st = st + " ";
int count = lengthx(st);
System.out.println(count);
String arr[] = new String[count];
int p = 0;
int c = 0;
for (int i = 0; i < st.length(); i++) {
if (st.charAt(i) == ' ') {
arr[p] = st.substring(c,i);
System.out.println(arr[p]);
c = i + 1;
p++;
}
}
Map<String, Integer> map = new HashMap<>();
for (String w : arr) {
Integer n = map.get(w);
n = (n == null) ? 1 : ++n;
map.put(w, n);
}
for (String key : map.keySet()) {
System.out.println(key + " = " + map.get(key));
}
Set<Map.Entry<String, Integer>> entries = map.entrySet();
Comparator<Map.Entry<String, Integer>> valueComparator = new Comparator<Map.Entry<String,Integer>>() {
#Override
public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
Integer v1 = e1.getValue();
Integer v2 = e2.getValue();
return v1.compareTo(v2); }
};
List<Map.Entry<String, Integer>> listOfEntries = new ArrayList<Map.Entry<String, Integer>>(entries);
Collections.sort(listOfEntries, valueComparator);
LinkedHashMap<String, Integer> sortedByValue = new LinkedHashMap<String, Integer>(listOfEntries.size());
for(Map.Entry<String, Integer> entry : listOfEntries){
sortedByValue.put(entry.getKey(), entry.getValue());
}
for(Map.Entry<String, Integer> entry : listOfEntries){
sortedByValue.put(entry.getKey(), entry.getValue());
}
System.out.println("HashMap after sorting entries by values ");
Set<Map.Entry<String, Integer>> entrySetSortedByValue = sortedByValue.entrySet();
for(Map.Entry<String, Integer> mapping : entrySetSortedByValue){
System.out.println(mapping.getKey() + " ==> " + mapping.getValue());
}
}
static int lengthx(String a) {
int count = 0;
for (int j = 0; j < a.length(); j++) {
if (a.charAt(j) == ' ') {
count++;
}
}
return count;
}
}
import java.io.*;
class Linked {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Enter the sentence");
String st = br.readLine();
st = st + " ";
int a = lengthx(st);
String arr[] = new String[a];
int p = 0;
int c = 0;
for (int j = 0; j < st.length(); j++) {
if (st.charAt(j) == ' ') {
arr[p++] = st.substring(c,j);
c = j + 1;
}
}
}
static int lengthx(String a) {
int p = 0;
for (int j = 0; j < a.length(); j++) {
if (a.charAt(j) == ' ') {
p++;
}
}
return p;
}
}
Simply use Java 8 Stream collectors groupby function:
import java.util.function.Function;
import java.util.stream.Collectors;
static String[] COUNTRY_NAMES
= { "China", "Australia", "India", "USA", "USSR", "UK", "China",
"France", "Poland", "Austria", "India", "USA", "Egypt", "China" };
Map<String, Long> result = Stream.of(COUNTRY_NAMES).collect(
Collectors.groupingBy(Function.identity(), Collectors.counting()));
Count frequency of elements of list in java 8
List<Integer> list = new ArrayList<Integer>();
Collections.addAll(list,3,6,3,8,4,9,3,6,9,4,8,3,7,2);
Map<Integer, Long> frequencyMap = list.stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
System.out.println(frequencyMap);
Note :
For String frequency counting split the string and convert it to list and use streams for count frequency => (Map frequencyMap)*
Check below link
String s[]=st.split(" ");
String sf[]=new String[s.length];
int count[]=new int[s.length];
sf[0]=s[0];
int j=1;
count[0]=1;
for(int i=1;i<s.length;i++)
{
int t=j-1;
while(t>=0)
{
if(s[i].equals(sf[t]))
{
count[t]++;
break;
}
t--;
}
if(t<0)
{
sf[j]=s[i];
count[j]++;
j++;
}
}
Created a simple easy to understand solution for this problem covers all test cases-
import java.util.HashMap;
import java.util.Map;
/*
* Problem Statement - Count Frequency of each word in a given string, ignoring special characters and space
* Input 1 - "To be or Not to be"
* Output 1 - to(2 times), be(2 times), or(1 time), not(1 time)
*
* Input 2 -"Star 123 ### 123 star"
* Output - Star(2 times), 123(2 times)
*/
public class FrequencyofWords {
public static void main(String[] args) {
String s1="To be or not **** to be! is all i ask for";
fnFrequencyofWords(s1);
}
//-------Supporting Function-----------------
static void fnFrequencyofWords(String s1) {
//------- Convert String to proper format----
s1=s1.replaceAll("[^A-Za-z0-9\\s]","");
s1=s1.replaceAll(" +"," ");
s1=s1.toLowerCase();
//-------Create String to an array with words------
String[] s2=s1.split(" ");
System.out.println(s1);
//-------- Create a HashMap to store each word and its count--
Map <String , Integer> map=new HashMap<String, Integer>();
for(int i=0;i<s2.length;i++) {
if(map.containsKey(s2[i])) //---- Verify if Word Already Exits---
{
map.put(s2[i], 1+ map.get(s2[i])); //-- Increment value by 1 if word already exits--
}
else {
map.put(s2[i], 1); // --- Add Word to map and set value as 1 if it does not exist in map--
}
}
System.out.println(map); //--- Print the HashMap with Key, Value Pair-------
}
}
public class WordFrequencyProblem {
public static void main(String args[]){
String s="the quick brown fox jumps fox fox over the lazy dog brown";
String alreadyProcessedWords="";
boolean isCount=false;
String[] splitWord = s.split("\\s|\\.");
for(int i=0;i<splitWord.length;i++){
String word = splitWord[i];
int count = 0;
isCount=false;
if(!alreadyProcessedWords.contains(word)){
for(int j=0;j<splitWord.length;j++){
if(word.equals(splitWord[j])){
count++;
isCount = true;
alreadyProcessedWords=alreadyProcessedWords+word+" ";
}
}
}
if(isCount)
System.out.println(word +"Present "+ count);
}
}
}
public class TestSplit {
public static void main(String[] args) {
String input="Find the repeated word which is repeated in this string";
List<String> output= (List) Arrays.asList(input.split(" "));
for(String str: output) {
int occurrences = Collections.frequency(output, str);
System.out.println("Occurence of " + str+ " is "+occurrences);
}
System.out.println(output);
}
}
Please try these it may be help for you
public static void main(String[] args) {
String str1="I am indian , I am proud to be indian proud.";
Map<String,Integer> map=findFrquenciesInString(str1);
System.out.println(map);
}
private static Map<String,Integer> findFrquenciesInString(String str1) {
String[] strArr=str1.split(" ");
Map<String,Integer> map=new HashMap<>();
for(int i=0;i<strArr.length;i++) {
int count=1;
for(int j=i+1;j<strArr.length;j++) {
if(strArr[i].equals(strArr[j]) && strArr[i]!="-1") {
strArr[j]="-1";
count++;
}
}
if(count>1 && strArr[i]!="-1") {
map.put(strArr[i], count);
strArr[i]="-1";
}
}
return map;
}
try this
public void count()throws IOException
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("enetr the strring");
String s = in.readLine();
int l = s.length();
int a=0,b=0,c=0,i,j,y=0;
char d;
String x;
String n[] = new String [50];
int m[] = new int [50];
for (i=0;i<50;i++)
{
m[i]=0;
}
for (i=0;i<l;i++)
{
d = s.charAt(i);
if((d==' ')||(d=='.'))
{
x = s.substring(a,i);
a= i+1;
for(j=0;j<b;j++)
{
if(x.equalsIgnoreCase(n[j]) == true)
{
m[j]++;
c = 1;
}
}
if(c==0)
{
n[b] = x;
m[b] = 1;
b++;
}
}
c=0;
}
for(i=0;i<b;i++)
{
for (j=0;j<b;j++)
{
if(y<m[j])
{
y=m[j];
}
}
if(m[i]==y)
{
System.out.println(n[i] + " : " + m[i]);
m[i]=0;
}
y=0;
}
}
For instance suppose I have the following String
String S = "5,a\n" +
"6,b\n" +
"9,a";
The format is always the same - one digit, then comma, then one character and then line end character.
For looping each row in String I use
for(String a : S.split("\\n")){}
I want to learn the character with highest amount, when grouped by character. For Instance, there is only one "b", so value is 6; whereas "a" has two lines, so its value is 5 + 9 = 14. Since 14 is maximum here, I want to find out "a" and 14 and save them in variables.
You can do something like below :
public static void main (String[] args) throws java.lang.Exception
{
String S = "5,a\n" +
"6,b\n" +
"9,a";
String[] lines = S.split("\\n");
Map<String, Integer> map = new HashMap<String, Integer>();
for( String t : lines )
{
String[] e = t.split(",");
Integer digit = Integer.parseInt(e[0]);
String c = e[1];
if ( map.get(c) != null )
{
Integer val = map.get(c);
val += digit;
map.put( c, val );
}
else
{
map.put( c, digit );
}
}
int max = 0;
String maxKey = null;
for ( String k : map.keySet() )
{
if ( map.get(k) > max )
{
max = map.get(k);
maxKey = k;
}
}
System.out.println("The maximum key is : " + maxKey );
System.out.println("The maximum value is : " + max );
}
Output is :
The maximum key is : a
The maximum value is : 14
Use a HashMap to store each pair, with the letter as the key. If the entry doesn't exist, put the first number. If it exists, get the entry and add the number, and then put the sum.
import java.util.HashMap;
import java.util.Map;
public class ParseTest {
public static void main(String[] args) {
String S = "5,a\n" + "6,b\n" + "9,a";
String maxKey = null;
int maxVal = 0;
Map<String, Integer> sums = new HashMap<>();
for (String a : S.split("\\n")) {
String[] split = a.split(",");
int value = Integer.parseInt(split[0]);
String key = split[1];
if (sums.containsKey(key)) {
sums.put(key, sums.get(key) + value);
} else {
sums.put(key, value);
}
if (sums.get(key) > maxVal) {
maxVal = sums.get(key);
maxKey = key;
}
}
System.out.println("Max key: " + maxKey + ", Sum: " + maxVal);
}
}
After finishing my answer, I found that many similar answers have been posted out :). Anyway, my solution:
public static void main(String[] args) {
String S = "5,a\n6,b\n9,a";
Map<String, Integer> map = new HashMap<String, Integer>();
String highestAmountChar = "";
int highestAmount = 0;
for (String str : S.split("\\n")) {
String[] amountChar = str.split(",");
if (map.get(amountChar[1]) == null) {
map.put(amountChar[1], Integer.parseInt(amountChar[0]));
} else {
map.put(amountChar[1], map.get(amountChar[1]) + Integer.parseInt(amountChar[0]));
}
if (highestAmount < map.get(amountChar[1])) {
highestAmount = map.get(amountChar[1]);
highestAmountChar = amountChar[1];
}
}
System.out.println("The character " + highestAmountChar + " has highest amount " + highestAmount);
}
You could use something like this without using HashMap or any collection for that matter
import java.util.Arrays;
public class Test {
public static void main(String args[]) {
String S = "5,a\n" +
"6,b\n" +
"9,a";
// Separate the string by number and letter
String[] separated = S.split("\\n");
// Create a new array to store the letters only
char[] letters = new char[separated.length];
// Write the letter
for (int i = 0; i < letters.length; i++) {
letters[i] = separated[i].charAt(2);
}
// Sort them haha
Arrays.sort(letters);
// And now find out which letter is repeated most
// Store the first letter
char previous = letters[0];
// Make it the most repeated one for now
char mostRepeated = letters[0];
int count = 1;
int maxCount = 1;
for (int i = 1; i < letters.length; i++) {
// since the array is sorted if the actual letter is the same as the previous one then keep counting
if (letters[i] == previous)
count++;
else {
if (count > maxCount) {
mostRepeated = letters[i - 1];
maxCount = count;
}
previous = letters[i];
count = 1;
}
}
char answer = count > maxCount ? letters[letters.length-1] : mostRepeated;
// Once you get the letter now just add all the numbers that goes with it
int sum = 0;
for (String s:separated) {
if (s.charAt(2) == answer) {
sum += Character.getNumericValue(s.charAt(0));
}
}
// Print the result by printing the letter and it sum
}
}
Is there any method for counting the occurrence of each item on an array?
Lets say I have:
String[] array = {"name1","name2","name3","name4", "name5"};
Here the output will be:
name1 1
name2 1
name3 1
name4 1
name5 1
and if I have:
String[] array = {"name1","name1","name2","name2", "name2"};
The output would be:
name1 2
name2 3
The output here is just to demonstrate the expected result.
List asList = Arrays.asList(array);
Set<String> mySet = new HashSet<String>(asList);
for(String s: mySet){
System.out.println(s + " " + Collections.frequency(asList,s));
}
With java-8, you can do it like this:
String[] array = {"name1","name2","name3","name4", "name5", "name2"};
Arrays.stream(array)
.collect(Collectors.groupingBy(s -> s))
.forEach((k, v) -> System.out.println(k+" "+v.size()));
Output:
name5 1
name4 1
name3 1
name2 2
name1 1
What it does is:
Create a Stream<String> from the original array
Group each element by identity, resulting in a Map<String, List<String>>
For each key value pair, print the key and the size of the list
If you want to get a Map that contains the number of occurences for each word, it can be done doing:
Map<String, Long> map = Arrays.stream(array)
.collect(Collectors.groupingBy(s -> s, Collectors.counting()));
For more informations:
Stream
Collectors
Hope it helps! :)
You could use a MultiSet from Google Collections/Guava or a Bag from Apache Commons.
If you have a collection instead of an array, you can use addAll() to add the entire contents to the above data structure, and then apply the count() method to each value. A SortedMultiSet or SortedBag would give you the items in a defined order.
Google Collections actually has very convenient ways of going from arrays to a SortedMultiset.
I wrote a solution for this to practice myself. It doesn't seem nearly as awesome as the other answers posted, but I'm going to post it anyway, and then learn how to do this using the other methods as well. Enjoy:
public static Integer[] countItems(String[] arr)
{
List<Integer> itemCount = new ArrayList<Integer>();
Integer counter = 0;
String lastItem = arr[0];
for(int i = 0; i < arr.length; i++)
{
if(arr[i].equals(lastItem))
{
counter++;
}
else
{
itemCount.add(counter);
counter = 1;
}
lastItem = arr[i];
}
itemCount.add(counter);
return itemCount.toArray(new Integer[itemCount.size()]);
}
public static void main(String[] args)
{
String[] array = {"name1","name1","name2","name2", "name2", "name3",
"name1","name1","name2","name2", "name2", "name3"};
Arrays.sort(array);
Integer[] cArr = countItems(array);
int num = 0;
for(int i = 0; i < cArr.length; i++)
{
num += cArr[i]-1;
System.out.println(array[num] + ": " + cArr[i].toString());
}
}
Using HashMap it is walk in the park.
main(){
String[] array ={"a","ab","a","abc","abc","a","ab","ab","a"};
Map<String,Integer> hm = new HashMap();
for(String x:array){
if(!hm.containsKey(x)){
hm.put(x,1);
}else{
hm.put(x, hm.get(x)+1);
}
}
System.out.println(hm);
}
It can be done in a very simple way using collections
please find the code below
String[] array = {"name1","name1","name2","name2", "name2"};
List<String> sampleList=(List<String>) Arrays.asList(array);
for(String inpt:array){
int frequency=Collections.frequency(sampleList,inpt);
System.out.println(inpt+" "+frequency);
}
Here the output will be like
name1 2
name1 2
name2 3
name2 3
name2 3
To avoid printing redundant keys use HashMap and get your desired output
I would use a hashtable with in key takes the element of the array (here string) and in value an Integer.
then go through the list doing something like this :
for(String s:array){
if(hash.containsKey(s)){
Integer i = hash.get(s);
i++;
}else{
hash.put(s, new Interger(1));
}
Count String occurence using hashmap, streams & collections
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class StringOccurence {
public static void main(String args[]) {
String[] stringArray = { "name1", "name1", "name2", "name2", "name2" };
countStringOccurence(stringArray);
countStringOccurenceUsingStream(stringArray);
countStringOccurenceUsingCollections(stringArray);
}
private static void countStringOccurenceUsingCollections(String[] stringArray) {
// TODO Auto-generated method stub
List<String> asList = Arrays.asList(stringArray);
Set<String> set = new HashSet<String>(asList);
for (String string : set) {
System.out.println(string + " --> " + Collections.frequency(asList, string));
}
}
private static void countStringOccurenceUsingStream(String[] stringArray) {
// TODO Auto-generated method stub
Arrays.stream(stringArray).collect(Collectors.groupingBy(s -> s))
.forEach((k, v) -> System.out.println(k + " --> " + v.size()));
}
private static void countStringOccurence(String[] stringArray) {
// TODO Auto-generated method stub
Map<String, Integer> map = new HashMap<String, Integer>();
for (String s : stringArray) {
if (map.containsKey(s)) {
map.put(s, map.get(s) + 1);
} else {
map.put(s, 1);
}
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " --> " + entry.getValue());
}
}
}
Here is my solution -
The method takes an array of integers(assuming the range between 0 to 100) as input and returns the number of occurrences of each element.
let's say the input is [21,34,43,21,21,21,45,65,65,76,76,76].
So the output would be in a map and it is: {34=1, 21=4, 65=2, 76=3, 43=1, 45=1}
public Map<Integer, Integer> countOccurrence(int[] numbersToProcess) {
int[] possibleNumbers = new int[100];
Map<Integer, Integer> result = new HashMap<Integer, Integer>();
for (int i = 0; i < numbersToProcess.length; ++i) {
possibleNumbers[numbersToProcess[i]] = possibleNumbers[numbersToProcess[i]] + 1;
result.put(numbersToProcess[i], possibleNumbers[numbersToProcess[i]]);
}
return result;
}
There are several methods which can help, but this is one is using for loop.
import java.util.Arrays;
public class one_dimensional_for {
private static void count(int[] arr) {
Arrays.sort(arr);
int sum = 0, counter = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[0] == arr[arr.length - 1]) {
System.out.println(arr[0] + ": " + counter + " times");
break;
} else {
if (i == (arr.length - 1)) {
sum += arr[arr.length - 1];
counter++;
System.out.println((sum / counter) + " : " + counter
+ " times");
break;
} else {
if (arr[i] == arr[i + 1]) {
sum += arr[i];
counter++;
} else if (arr[i] != arr[i + 1]) {
sum += arr[i];
counter++;
System.out.println((sum / counter) + " : " + counter
+ " times");
sum = 0;
counter = 0;
}
}
}
}
}
public static void main(String[] args) {
int nums[] = { 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 5, 5, 6 };
count(nums);
}
}
You can do it by using Arrays.sort and Recursion. The same wine but in a different bottle....
import java.util.Arrays;
public class ArrayTest {
public static int mainCount=0;
public static void main(String[] args) {
String prevItem = "";
String[] array = {"name1","name1","name2","name2", "name2"};
Arrays.sort(array);
for(String item:array){
if(! prevItem.equals(item)){
mainCount = 0;
countArray(array, 0, item);
prevItem = item;
}
}
}
private static void countArray(String[] arr, int currentPos, String item) {
if(currentPos == arr.length){
System.out.println(item + " " + mainCount);
return;
}
else{
if(arr[currentPos].toString().equals(item)){
mainCount += 1;
}
countArray(arr, currentPos+1, item);
}
}
}
You can use Hash Map as given in the example below:
import java.util.HashMap;
import java.util.Set;
/**
*
* #author Abdul Rab Khan
*
*/
public class CounterExample {
public static void main(String[] args) {
String[] array = { "name1", "name1", "name2", "name2", "name2" };
countStringOccurences(array);
}
/**
* This method process the string array to find the number of occurrences of
* each string element
*
* #param strArray
* array containing string elements
*/
private static void countStringOccurences(String[] strArray) {
HashMap<String, Integer> countMap = new HashMap<String, Integer>();
for (String string : strArray) {
if (!countMap.containsKey(string)) {
countMap.put(string, 1);
} else {
Integer count = countMap.get(string);
count = count + 1;
countMap.put(string, count);
}
}
printCount(countMap);
}
/**
* This method will print the occurrence of each element
*
* #param countMap
* map containg string as a key, and its count as the value
*/
private static void printCount(HashMap<String, Integer> countMap) {
Set<String> keySet = countMap.keySet();
for (String string : keySet) {
System.out.println(string + " : " + countMap.get(string));
}
}
}
This is a simple script I used in Python but it can be easily adapted. Nothing fancy though.
def occurance(arr):
results = []
for n in arr:
data = {}
data["point"] = n
data["count"] = 0
for i in range(0, len(arr)):
if n == arr[i]:
data["count"] += 1
results.append(data)
return results
you can find using HashMap with simple technic
public class HashMapExample {
public static void main(String[] args) {
stringArray();
}
public static void stringArray()
{
String[] a = {"name1","name2","name3","name4", "name5"};
Map<String, String> hm = new HashMap<String, String>();
for(int i=0;i<a.length;i++)
{
String bl=(String)hm.get(a[i]);
if(bl==null)
{
hm.put(a[i],String.valueOf(1));
}else
{
String k=hm.get(a[i]);
int j=Integer.valueOf(k);
hm.put(a[i],String.valueOf(j+1));
}
}
//hm.entrySet();
System.out.println("map elements are "+hm.toString());
}
}
You could use
for (String x : array){
System.out.println(Collections.frequency(array,x));
}
You can use HashMap, where Key is your string and value - count.
// An Answer w/o using Hashset or map or Arraylist
public class Count {
static String names[] = {"name1","name1","name2","name2", "name2"};
public static void main(String args[]) {
printCount(names);
}
public static void printCount(String[] names){
java.util.Arrays.sort(names);
int n = names.length, c;
for(int i=0;i<n;i++){
System.out.print(names[i]+" ");
}
System.out.println();
int result[] = new int[n];
for(int i=0;i<n;i++){
result[i] = 0;
}
for(int i =0;i<n;i++){
if (i != n-1){
for(int j=0;j<n;j++){
if(names[i] == names[j] )
result[i]++;
}
}
else if (names[n-2] == names[n-1]){
result[i] = result[i-1];
}
else result[i] = 1;
}
int max = 0,index = 0;
for(int i=0;i<n;i++){
System.out.print(result[i]+" ");
if (result[i] >= max){
max = result[i];
index = i;
}
}
}
}
public class Main
{
public static void main(String[] args) {
String[] a ={"name1","name1","name2","name2", "name2"};
for (int i=0;i<a.length ;i++ )
{
int count =0;
int count1=0;
for(int j=0;j<a.length;j++)
{
if(a[i]==a[j])
{
count++;
}
}
for(int j=i-1;j>=0 ;j--)
{
if(a[i]==a[j])
{
count1++;
}
}
if(count1 ==0)
{
System.out.println(a[i]+" occurs :"+count);
}
}
}
}
import java.util.HashMap;
import java.util.Map;
public class FrequencyUsingMap {
public static void main(String[] args) {
int a[] = {1,1,1,1,2,2,3,4,1};
int num = 0;
int maxfreq = 0;
int maxnum =0;
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i<a.length; i++){
num = a[i];
if(map.containsKey(num)){
int frq = map.get(num);
frq++;
map.put(num, frq);
if(frq>maxfreq){
maxfreq = frq;
maxnum = num;
}
}else{
map.put(num, 1);
}
}
System.out.println(map);
System.out.println("number "+ maxnum + " having max frequency " +maxfreq);
}
}
I wrote an easy solution for this, have a look:
public class Plus_Minus {
public static void main(String[] args) {
double [] x = { -4, 3, -9, -5, 4, 1 };
double p = 0;
double n = 0;
int z = 0;
for (int i = 0; i < x.length; i++) {
if (x[i] > 0) {
p += 1;
}
if (x[i] < 0) {
n += 1;
}
if (x[i] == 0) {
z += 1;
}
}
double ppi = p / x.length;
double pni = n / x.length;
int pzi = z / x.length;
System.out.println(ppi);
System.out.println(pni);
System.out.println(pzi);
}
}
public class test {
static String uniq[];
public static String[] convertWordArray(String str) {
str = str.toLowerCase();
String test[] = str.split(" ");
return test;
}
public static void findRepetitiveWordsinString(String str) {
String[] test =convertWordArray(str);
int len = test.length;
int count;
List<Integer> l = new ArrayList<>();
for (int i = 0; i < len; i++) {
count = 1;
for (int j = i + 1; j < len; j++) {
if (test[i].equals(test[j])) {
count++;
test[j] = "0";
}
}
if (count > 1 && test[i] != "0") {
System.out.println(test[i]);
l.add(i);
}
}
System.out.println("Repetitive words at index :" +l);
uniq = new String[l.size()];
for (int i = 0; i < l.size(); i++) {
uniq[i] = test[l.get(i)];
}
System.out.println("Number of words that are repeated: " + uniq.length);
}
public static void countMatches(String a[], String b[]) {
int count;
for (int i = 0; i < a.length; i++) {
count = 0;
for (int j = 0; j < b.length; j++) {
if (a[i].equals(b[j]))
count++;
}
if (count > 1) {
System.out.println("Repeating word is: " + a[i] + " and the repeating count is " + count);
}
}
}
public static void main(String[] args) {
String str;
Scanner scanner = new Scanner(System.in);
str = scanner.nextLine();
findRepetitiveWordsinString(str);
countMatches(uniq, convertWordArray(str));
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
public class MultiString {
public HashMap<String, Integer> countIntem( String[] array ) {
Arrays.sort(array);
HashMap<String, Integer> map = new HashMap<String, Integer>();
Integer count = 0;
String first = array[0];
for( int counter = 0; counter < array.length; counter++ ) {
if(first.hashCode() == array[counter].hashCode()) {
count = count + 1;
} else {
map.put(first, count);
count = 1;
}
first = array[counter];
map.put(first, count);
}
return map;
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] array = { "name1", "name1", "name2", "name2", "name2",
"name3", "name1", "name1", "name2", "name2", "name2", "name3" };
HashMap<String, Integer> countMap = new MultiString().countIntem(array);
System.out.println(countMap);
}
}
Gives you O(n) complexity.