将C++地图转换为Java地图

问题描述 投票:1回答:1

请看下面的cpp代码

string ans = "NO";
map<int,vi> idv ; //vi is vector of int

for(int i=1;i<=n;i++)
  idv.[arr[i]].push_back(i);

//frequecy >= 3
for(auto el:idv){
   if(el.ss.size() >= 3){
      ans = "YES";}
}

//non adjecent equal elements
for(auto el:idv)
{
   if(el.ss.size() == 2 && el.ss[0] != el.ss[1]-1)
    {
      ans = "YES";
    }
}

cout<<ans<<endl;

我的java翻译代码

                String ans = "NO";
                Map<Integer,List<Integer>> map = new HashMap<>();
                for (int i : arr) {
                    // map.merge(i,1,Integer::sum);
                    // map.put(i, )
                    List<Integer> temp = map.getOrDefault(i, new ArrayList<>());
                    temp.add(i);
                    map.put(i,temp);

                }

                //check for freq 3
                for (Map.Entry<Integer,List<Integer>> e : map.entrySet()) 
                {
                    if(e.getValue().size() == 3)     
                        ans ="YES";
                }

                //freq 2 and pos change 
                for (Map.Entry<Integer,List<Integer>> i : map.entrySet()) 
                {
                    if(i.getValue().size() == 2 && i.getValue().get(0) != i.getValue().get(1) - 1)
                        ans = "YES";    
                }

                System.out.println(ans);

输入 arr[]

1 2 1
1 2 2 3 2
1 1 2
1 2 2 1
1 1 2 2 3 3 4 4 5 5

产量

YES
YES
NO
YES
NO

但其不能正常工作的目的。请谁能告诉我如何更有效地做到这一点。另外,对于in first循环,我想我可以使用map.merge。如果有人知道如何做,请让我知道。谢谢✌️

java c++ c++11 java-8 c++14
1个回答
2
投票

首先,下面的片段将指数推送到向量的末尾,你需要在Java中采用同样的方法,而不需要增强for-each循环。

// C++
for (int i=1;i<=n;i++)
    idv.[arr[i]].push_back(i);

// Java
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i=0; i<arr.length; i++) {
    List<Integer> temp = map.getOrDefault(arr[i], new ArrayList<>());
    temp.add(i);
    map.put(arr[i],temp);

    // or shorter:
    // map.computeIfAbsent(arr[i], key->new ArrayList<>()).add(i);
}

其次,你在Java和C++中都迭代了两次映射,这是不需要的。使用相同的逻辑异构。在Java中,你可以只迭代值,如果你不需要键,就不需要迭代实际条目。

for (List<Integer> list: map.values()) {
    if (list.size() == 3 || (list.size() == 2 && list.get(0) != list.get(1) - 1)) {
        ans = "YES";
        break;        // no need to continue iteration, you have the answer
    }
}

整个过程可以更加简化,利用 帮助您创建 Map<Integer, List<Integer>>:

Map<Integer, List<Integer>>  map1 = IntStream.range(0, arr.length)
    .boxed()
    .collect(Collectors.groupingBy(i -> arr[i]));

String ans = "NO";
for (List<Integer> list: map.values()){
    if (list.size() == 3 || (list.size() == 2 && list.get(0) != list.get(1) - 1)) {
        ans = "YES";
        break;
    }
}

谢谢 @Holger,这可以更简单地使用 Collectors.collectingAndThen:

String ans = IntStream.range(0, arr.length)
    .boxed()
    .collect(Collectors.collectingAndThen(
        Collectors.groupingBy(i -> arr[i]),
        map -> map.values().stream()
            .filter(l -> l.size() == 3 || (l.size() == 2 && l.get(0) != l.get(1) - 1))
            .findAny().map(x -> "YES").orElse("NO")));
© www.soinside.com 2019 - 2024. All rights reserved.