Въпрос относно последователност от числа в масив
Здравейте,
Решавайки една от задачите в глава 7. Масиви от "Въведение в програмирането със С#" се сблъсках трудност относно разбирането на логикатата й и не успях да я реша. Става въпрос за задача 9. Напишете програма, която намира последователност от числа, чиито сума е максимална.
Пример: {2, 3, -6, -1, 2, -1, 6, 4, -8, 8} = 11.
След като намерих едно от възможните й решения, се помъчих да открия логиката как точно се достига до крайния верен резултат, но без успех. Блъсках си главата, но нищо не мога да разбера, а изглежда доста кратък и лесен код.
Да поясня, всички въпроси и коментари, които имам към кода, са с примерните числа от масива в задачата.
int sum = 0, tempSum;
Console.Write("Enter array length: ");
int length = Int32.Parse(Console.ReadLine());
int[] arr = new int[length];
for (int i = 0; i < length; i++)
{
Console.Write("Enter {0} element: ", i);
arr[i] = Int32.Parse(Console.ReadLine());
}
for (int i = 0; i < length - 1; i++) // ако вземем числата в условието, то в началото i = 2.
{
tempSum = arr[i]; // следователно тук tempSum = 2.
for (int j = i + 1; j < length; j++) // ако вземем числата в условието, то в началото j = 3.
{
tempSum += arr[j]; // тук tempSum = 2 + 3 = 5.
if (tempSum > sum) //тук tempSum е 5, а не 2, ако правилно разсъждавам. 5 > 0, тъй като sum = 0.
{
sum = tempSum; // от тук следва, че sum = 5.
}
}
}
Console.WriteLine("Result is {0}. ", sum);
Ако коментарите са ми верни. То при следващата итерация на вътрешния for loop:
j = -6, tempSum = 2 + (-6) = -4, ако взема стойността на sum от предната итерация то би трябвало да е равен на 5 и няма да се изпълни if-a.
При следващо завъртане на вътрешния цикъл:
j = -1, tempSum = 2 + (-1) = 1, тук sum коя стойност взема, тази от предната итерация ли, т.е. няма как да го вземе тъй като не се е изпълнил if-a, значи взима от първата и е равен на 5, и пак няма да се изпълни if-a, защото 1 < 5?
Така продължавам до края на вътрешния цикъл, после външния се завърта и вече i = 3, tempSum = 3. А j = -6, tempSum = 3 + (-6) = -3 и вече не знам sum на какво е равно.
Просто много се обърках. Явно не мисля в правилната посока.
Ако някой може да ми обясни логиката на двата цикъла и как точно се извършват итерациите във вътрешния цикъл, външния и съответно какви са стойностите които приемат tempSum при i, tempSum при j и sum.
Благодаря предварително.
Здравей,
След като видях това, което сте ми писали ти и @puffed, и след като дебъгнах кода, нещата малко по малко се подредиха.
Мерси за помощта.
Междудругото, ако ти е интересно има доста ефективен алгоритъм(Kadane Algorithm) точно за тоя проблем . Не е може би за основи на програмирането , но всъщност не е толкова труден и като код е доста кратко. А е по-бърз тъй като му отнема N стъпки за да се изпълни, а не N^2.
При редица : -2 , 3 , 2 , -1
На всяка стъпка за всеки индекс се записва най-голямата стойност между стойноста на елемента или стойноста на елемента + текущата сума. Другото от алгоритъма е да направиш проверка текущата сума дали е > maxSum и ако е да присвоиш на maxSum стойноста на currentSum.
Като почнем от 1 до дължината ( отначало слагаме max и current да са array[0] т.е. - 2)
1ва итерация - currentSum = Math.Max(3 , 3 + (-2)) , записва се 3 , maxSum става 3
2ра итерация - currentSum = Math.Max(2 , 3 +2 ) , записва се 5 , maxSum става 5
3та итерация - currentSum = Math.Max(-1, 5 + (-1)) записва се 4 , maxSum си остава 5 защото 5 > 4
като цял код - http://pastebin.com/8hHVZ1Sk
Много съм приятно изненадан от наличието на този отговор тук, ако можех и повече плюсове щях да дам.
Като занимавка за любопитният читател, предлагам да се пробва да модифицира алгоритъмът да връща и началният и крайният индекс на максималната редица.