- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Reference Question: Numbers which constitute the Maximum sum
我正在编写一个程序,该程序将打印构成最大总和的元素。我已经能够通过任何随机场景,但是当我的最大总和由两组组成时,我的代码会失败。
我的代码:
class Ideone {
public static void main(String[] args) throws java.lang.Exception {
Scanner reader = new Scanner(System.in);
int TestCases = reader.nextInt();
reader.nextLine();
String[] output = new String[TestCases];
String sss = "";
String ddd = "";
for (int k = 0; k < TestCases; k++) {
int noofELements = reader.nextInt();
reader.nextLine();
String[] al = reader.nextLine().split(" ");
List<Integer> numbers = Arrays.stream(al).map(Integer::valueOf).collect(Collectors.toList());
Ideone mm = new Ideone();
String maxi = mm.maximumm(numbers, ddd);
sss = sss.concat(maxi);
}
System.out.println(sss);
}
public String maximumm(List<Integer> numbers, String sss) {
int toIndex = 3, fromIndex = 0;
List<Integer> result = new ArrayList<>();
while (toIndex < numbers.size()) {
Map<Integer, Integer> map =
IntStream.range(fromIndex, toIndex).mapToObj(i -> new AbstractMap.SimpleEntry<>(i, numbers.get(i)))
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
// find max of sublist
int maxOfSub = numbers.subList(fromIndex, toIndex).stream().max(Integer::compareTo).get();
//update indexes
fromIndex = map.get(maxOfSub) + 2;
toIndex += fromIndex;
result.add(maxOfSub);
}
int lastMax = numbers.subList(fromIndex, numbers.size()).stream().max(Integer::compareTo).get();
if (lastMax > 0) {
result.add(lastMax);
}
result = result.stream().sorted(Integer::compareTo).collect(Collectors.toList());
//System.out.println(result);
sss = sss.concat(result.toString().replace(", ", "").replace("]", "").replace("[", ""));
return sss;
// return result.stream().reduce(0,Integer::sum);
}
}
例如,当我输入 4 5 4 3
时,非相邻元素的最大总和为 8 ,这将由 4 4
或 5 3
。
我的完整代码工作正常,只是我无法在最终结果中获得这两个结果。
我的错误日志:
Exception in thread "main" java.lang.IllegalStateException: Duplicate key 0 at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133) at java.util.HashMap.merge(HashMap.java:1254) at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320) at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250) at java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:110) at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at Ideone.maximumm(Ideone.java:47) at Ideone.main(Ideone.java:27)
错误指向这一行:result.add(maxOfSub);
任何帮助都会很好:)
最佳答案
此错误的原因是您有重复的 <key>
当您调用Stream.collect()
时。请记住,此方法对流元素执行可变归约操作。所以当你打电话时:
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
在这里,您定义 <keys>
的Map
对象为<values>
的Entry<index, values>
由 Stream.mapToObj()
定义方法。现在,在数据测试中,您有 4, 5, 4, 3
,这意味着,您正在尝试创建 <key>
号码 4
两次。因此,你得到了这个IllegalStateException
.
很简单,只要切换你的Map
的定义即可来自 <values, indexes>
的对象至<indexes, values>
在 Stream.collect()
称呼。 我该如何做到这一点?好吧,只需替换 Map.Entry::getValue
与 Map.Entry::getKey
反之亦然,如下所示:
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
此外,使用 IntStream.boxed()
有更好的等价物方法。此方法返回 Stream
由该流的元素组成,每个元素装箱为 Integer
。对我来说,这是转换 List
的最佳方式对象变成 Map
像这样的对象:
Map<Integer, Integer> map = IntStream
.range(fromIndex, toIndex)
.boxed()
.collect(Collectors.toMap(i -> i, i -> numbers.get(i) > 0 ? numbers.get(i) : 0));
请注意,我正在使用此表达式 i -> numbers.get(i) > 0 ? numbers.get(i) : 0
分配 <values>
Map
的目的。 为什么要这样做?因为,我们需要跟踪删除负数,所以我用零替换它们。 Stream.filter()
方法是一种替代方法,但是 Map
对象将不包含过滤后的元素。
但是,此修改将影响您更新索引的方式,因为现在映射值是 <values>
而不是<indexes>
如这一行所示:
fromIndex = map.getOrDefault(maxOfSub, toIndex - 1) + 2;
要解决此问题,您只需转换获取 <index>
来自通讯员<value>
像这样:
fromIndex = IntStream
.range(fromIndex, toIndex)
.filter(i -> map.get(i).equals(maxOfSub))
.findFirst()
.orElse(toIndex - 1) + 2;
现在,以上信息只能解决IllegalStateException
。然而,我发现还有另一个错误。如果我使用这个数字数组 1, 9, 1, 7, 7, 5, 4, 1, 6
,非相邻数字的最大和应为 [9 + 7 + 5 + 6] = 27
但你的代码得到 [9 + 7 + 6] = 22
。所以我试图在这里找到解决方案:
public class Ideone
{
public static void main(String[] args)
{
// List<Integer> numbers = Arrays.asList(4, 5, 4, 3);
// List<Integer> numbers = Arrays.asList(1, 9, 1, 7, 7, 5, 4, 1, 6);
List<Integer> numbers = Arrays.asList(-1, 7, 8, -5, 4, 9, -2, 3);
String sss = "";
String ddd = "";
Ideone mm = new Ideone();
List<List<Integer>> maxi = mm.findMaxSumNonAdjacentStream(numbers, numbers.size());
System.out.println(Collections.singletonList(maxi));
}
public List<List<Integer>> findMaxSumNonAdjacentStream(List<Integer> numbers, int size)
{
int fromIndex = 0;
Map<Integer, Integer> maxSumMap = IntStream
.range(fromIndex, size)
.boxed()
.collect(Collectors.toMap(i -> i, i -> numbers.get(i) > 0 ? numbers.get(i) : 0));
Map<Integer, List<Integer>> indexMap = IntStream
.range(fromIndex, size)
.mapToObj(i -> new AbstractMap.SimpleEntry<>(i, Collections.singletonList(numbers.get(i))))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
maxSumMap.replace(1, Math.max(numbers.get(1), numbers.get(0)));
List<Integer> maxValList = maxSumMap
.entrySet()
.stream()
.filter(entry -> entry.getKey() > 1)
.map(entry -> {
int index = entry.getKey();
int prevOne = index - 1;
int prevTwo = index - 2;
int prevValOne = maxSumMap.getOrDefault(prevOne, 0);
int prevValTwo = maxSumMap.getOrDefault(prevTwo, 0);
int maxVal = Math.max(prevValOne, prevValTwo + entry.getValue());
boolean exclude = prevValOne > (prevValTwo + entry.getValue());
List<Integer> elements = new ArrayList<>();
if (prevValOne > 0 && exclude) {
elements = new ArrayList<>(indexMap.get(prevOne));
} else if (prevValTwo > 0 && !exclude) {
elements = new ArrayList<>(indexMap.get(prevTwo));
}
if (!exclude) {
elements.add(entry.getValue());
elements = elements.stream().sorted(Integer::compareTo).collect(Collectors.toList());
}
maxSumMap.replace(index, maxVal);
indexMap.replace(index, elements);
return index;
})
.collect(Collectors.toList());
Integer max = maxValList
.stream()
.mapToInt(v -> v)
.max().orElseThrow(NoSuchElementException::new);
int lastMax = maxValList.stream().max(Integer::compareTo).orElse(-1);
Integer maxVal = maxSumMap.get(max);
List<Integer> result = maxSumMap
.entrySet()
.stream()
.filter(entry -> entry.getValue().equals(maxVal))
.map(i -> i.getKey())
.collect(Collectors.toList());
Predicate<Map.Entry<Integer, List<Integer>>> containMaxList =
mapEntry -> result.contains(mapEntry.getKey());
return indexMap.entrySet()
.stream()
.filter(containMaxList)
.map(i -> i.getValue())
.collect(Collectors.toList());
}
}
关于java - 非法状态异常 : "Duplicate key" for Collectors. toMap(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56230537/
以下面的列表为例: List input = List.of("FOO", "FOO", "FOO", "FOO", "FOO", "BAR", "BAR", "BAZ", "BAZ", "BAZ",
我有一个类似于下面的类 MyObject . public class MyObject { private String key; // not unique. multiple objec
我想获取按频率键控的数组值频率图。我能够得到相反的 - 按值键控的 map 。尝试切换参数,但 grouping by 不接受 Collector 作为第一个参数。 另一个问题,如何将 Map 实现更
我是 Java 8 Stream API 的新手,但我想用它来解决以下问题。假设我有一个名为 InputRecord 的 POJO,其中包含 name、fieldA 和 fieldB 属性,这些属性可
基准测试在 intel core i5, Ubuntu 下运行 java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.
我尝试使用流和收集器对值进行分组。我有我必须拆分的字符串列表。 我的数据: List stringList = new ArrayList<>(); stringList.add("Key:1,2,3
我想创建一个 Map来自 List的 Points并在映射中使用相同的 parentId 映射列表中的所有条目,例如 Map> . 我用了Collectors.toMap()但它没有编译: Map>
我已经实现了以下示例: Map> map = events.getItems().stream() .collect(Collectors.groupingBy(Event::getS
这个问题在这里已经有了答案: java 8 Collector is not a functional interface, who can tell why? (2 个回答) Java8: Usin
我想通过 Java 8 Stream 和 Collector 接口(interface)将 Map 转换为 ConcurrentHashMap,然后是我可以使用的两个选项。 第一个: Map mb =
如果我有一个对象列表(~200 个元素),只有几个唯一对象(~20 个元素)。 我只想拥有独特的值(value)。之间list.stream().collect(Collectors.toSet())
对于下面开发的 Java 8 代码,我收到以下错误。在此示例中,尝试将 Dish Name 的所有名称连接到一个变量中。使用下面的代码我得到了这个 "The method collect(Collec
我正在尝试使用rook在kubernetes集群上配置ceph,我已经运行了以下命令: kubectl apply -f common.yaml kubectl apply -f operator.y
这是我的流: Stream> futureStream = IntStream .iterate(1, n -> n n++) .mapToObj(pageNumber -> thi
Collector.of(Supplier 供应商、BiConsumer 累加器、BinaryOperator 组合器、Function 完成器、Characterstics...) Coll
按照常规思维,往一个map里put一个已经存在的key,会把原有的key对应的value值覆盖,然而通过一次线上问题,发现Java8中的Collectors.toMap反其道而行之,它默认给抛异常,
我想通过基于 LocalDateTime 的集合进行分组,但我只想获取小时,而不是分钟、秒... .collect(Collectors.groupingBy(cp -> getUpdateLocal
这个问题在这里已经有了答案: What is the point of "final class" in Java? (24 个答案) 关闭 3 年前。 为什么 Collectors 类在 Java
我有一个College具有嵌套静态类的类 Dept 学院 class College { private String collegeName; private Dept dept; public D
在Java库源代码中,Collectors#toList方法的定义如下: public static Collector> toList() { return new CollectorIm
我是一名优秀的程序员,十分优秀!