Jak usprawnić program?

0

Witam, ostatni napisałem prosty program - Generalnie chodzi o to, aby znaleźć takie sumy(obojętnie ilu czynników) liczb(z tablicy) aby były to wielokrotności 100 ale nie większe niż 1000.
Poniżej krótki opis działania:
W tablicy mam 106 elementów, element o indeksie 0 jest dodawany do elementu o indeksie 1, potem element o indeksie 0 jest dodawany do elementu o indeksie 2 itd. Jak element zerowy zostanie dodany po kolei do każdego z pozostałych elementów, to to samo dzieje się z elementem o indeksie 1 itd, ale bez powtórzeń (czyli element o indeksie 1 jest od razu dodawany od elementu o indeksie 2). Jeśli jakaś suma jest wielokrotnością liczby 100 do tysiąca włącznie, to wypisuje ją w konsoli. Sumy >1000 są wpisywane do listy. Teraz 0 element listy jest dodawany do 0 elementu tablicy, potem 0 element listy jest dodawany do 1 elementu tablicy itd. Tak samo dla 1 elementu listy i każdego innego. Po każdej pętli z listy usuwany jest 0 element. Jednocześnie jeśli suma (teraz już 3 liczb) jest <1000, to jest ona zapisywana na końcu listy. Czyli po zakończeniu jednej pętli mamy znowu listę z sumami, ale teraz trzech liczb. Dzieje się tak dopóki lista nie będzie pusta. Program działa dość sprawnie, gdy liczb jest niewiele. Niestety przy większej ilości czynników ilość kombinacji dramatycznie rośnie i komputer nie jest w stanie tego przerobić (czekałem nawet i 20 minut). Teraz moje pytanie i problem zarazem - Czy da się napisać to tak, aby program sensownie działał?

Kod

public static void main(String[] args) {
		ArrayList<Integer> sumy = new ArrayList<Integer>();
		int[] liczby = { 165, 611, 195,
				};

		for (int i = 0; i < liczby.length; i++) {

			for (int j = i; j < liczby.length - 1; j++) {

				for (int k = 1; k < 11; k++) {
					if (liczby[i] + liczby[j + 1] == k * 100) {
						System.out.println("Liczba o indeksie: " + i);
						System.out.println("Wielokrotności 100: " + liczby[i]
								+ "+" + liczby[j + 1] + "="
								+ (liczby[i] + liczby[j + 1]));
					}
				}
				if (liczby[i] + liczby[j + 1] < 1000) {
					sumy.add(liczby[i] + liczby[j + 1]);
				}
			}
		}
		System.out.println("kolejne sumy " + sumy);
		System.out.println(sumy.size());
		for (sumy.size(); sumy.size() > 0;) {
			int a = sumy.size();
			for (int i = 0; i < liczby.length; i++) {
				for (int j = 0; j < a; j++) {
					for (int k = 1; k < 11; k++) {
						if (liczby[i] + sumy.get(j) == k * 100) {
							System.out.println("Wielokrotności liczby 100: "
									+ liczby[i] + "+" + sumy.get(j) + "="
									+ (liczby[i] + sumy.get(j)));
						}
					}
					if (liczby[i] + sumy.get(j) < 1000) {
						sumy.add(liczby[i] + sumy.get(j));
					}
				}
			}
			for (int i = 0; i < a; i++) {
				sumy.remove(0);
			}
			System.out.println(sumy);
			System.out.println(sumy.size());
		}
		System.out.println("Koniec dodawania");
	}
}
0

Ogólnie jest to problem sumy podzbioru, który jest NP-zupełny, więc wydajnego algorytmu nikt nie zna:
http://pl.wikipedia.org/wiki/Problem_sumy_podzbioru

BTW sprawdzanie czy liczba jest wielokrotnością 100 w pętli jest mocno słabe, wystarczy

if ((liczby[i] + liczby[j + 1]) % 100 == 0)
0
  1. podziel kod na metody i klasy.
  2. nazewnictwo. Co to za zmienna a w pętlach? jaki limit ona reprezentuje?
  3. Unikaj zagnirżdżania pętli. To miesza.
  4. masz napisane testy do tego?

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