Mam następujący realizację Kadane's algorithm rozwiązać problem maksymalnego subarray tablicy:Kadaně, aby znaleźć subarray z maksymalną sumą
public static decimal FindBestSubsequence
(this IEnumerable<decimal> source, out int startIndex, out int endIndex)
{
decimal result = decimal.MinValue;
decimal sum = 0;
int tempStart = 0;
List<decimal> tempList = new List<decimal>(source);
startIndex = 0;
endIndex = 0;
for (int index = 0; index < tempList.Count; index++)
{
sum += tempList[index];
if ((sum > result) ||
(sum == result && (endIndex - startIndex) < (index - tempStart)))
{
result = sum;
startIndex = tempStart;
endIndex = index;
}
else if (sum < 0)
{
sum = 0;
tempStart = index + 1;
}
}
return result;
}
zawiedzie, gdy używam sekwencję, która zaczyna się negatywna numer taki jak -1, 2, 3
, podając wynik 4, [0,2]
zamiast 5, [1,2]
.
Za życie mnie nie mogę znaleźć, gdzie jest błąd. Być może jest to defekt w konstrukcji algorytmu?
Z góry dziękuję.
Idealny. Po prostu wziąłem już istniejącą implementację w C, która wydawała się standardowa i przeniesiona do C#. Pozdrawiam wszystkie moje testy jednostkowe, więc uważam, że jest to najlepsza opcja. Dzięki! –
Dodatkowo, jeśli refactorujesz to, Iterowałbym IEnumerable bezpośrednio, nie ma potrzeby tworzenia kopii listy. I przekazywanie wielu argumentów "out" zwykle jest złą praktyką, niestandardowy typ zwrotu byłby lepszy. – Groo
Zgadzam się z kopią listy. Nie zgadzam się z tworzeniem nowego typu zwrotu, ponieważ w tym przypadku wydaje się oczywiste użycie indeksu początkowego i indeksu końcowego. –