1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
package aufgabe2;
import fhw.*;
/**
* FH Wiesbaden, FB 06, Medieninformatik, Algorithmen und Datenstrukturen, SS 2006<br>
* Uebungsblatt 4, Aufgabe 2<br><br>
*
* Programm, das rekursiv die maximale Teilsumme eines Arrays mit n ganzen Zahlen findet
* und die Summe, sowie die Indizes der Teilfolge ausgibt<br>
* Eingabe: <br>
* Ausgabe: <br><br>
*
* Getestet mit Microsoft Windows XP Media Center Edition, Java-Version 1.5.0_05<br>
*
* @author Phibee
* @version 1.0 (28.04.2006)
*/
public class MaxSubArrayRekArray {
/**
* Startroutine des Programms
* @param args Kommandozeilenparameter
*/
public static void main(String[] args) {
int[] a = ADSTool.readIntArray("u4a1simple.dat");
int[] max = {0,0,0};
max[0] = getMaxSubArray(a, 0, a.length-1)[0];
max[1] = getMaxSubArray(a, 0, a.length-1)[1];
max[2] = getMaxSubArray(a, 0, a.length-1)[2];
System.out.println("Teilfolge von "+max[0]+" bis "+max[1]+" maximal mit Wert: "+max[2]);
} // Ende main
/**
* Methode, die rekursiv die maximale Teilsumme eines Arrays mit n ganzen Zahlen findet
* @param a Array
* @param start Startindex
* @param ende Endindex
* @return Array mit groesster Teilsumme und deren Indizes
*/
public static int[] getMaxSubArray(int[] a, int start, int ende) {
int[] max = {0,0,0};
if (start==ende) {
if (a[start]>0) {
max[0]=start;
max[1]=ende;
max[2]=a[start];
}
else {
max[0]=start;
max[1]=ende;
max[2]=0;
}
return max;
}
else {
int[] schnittstelle = new int[3];
schnittstelle[0]=rechteRandsumme(a,start,(start+ende)/2)[0];
schnittstelle[1]=linkeRandsumme(a,(start+ende)/2+1,ende)[1];
schnittstelle[2]=rechteRandsumme(a,start,(start+ende)/2)[2]+
linkeRandsumme(a,(start+ende)/2+1,ende)[2];
return (max((getMaxSubArray(a,start,(start+ende)/2)),
schnittstelle,
getMaxSubArray(a,(start+ende)/2+1,ende)));
}
} // Ende getMaxSubArray
/**
* Methode zur Bestimmung der groessten dreier Teilsummen
* @param a groesste Teilsumme der linken Haelfte
* @param b Summe der groessten linken Randsumme der rechten Haelfte
* und der groessten rechten Randsumme der linken Haelfte
* @param c groesste Teilsumme der rechten Haelfte
* @return Array mit groesster der 3 Teilsummen und deren Indizes
*/
public static int[] max(int[] a, int[] b, int[] c) {
int[] max={0,0,0};
if (a[2]>b[2]) {
if (a[2]>c[2]) max=a;
}
else if (b[2]>c[2]){
max=b;
}
else max=c;
return max;
}
/**
* linke Randsumme des rechten Teilarrays
* @param a Array
* @param start Startindex
* @param ende Endindex
* @return Array mit groesster Randsumme und deren Indizes
*/
public static int[] linkeRandsumme(int[] a, int start, int ende) {
int sum=0;
int[] max={start,start,0};
for (int i=start ; i<=ende ; i++) {
sum+=a[i];
if (sum>max[2]) {
max[0]=start;
max[1]=i;
max[2]=sum;
}
}
return max;
}
/**
* rechte Randsumme des linken Teilarrays
* @param a Array
* @param start Anfangsindex
* @param ende Endindex
* @return Array mit groesster Randsumme und deren Indizes
*/
public static int[] rechteRandsumme(int[] a, int start, int ende) {
int sum=0;
int[] max={ende,ende,0};
for (int i=ende ; i>=start ; i--) {
sum+=a[i];
if (sum>max[2]) {
max[0]=i;
max[1]=ende;
max[2]=sum;
}
}
return max;
}
} // Ende MaxSubArrayRek
|