找到不同字符串组合的频率

时间:2016-08-11 14:56:23

标签: java arraylist hashmap permutation

我正在尝试在HashMap中找到不同字符串组合的频率。例如,假设我们有拥有各种购物清单的人。我们将每个购物清单存储在String类型的ArrayList中,并将其映射到一个人的名字。然后我们会有以下内容:

 {Megan=[Skim milk, Bananas, eggs, butter], 
  Neal=[Bananas, butter, Whole Milk, Pork Chops], 
  Ash=[Pork Loin, Pork Chops, Skim Milk, butter], 
  Amanda=[Skim milk, strawberries], 
  John=[Whole Milk, eggs, bananas]}. 

假设我将这些值存储在名为map的HashMap中。所以结合每一个,这是我到目前为止所尝试的:

  HashMap<ArrayList<String>, Integer> frequencies = new HashMap<>();
  // ......
  // Initialize the frequency map ..
  //....

  public void getMostCommon() {
    boolean hasElements;
    for (String person : map.keySet()) {
      Collections.sort(map.get(person));
      ArrayList<String> input = map.get(person);
      //Iterate over each list entry
      for (Map.Entry<String, ArrayList<String>> listEntry : map.entrySet()) {
        ArrayList<String> tempList = listEntry.getValue();
        ArrayList<String> matchingElem = getMatchingElements(input, tempList);
        hasElements = (temp != null);
        //Count frequency
        if (freq.containsKey(temp)) {
          if (hasElements) {
            freq.put(temp, freq.get(temp)+1);
          }
       } else {
          if (hasElements) {
            freq.put(temp, 1);
          }
        } 
      }
    }
   System.out.println(freq.toString());
  }

我使用辅助函数来检查是否有匹配的元素。这是:

     public ArrayList<String> getMatchingElements(ArrayList<String> a, 
                                                  ArrayList<String> b) {
       ArrayList<String> retVal = new ArrayList<>();
       if (a.size() >= b.size()) {
         for (int i=0; i < a.size(); i++) {
           for (int j=0; j < b.size(); j++) {
             if (a.get(i).contains(b.get(j))) {
                retVal.add(b.get(j));
                }
               }
             }
          } else {
            for (int i=0; i < b.size(); i++) {
              for (int j=0; j < a.size(); j++) {
                if (b.get(i).contains(a.get(j))) {
                   retVal.add(a.get(j));
                    }
                  }
                }
              }
          return retVal;
         }

这里的问题是我没有得到正确的频率数字。我相信它是这样的,因为将一个字段静态用于比较(第一个输入)并将其与从entrySet获取的tempList进行比较。我认为这里有重复计算,但我不知道如何解决这个问题。我希望最终输出存储最常见的n个项目,对于所有大于0的频率。这样的事情将是[脱脂牛奶,香蕉],[鸡蛋,香蕉]等的频率。我该怎么办?这个问题?

编辑:改述问题/目标。

1 个答案:

答案 0 :(得分:0)

你正在使它变得更加复杂。您需要做的就是创建另一个地图,其中您将购物清单项目作为字符串键,而整数值将是您遇到购物清单项目的次数。一开始它将是空的。

然后,您浏览每个用户的原始地图并遍历其列表。对于列表中的每个项目,您将检查它是否在您的新地图中。如果不存在,则将其添加为新密钥并将值设置为1.如果存在,则只需将值增加一。

完成后,您将拥有一张购物清单项目地图,其中包含了所有购物者列表中提及的次数。

Map<String, Integer> result = new HashMap<>();
for(String shopper : shppersListMap) {
  List<String> shoppingList = shppersListMap.get(shopper);
  for(String item : shoppingList) {
    if(reasult.containsKey(item)) {
      result.put(item, result.get(item) + 1);
    } else {
      result.put(item, 1);
    }
  }
}
return result;