Algorytm Kadane z początkiem i końcem ciągu o największej sumie

0

Cześć,

Algorytm Kadane pozwala na znalezienie w jakiejś tablicy spójnej podtablicy o największej sumie elementów i zwróceniu tej sumy.
np. przy tablicy takiej int[] tab = {31, -41, 59, 26, -53, 58, 97, -93, -23, 84}; zwróci sumę ciągu 187.
Chciałem ten algorytm rozbudować tak, żeby pokazywał też wyraz początkowy i wyraz końcowy tej podtablicy. W powyższym przypadku byłyby to wyrazy o nr 2(59) i 6(97).
Ale coś nie działa. Czy ktoś wie co trzeba zmienić w poniższym kodzie, żeby zaczęło działać poprawnie? Obecnie pokazuje mi p=0 i k=0.

package com.company;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Scanner;

public class Main {
    static int Kadane(int tab[]) {
        int sumaMax = tab[0];
        int sumaLoc = tab[0];
        int size = tab.length;
        int p = 0;
        int k = 0;
        int licznik = 0;

        for (int i = 1; i < size; i++) {
            sumaLoc = Math.max(tab[i], sumaLoc + tab[i]);
            if (tab[i] > (sumaLoc + tab[i])) {
                p = i;
                k = i;
                licznik = 0;
            }
            if (tab[i] <= (sumaLoc + tab[i])) {
                licznik++;
                p = i - licznik;
                k = i;
            }

            sumaMax = Math.max(sumaMax, sumaLoc);
            if (sumaLoc > sumaMax) {
                p = i;
                k = i;
                licznik = 0;
            }
            if (sumaLoc <= sumaMax) {
                licznik++;
                p = i - licznik;
                k = i;
            }
        }
        return sumaMax;
    }
    
    public static void main (String[]args) throws FileNotFoundException {
        int n = 10;
        int[] tab = {31, -41, 59, 26, -53, 58, 97, -93, -23, 84};

        int p = 0;
        int k = 0;
      

        System.out.println(Kadane(tab));
        System.out.println("Początek przedziału to: p = " + p);
        System.out.println("Początek przedziału to: k = " + k);
    }
}
4

Zwróć uwagę na ten fragment:

int p = 0; //tu ustawiamy p na zero i tak już zostanie
int k = 0;
      

System.out.println(Kadane(tab));
System.out.println("Początek przedziału to: p = " + p);
System.out.println("Początek przedziału to: k = " + k);

zmienne p i k w main - to zupełnie inne zmienne niż p i k w funkcji Kadane .
One się tak samo nazywają, ale nie mają nic ze sobą wspólnego - to, że są ustawiane w Kadane nie zmienia magidznie ich wartości w main
musisz je odpowiednio zwrócić/przekazać.

jak to rozwiązać? Trzeba je zwrócić jako wynik

//dopisz na początku taką definicję rekordu
record Result( int sumaMax, int p, int k) {}

//zmodyfikuj definicję metody
static Result Kadane(int tab[]) {
...

//zwróć rekord (w kadane)
return new Result(sumaMax, p, k);

//na koniec w main:
//możesz wywalić te linijki z int p = 0; 
// a potem
var result = Kadane(tab);
System.out.println(result.sumaMax());
System.out.println(result.p());
//itd.
0

@jarekr000000:
+1

@Karol321:
Ja to zawsze z ambiwalentnymi uczuciami widzę kod jakiś alg z algorytmiki teoretycznej, źle zakodowany na płaszczyśnie danego języka (np proceduralna java, brrr - kopnęło cie przekazywanie wartości).
Niby wysokie walory intelektualne takich algorytmów mają być czynnikiem rozwijającym, ale osobiście wątpię czy są.

1 użytkowników online, w tym zalogowanych: 0, gości: 1