Мне нужно суммировать три последовательных элемента массива при динамическом добавлении чисел к одному и тому же массиву и возвращать true, если сумма равна значению аргумента. Я уже написал приведенный ниже код, и все он возвращает требуемый результат, но он не работает для некоторых тестовых случаев (у меня нет точных тестовых случаев). Может ли кто-нибудь сказать мне, какой именно сценарий может привести к сбою моей программы?
import java.util.LinkedList;
import java.util.List;
public class Test {
List<Integer> mergeList = new LinkedList<Integer>();
List<List<Integer>> allList = new LinkedList<List<Integer>>();
List<Integer> tail;
int from = 0;
int to = 0;
public void addLast(int[] list) {
allList.removeAll(allList);
for(int i : list) {
mergeList.add(i);
}
if (mergeList.size() > 0) {
int j = 0;
while(to < mergeList.size()){
from = j;
to = j + 3;
tail = mergeList.subList(from, to);
j++;
allList.add(tail);
}
}
}
public boolean containsSum3(int sum) {
boolean retVal = false;
for (List<Integer> sum3List : allList) {
if (sum3List.stream().mapToInt(Integer::intValue).sum() == sum) {
retVal = true;
}
}
return retVal;
}
public static void main(String[] args) {
Test s = new Test();
s.addLast(new int[] { 1, 2, 3 });
System.out.println(s.containsSum3(6));
System.out.println(s.containsSum3(9));
s.addLast(new int[] { 4 });
System.out.println(s.containsSum3(9));
s.addLast(new int[] { 5, 2});
System.out.println(s.containsSum3(11));
s.addLast(new int[] { 0, -1 });
System.out.println(s.containsSum3(7));
System.out.println(s.containsSum3(2));
}
}
Выход:
true
false
true
true
true
false
Да, я тоже это заметил. Но он обеспечивает более 3 элементов.
Откуда вы знаете, что тестовые примеры содержат более 3 элементов? В вопросе говорится, что у вас нет тестовых сценариев.
" (У меня нет точных тестовых случаев) " Не помешает добавить те крайние случаи, о которых упоминал @sprinter... возвращение false, когда присутствует недостаточно элементов, - это хорошее начало, чтобы увидеть, проходите ли вы тестовые случаи.
Привет @DennisLLopis, да, я разберусь с его точкой зрения и посмотрю. Спасибо
Я сгенерировал большие случайные наборы целых чисел и не смог найти очевидных случаев, когда ваш код дает сбой, кроме недостаточного количества элементов. Между прочим, функция, которую я написал для проверки наличия в списке последовательных n элементов, суммирующих заданное значение, была следующей:
public static boolean containsSum(List<Integer> list, int sum, int n) {
return IntStream.range(0, list.size() - n + 1)
.anyMatch(i -> list.subList(i, i + n).stream()
.reduce(0, Integer::sum) == sum);
}
Я не вижу причин для вашего кода, который хранит весь список списков: компромисс между пространством и временем не имеет большого смысла. Я предлагаю вам упростить addLast
, чтобы просто добавить элементы в mergeList
. В вашем коде есть куча стилистических проблем, но я уверен, что вы решите их в свое время.
Код OP и ваш, очевидно, не распространяется на целочисленные переполнения.
Отличный момент. Я был бы удивлен, если бы это были неудачные тесты, но, тем не менее, хороший пикап.
Вот очевидный для вас: если в первый раз вы вызываете
addLast
массив с менее чем 3 элементами, вы получите исключениеIndexOutOfBounds
.