I have a problem statement as described below: Write a function that takes this input as a parameter and returns a data structure containing the number of
- clicks that were recorded on each domain AND each subdomain under it.
- For example, a click on "mail.yahoo.com" counts toward the totals for "mail.yahoo.com", "yahoo.com", and "com".
- (Subdomains are added to the left of their parent domain. So "mail" and "mail.yahoo" are not valid domains.
- Note that "mobile.sports" appears as a separate domain near the bottom of the input.)
Below is the input data:
String[] counts = {
"900,google.com",
"60,mail.yahoo.com",
"10,mobile.sports.yahoo.com",
"40,sports.yahoo.com",
"300,yahoo.com",
"10,stackoverflow.com",
"20,overflow.com",
"5,com.com",
"2,en.wikipedia.org",
"1,m.wikipedia.org",
"1,mobile.sports",
"1,google.co.uk"
};
Below is the expected output:
calculateClicksByDomain(counts) =>
com: 1345
google.com: 900
stackoverflow.com: 10
overflow.com: 20
yahoo.com: 410
mail.yahoo.com: 60
mobile.sports.yahoo.com: 10
sports.yahoo.com: 50
com.com: 5
org: 3
wikipedia.org: 3
en.wikipedia.org: 2
m.wikipedia.org: 1
mobile.sports: 1
sports: 1
uk: 1
co.uk: 1
google.co.uk: 1
I tried to write a solution for above problem statement:
Map<String, Integer> calculateClicksByDomainMap = new HashMap<>();
for(int i = 0; i < counts.length; i ) {
String[] seperateClickCountsAtComma = counts[i].split("\\,");
for(int j = 0; j < seperateClickCountsAtComma.length; j = 2) {
String clickCounts = seperateClickCountsAtComma[j];
String domain = seperateClickCountsAtComma[j 1];
calculateClicksByDomainMap.put(domain, Integer.parseInt(clickCounts));
}
}
for(Entry<String, Integer> domainCounts : calculateClicksByDomainMap.entrySet()) {
String domainName = domainCounts.getKey();
Integer domainCount = domainCounts.getValue();
splitStringOnOccurenceOfDot(domainName);
//System.out.println(domainName " " domainCount);
//String test[] = domainName.split("\\.");
//System.out.println(test[0] "=======" test[1] "-----");
}
public static String splitStringOnOccurenceOfDot(String domainName) {
if(!domainName.contains(".")) {
return domainName;
}
String[] subdomain = domainName.split("\\.");
domainName = subdomain[1];
System.out.println(domainName "===============" );
return splitStringOnOccurenceOfDot(domainName);
}
However, I'm not sure how to split the string using recursion. Can anyone help me what is the efficient way to write code in order to get the expected output? I there a way to solve it using recursion? Thank you for your time.
CodePudding user response:
The Map needs to ConcurrentHashMap, so that it allows concurrent updates.
First for loop with nesting can call the recursive method like below, might not need another for loop:
Map<String, Integer> calculateClicksByDomainMap = new ConcurrentHashMap<>();
for (final String count : counts) {
String[] separateClickCountsAtComma = count.split("\\,");
for (int j = 0; j < separateClickCountsAtComma.length; j = 2) {
Integer clickCount = Integer.parseInt(separateClickCountsAtComma[j]);
String domain = separateClickCountsAtComma[j 1];
calculateClicksByDomainMap.put(domain, clickCount);
splitStringOnOccurenceOfDot(domain.substring(domain.indexOf(".") 1), clickCount, calculateClicksByDomainMap);
}
}
Rather than returning a value, recursion add/update map itself.
public static void splitStringOnOccurenceOfDot(String domainName, Integer domainCount, Map<String, Integer> calculateClicksByDomainMap) {
if(calculateClicksByDomainMap.containsKey(domainName)) {
Integer newCount = calculateClicksByDomainMap.get(domainName) domainCount;
calculateClicksByDomainMap.put(domainName, newCount);
} else {
calculateClicksByDomainMap.put(domainName, domainCount);
}
if(domainName.contains(".")) {
splitStringOnOccurenceOfDot(domainName.substring(domainName.indexOf(".") 1), domainCount, calculateClicksByDomainMap);
}
}