我正在编写一个程序,该程序将打印构成最大和的元素。 我可以经历任何随机情况,但是当我的最大和为两组时,我的代码将失败。
我的代码:
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
得出。
我的完整代码工作正常,只是我无法在最终结果中得到两个结果。
我的错误日志:
线程“主”中的异常java.lang.IllegalStateException:复制 按键0 java.util.stream.Collectors.lambda $ throwingMerger $ 0(Collectors.java:133) 在java.util.HashMap.merge(HashMap.java:1254)在 java.util.stream.Collectors.lambda $ toMap $ 58(Collectors.java:1320)在 java.util.stream.ReduceOps $ 3ReducingSink.accept(ReduceOps.java:169) 在java.util.stream.IntPipeline $ 4 $ 1.accept(IntPipeline.java:250)在 java.util.stream.Streams $ RangeIntSpliterator.forEachRemaining(Streams.java:110) 在java.util.Spliterator $ OfInt.forEachRemaining(Spliterator.java:693) 在 java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) 在 java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) 在 java.util.stream.ReduceOps $ ReduceOp.evaluateSequential(ReduceOps.java:708) 在 java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 在 java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) 在Ideone.main(Ideone.java:27)的Ideone.maximumm(Ideone.java:47)
错误指向此行:result.add(maxOfSub);
任何帮助都会很好:)
答案 0 :(得分:2)
此错误的原因是,您在调用<key>
时重复了Stream.collect()
。请记住,此方法对流元素执行可变的约简操作。因此,当您拨打电话时:
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
在这里,您正在将<keys>
对象的Map
定义为<values>
方法定义的Entry<index, values>
的{{1}}。现在,当您在数据测试中拥有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>
要解决此问题,您只需像下面这样从corespondent 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
答案 1 :(得分:0)
您正在尝试从具有重复值的映射构建反向映射,这会导致键重复。您必须避免这种情况。
类似的地图
{0: 4, 1: 5, 2: 4, 3: 3}
不能转换为
{4: 0, 5: 1, 4: 2, 3: 3}
因为map.get(4)会是什么?是4还是0?
错误发生在
// 1)
IntStream.range(fromIndex, toIndex)
// 2)
.mapToObj(i -> new AbstractMap.SimpleEntry<>(i, numbers.get(i)))
// 3)
.collect(Collectors.toMap(
Map.Entry::getValue,
Map.Entry::getKey));
SimpleEntry ((0: numbers[0]), (1: numbers[1]), (2: numbers[2]))
3),然后尝试将其反转为地图:
{数字[0]:0,数字[1]:1 ...}
答案 2 :(得分:0)
您的值中有些重复<keys>
。看:
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));
您交换了代码key-value
中的Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)
,所以出现了重复的错误。