【问题标题】:HashMap<HashSet, Long> comparing strings in hashset and dividing themHashMap<HashSet, Long> 比较hashset中的字符串并划分它们
【发布时间】:2018-01-19 14:16:04
【问题描述】:

我正在发布以下任务的代码。 我有一个带有如下条目的哈希图:

HashMap<HashSet<String>, Long> mapping = new HashMap<>();

aaa.bb.cc.d, aaa.bb.cc, gg.hh.ee, aaa.bb, 34523
fff.kk.mmmm.ft, iiii.pp.cds, fff.kk, aaa.b, 4343
tpks.tt.po.d, tpks.tt.po, tpks.tt, aa.bb, 544670

运行代码后的结果应该如下:

1st entry key should go in nesteds_2 : aaa.bb.cc.d, gg.hh.ee 
2nd entry key should go in nesteds_3 : fff.kk.mmm.ft, iiii.pp.cds, aaa.b 
3rd entry key should go in nesteds_2 : tpks.tt.po.d, aa.bb 
etc.

HashSet 中的字符串都是按长度降序排列的。每当一个字符串包含另一个字符串时,只需要较长的那个。如果任何字符串包含在另一个字符串中,即 HashSet 中的字符串小于 4 - 它们应该从 HashSet 中删除并存储到相应的数组中。然后必须从哈希图中删除整个条目。

这是我到目前为止所得到的,但它似乎不起作用。知道为什么以及如何改进它吗?

public class Edit {
    public void edit(HashMap<HashSet<String>, Long> hm){
        List<String> li;
        String _1,_2,_3,_4;
        ArrayList<String> nesteds = new ArrayList<>();
        ArrayList<String> nesteds_2 = new ArrayList<>();
        ArrayList<String> nesteds_3 = new ArrayList<>();

        for(Iterator<Map.Entry<HashSet<String>, Long>> it = hm.entrySet().iterator(); it.hasNext(); ) {
            li = new ArrayList<String>((Collection<? extends String>) it.next().getKey());
            Comparator<String> stringLengthComparator = new Comparator<String>()
            {
                @Override
                public int compare(String o1, String o2)
                {
                    return Integer.compare(o2.length(), o1.length());
                }
            };

            Collections.sort(li, stringLengthComparator);
            _1 = li.get(0);
            _2 = li.get(1);
            _3 = li.get(2);
            _4 = li.get(3);


            if(_1.contains(_2)){
                li.remove(_2);
                if(_1.contains(_3)){
                    li.remove(_3);
                    if(_1.contains(_4)){
                        li.remove(_4);
                    }
                }
            }else{
                if(_1.contains(_3) || _2.contains(_3)){
                    li.remove(_3);
                    if(_2.contains(_4) || _2.contains(_4)){
                        li.remove(_4);
                    }
                }else{
                    if(_3.contains(_4) || _1.contains(_4) || _2.contains(_4)){
                        li.remove(_4);
                    }
                }
            }
            System.out.println(li.toString());
        }
    }
}

【问题讨论】:

  • “哈希集中的字符串都是按长度降序排列的。” 不,它们不是。 HashSets 中的对象没有一个有意义的顺序。
  • 是的,这就是为什么对于每个条目,我将每个哈希集放在一个数组列表中,并且在检查一个字符串是否包含另一个字符串时我正在使用排序的数组列表

标签: java string hashmap hashset


【解决方案1】:

您或许应该将代码拆分为方法。

例如,此方法将通过删除包含在另一个字符串中的字符串来简化字符串集合:

    private static List<String> simplify(Iterable<String> elms) {
        List<String> result = new ArrayList<>();
outer:
        for (String elm: elms) {
            int i = 0;
            while (i < result.size()) {
                String relm = result.get(i);
                if (relm.contains(elm)) {
                    continue outer;
                } else if (elm.contains(relm)) {
                    result.remove(i);
                } else {
                    ++i;
                }
            }
            result.add(elm);
        }
        return result;
    }

你的循环会变成:

    for(Map.Entry<HashSet<String>, Long> e: hm.entrySet()) {
        List<String> li = simplify(e.getKey());
        Collections.sort(li, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return Integer.compare(o2.length(), o1.length());
            }
        });
        System.out.println(li.toString());
    }

【讨论】:

  • 效果很好,谢谢。我还是新手,我倾向于用太多的代码让我的生活变得非常艰难,因为它可以像你一样写得非常优雅。干杯。
猜你喜欢
  • 2018-06-13
  • 1970-01-01
  • 2013-04-23
  • 1970-01-01
  • 2017-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多