Home > Back-end >  Java - How to implement a data structure that contains the number of clicks that were recorded on ea
Java - How to implement a data structure that contains the number of clicks that were recorded on ea

Time:05-27

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);
    }
  }

  • Related