You are not logged in.

  • Login

1

Wednesday, April 26th 2006, 5:43pm

Maximum Sub Array Problem: Rekursiv

Endlich....es ist vollbracht !!!!!!!!!!!!!!!!!!!!!!!!!!!!

1000 Dank an Stefan & Marco :shock:


Java Quellcode

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
package ueb4;
 
import fhw.ADSTool;
 
public class A2 {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// int[] a = ADSTool.readIntArray(args.length==0 ? "u4a1.dat" :
		// args[0]);
		int summe = 0, max = 0;
		int[] a = { 31, -41, 59, 26, -53 };
 
		// maxsub();
		System.out.println("Größte Teilsumme:"
				+ maxSubArray(a, 0, a.length - 1));
 
	}
 
	private static int maxSubArray(int[] a, int startpos, int endpos) {
		int mitte = (startpos + endpos) / 2;
		if (startpos == endpos) {
			if (a[startpos] > 0)
				return a[startpos];
			else
				return 0;
 
		} else {
 
			int lRand = RechteRandsumme(a, startpos, mitte);
			int rRand = LinkeRandsumme(a, mitte + 1, endpos);
			int sumRaender = lRand + rRand;
			int lhaelfte = maxSubArray(a, startpos, mitte);
			int rhaelfte = maxSubArray(a, mitte + 1, endpos);
 
			System.out.println("Startposition:" + startpos + " Mitte: " + mitte
					+ " Endposition: " + endpos);
			System.out.println("Linke Hälfte: " + lhaelfte);
			System.out.println("Rechte Hälfte: " + rhaelfte);
 
			System.out.println("LinkeRandsumme:" + lRand
					+ " + RechteRandsumme:  " + rRand + " = " + sumRaender);
 
			return max(lhaelfte, rhaelfte, lRand + rRand);
 
		}
	}
 
	private static int RechteRandsumme(int a[], int start, int ende) {
 
		int max = 0;
		int sum = 0;
 
		for (int i = ende; i >= start; i--) {
			sum += a[i];
			if (sum > max) {
				max = sum;
			}
		}
 
		return max;
	}
 
	private static int LinkeRandsumme(int a[], int start, int ende) {
 
		int max = 0;
		int sum = 0;
 
		for (int i = start; i <= ende; i++) {
			sum += a[i];
			if (sum > max) {
				max = sum;
			}
		}
 
		return max;
	}
 
	private static int max(int a, int b, int c) {
		int max0 = (a > b) ? a : b;
		int max = (max0 > c) ? max0 : c;
		return max;
	}
}

2

Thursday, April 27th 2006, 1:05pm

alternative Lösung mit Kommentaren

hier meine Lösung für alle, die noch nicht so ganz durchblicken. Ich hoffe, die Kommentare erklären das Programm adäquat:

Java Quellcode

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
/**
 * Algorithmen und Datenstrukturen<br>
 * FH-Wiesbaden, Sommersemester 2006<br>
 * Uebung04/Aufgabe02 - Rekursive Berechnung eines maximalen sub.Arrays<br>
 * 
 * @author Sebastian Schmitt
 * @version 1.0 
 */
package Aufgabe02;
import fhw.*;
 
 
public class MaxSubArrayRekursiv {
 
	/**
	 * @param args Kommandozeilenparameter
	 */
	public static void main(String[] args) {
		ADSTool.resetTime();
 
		int a[];
		a=ADSTool.readIntArray("u4a1.dat");
 
		int ergebniss=maxSubRec(a);
		System.out.println(ergebniss);//46610
 
		System.out.print("Zeit: "+ADSTool.stringRTime());//0.03s !!!
	}
	/**
	 * errechnet die maximale linke Randsumme eines int[]
	 * @param a int[]
	 * @return maximale linke Randsumme von a[]
	 */
	static int maxSumLeft(int [] a){
		int max=0;
		int tmp=0;
		for(int i=0; i<a.length; i++){
			tmp+=a[i];
			if(tmp>max)
				max=tmp;
		}
		return max;
	}
	/**
	 * errechnet die maximale rechte Randsumme eines int[]
	 * @param a int[]
	 * @return maximale rechte Randsumme von a[]
	 */
	static int maxSumRight(int a[]){
		int max=0;
		int tmp=0;
		for(int i=a.length-1; i>0; i--){
			tmp+=a[i];
			if(tmp>max)
				max=tmp;
		}
		return max;
	}
	/**
	 * errechnet das maximale sub-Array eines int[]
	 * @param a int[]
	 * @return maximales sub-array von a[]
	 */
	static int maxSubRec(int[] a){
		if(a.length==1)
			return a[0]>0 ? a[0] : 0;
			else{
				int[] b=new int[a.length/2];
				System.arraycopy(a,0,b,0,a.length/2);//linke Haelfte von a[]
				int[] c=new int[a.length-a.length/2];
				System.arraycopy(a,a.length/2,c,0,a.length-a.length/2);//rechte Haelfte von a[]
 
				int maxa=0;
				maxa=maxSumRight(b)+maxSumLeft(c);//linke + rechte Randsumme
				int maxb=maxSubRec(b);//"eine Stufe Tiefer" in die linke H. von a[]
				int maxc=maxSubRec(c);//"eune Stufe Tiefer" in die rechte H. von a[]
 
				//return Maximum(maxa/maxb/maxc) fuer uebergeordete Rekursionen
				if(maxa>=maxb && maxa>=maxc)
					return maxa;
				else if(maxb>=maxa && maxb>=maxc)
					return maxa;
				else
					return maxc;
			}
	}
}

3

Sunday, April 30th 2006, 12:03pm

Lösung mit Indizes-Angabe

Hier mal meine Lösung, die neben der größten Teilsumme auch noch deren Anfangs- und Endindex ausgibt:

Java Quellcode

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

Similar threads

Social bookmarks