Verständigungsproblem einer Angabe

Neue Frage »

Auf diesen Beitrag antworten »
Shizmo Verständigungsproblem einer Angabe

Hallo ich hab hier mal einen Teil einer Aufgabe, mein Problem ist, dass ich nicht mal die Angabe verstehe.

Zitat:
Es ist eine Klasse VectorSet zu erstellen, die mehrere Vector-Objekte enthält. Diese Objekte können vom Typ Vector2D oder vom Typ DNA sein, wobei davon ausgegangen werden kann, dass in ein VectorSet-Objekt immer nur Objekte eines Typs eingefügt werden. Die Klasse Vector als Oberklasse ist vorgegeben:

code:
1:
2:
3:
4:
5:
6:
7:
public class Vector
{
public Vector () {}
public Vector add (Vector v) {return v;}
public Vector div (int n) {return new Vector();}
public double distance (Vector v) {return 0;}
}


Teil 1
Nun sind davon die zwei Klassen Vector2D und DNA abzuleiten, die Methoden zu überschreiben, geeignete Konstruktoren zu erstellen und toString zu überschreiben, sodass folgende Anweisungsfolge

code:
1:
2:
3:
4:
5:
6:
7:
Vector v = new Vector ();
v = v.add (new Vector2D (1, 2));
v = v.add (new Vector2D (2, 3));
System.out.println (v.div (2));
v = new DNA ("CCCCGGGGAAAATTTT");
v = v.add (new DNA ("CGATCGATCGATCGAT"));
System.out.println (v.div (2));


folgende Ausgabe erzeugt:

Zitat:
(1.5,2.5)
CCCCCGGGCGAACGAT


Bei Vector2D soll add die zwei Komponenten eines 2-dimensionalen Vektors einfach addieren, also (1,2)+(2,3)=(1+2,2+3)=(3,5) und div den Vektor dividieren, also (3,5)/2=(3/2,5/2)=(1.5,2.5)

Also die Vector-Klasse ist genau so vorgegeben. Heißt das, dass ich daran nichts ändern, hinzufügen darf?

Dann erstelle ich eine Klasse Vector2D mit extends Vector, so dass sie eine Unterklasse ist.
In dieser Klasse brauch ich dann zwei Instanzvariablen und einen Konstruktor der die "befüllt", zB x und y.

Okay hier mein Problem:
v = v.add (new Vector2D (1, 2));

Hier wird ein Objekt Vector2D erstellt mit x=1 und y=2
Wie überlade ich jetzt das add? Da das v ja ein Vector ist und kein Vector2D, muss ich die add in Vector überladen oder kann ich dass auch irgendwie in der Unterklasse. Vielleicht hat jemand ein Beispiel.

Und das Ergebnis wird dann im Objekt Vector v gespeichert und dann kommt nochmal ein:
v = v.add (new Vector2D (2, 3));
Das heißt v wird erweitert? Also am besten ein Array? Darf ich die Vector Klasse anrühren, wenn die ja schon so vorgegeben ist?

Und warum Vector2D ? Warum 2Dimensional?

LG
 
Auf diesen Beitrag antworten »
eulerscheZahl

Ich musste mir das eben auch ein paar mal durchlesen.
Von der Vector Klasse lässt du die Finger.
Durch v = v.add (new Vector2D (1, 2)); ist v jetzt vom Typ Vector2D. Dort kannst du add und div entsprechend überladen.
Mit v = new DNA ("CCCCGGGGAAAATTTT"); wird v schließlich zum DNA. Auch dort kannst du die Methoden überladen. Hier ist mir die Funktionsweise allerdings noch nicht klar: das passiert bei div(3), was wenn mehr aneinandergehängt wird? Geht aus der Aufgabe nicht hervor. Auch die gegebene Ausgabe ist nicht wirklich erklärt, da kann man aber ein Muster erkennen.
Auf diesen Beitrag antworten »
Shizmo

Wie die DNA funktioniert wird danach erklärt, mir gings nur erst mal nur ums add.

Wie soll den die add-Methode ausschauen, denn der return-Wert soll ja wieder ein Vektor sein.
Auf diesen Beitrag antworten »
eulerscheZahl

Mal eine Möglichkeit:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
public class Vector2D {
	@Override
	public Vector add(Vector v) {
		if (!(v instanceof Vector2D)) ...; //z.B. exception werfen
		this.x += ((Vector2D)v).x;
		this.y += ((Vector2D)v).y;
		return this;
	}
}

du kannst auch einen komplett neuen Vector2D erstellen oder es auf den zweiten addieren.
 
Auf diesen Beitrag antworten »
Shizmo

Hmmm,

Aber wenn jetzt zwei mal hintereinander v = v.add... kommt, so wie hier:
v = v.add (new Vector2D (1, 2))
v = v.add (new Vector2D (2, 3))

Wie kann dann:
System.out.println (v.div (2));
(1.5,2.5) ausgeben.

Es sind ja 2 verschiedene Vector2D Objekte... verwirrt
Auf diesen Beitrag antworten »
eulerscheZahl

Mit v = v.add überscheibst du aber das alte v. Und im neuen steht dann die Summe.
Und ich hätte an dem Entwurf noch mehr zu bemängeln, von einer abstrakten Superklasse bis zum generischen add, aber wenn der Prof es denn so haben will...
Auf diesen Beitrag antworten »
Shizmo

Okay vielen Dank schon mal, so weit so gut.
So gehts weiter:

Die Methode distance soll die euklidische Distanz berechnen, also:
[latex]d((1,2),(3,5)) = |(1,2) - (3,5)| = \sqrt{(1-3)^2 + (2-5)^2}  = 3.60555[/latex]

Woher nimmt dann die Methode distance wieder die Werte? Die aktuellen sind (3,5), dass ist klar, aber (1,2)? Soll man den allerersten Wert zwischenspeichern oder um was geht es da?

So eine sinnlose Angabe... Zunge raus
Auf diesen Beitrag antworten »
eulerscheZahl

Musst du dann wohl. Je nach dem, was du sonst noch an neuen Aufgaben ergänzt, würde ich eine verkettete Liste vorschlagen. Da hast du dann zur Not auch alle Vorgänger.
Auf diesen Beitrag antworten »
Shizmo

Hab übersehen, dass ja ein Parameter mit übergeben wird.

Also ich hab soweit alles und bin nun bei Teil2.

Hier mal die ganze Angabe: Klick

Es geht um einen Clustering-Algorithmus.
Hier hab ich momentan mal gar keine Idee mehr, wie ich das anfangen soll.
Freue mich über jeden Tipp.
Auf diesen Beitrag antworten »
eulerscheZahl

Die 1 hast du fertig?
Hängt es in Teil 2 bei der Sortierung schon oder erst beim Mittelwert?
Auf diesen Beitrag antworten »
Shizmo

1 hab ich, ja.

Ich weiß nicht mal wie ich anfangen sollte, Pseudocode würde mir auch schon viel helfen.
Auf diesen Beitrag antworten »
eulerscheZahl

Ich sortiere mal ints. Wenn du Vector2D nimmst, ändert sich die Abstandsberechnung natürlich.
code:
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:
import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		int[] c = new int[x.length];
		boolean[] used = new boolean[c.length];
		c[0] = x[0];
		used[0] = true;
		for (int i = 1; i < c.length; i++) { //finde Wert für c[i]
			//initialisieren: Referenzwert als bisheriges Optimum berechnen
			int bestIndex = 1;
			while (used[bestIndex])
				bestIndex++; //finde ersten ungenutzten Wert
			int bestDist = 0;
			for (int j = 0; j < i; j++) {
				bestDist += Math.abs(x[i] - c[j]); //hier musst du eine Wurzel ziehen
			}
			//andere Werte prüfen
			for (int k = bestIndex + 1; k < c.length; k++) {
				if (used[k])
					continue; //schon benutzt, scheidet also aus.
				int currentDist = 0;
				for (int j = 0; j < i; j++) {
					currentDist += Math.abs(x[k] - c[j]);
				}
				if (currentDist > bestDist) {
					bestDist = currentDist;
					bestIndex = k;
				}
			}
			used[bestIndex] = true;
			c[i] = x[bestIndex];
		}
		System.out.println(Arrays.toString(c));
	}
}
Auf diesen Beitrag antworten »
Shizmo

Vielen Dank schon mal.

Hab leider doch noch eine Fehlermeldung zum Teil 1 bekommen, allerdings kann ich damit nichts anfangen, vielleicht fällt dir was auf:

code:
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:
> java -classpath '/tmp/autoc-einfprog-0.5.5-33-g6ad7fba-plus/check-62-12-1453052244' -Duser.language=EN -Duser.region=US -Xmx512M Tester

Wrong result(s) detected. Please check your calculations and compare them to the test calculations below!
Part 1 not passed!
Exception in thread "test" java.lang.Exception: 

Part 1

Calculated the following things:

VectorSet vs_dna = new VectorSet(40);
DNA dna = new DNA("CGATGCGGAT");
vs_dna.add(dna);
String result = vs.toString();
Vector v = vs_dna.average();

[Ausführungsprotokoll gekürzt]

String result = v.toString();
DNA dna = new DNA("TGCCACTGAC");
vs_dna.add(dna);
String result = vs.toString();

Error while calling String result = vs.toString()

>> Expected result <<
CGATGCGGAT TGAGCTAAGG TGCCACTGAC 
>> Your result <<
CGAGCCGGGG TGAGCTAAGG TGCCACTGAC 

Info: Take care of the right number of blanks! (like in the assignment)

at test.checkValue(test.java:379)
at test.run(Unknown Source)


Hier die DNA:
code:
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:
public class DNA extends Vector {
	
	//Instanzvariablen
	private String dna;
	
	//Konstruktor
	public DNA(String dna){
		this.dna = dna;
	}
	
	//add - Verknuepft zwei Strings
	public Vector add(Vector v){
		this.dna = this.dna + ((DNA)v).dna;
		   return this;
		}
	
	//div - Teilt die Strings durch n
	public Vector div(int n){
		String newDNA = "";
		//1.Schleife baut neue DNA
		for(int i = 0; i < dna.length()/n; i++){
			int c = 0, g = 0, a = 0, t = 0;
			//Teilt die Strings durch n und zaehlt die Basen
			for(int j = i; j < dna.length(); j=j+dna.length()/n){
				if(dna.charAt(j) == 'C'){ c++;}
				else if(dna.charAt(j) == 'G'){ g++; }
				else if(dna.charAt(j) == 'A'){ a++; }
				else if(dna.charAt(j) == 'T'){ t++; }
			}
			//Welche Base kommt am haeufigsten vor
			if(c>g && c>a && c>t){ newDNA = newDNA+"C";	}
			else if(g>c && g>a && g>t){ newDNA = newDNA+"G"; }
			else if(a>c && a>g && a>t){ newDNA = newDNA+"A"; }
			else if(t>c && t>a && t>g){ newDNA = newDNA+"T"; }
			//Wenn Basen gleich haeufig auftreten
			else if((c==g && c>a && c>t) || (c==a && c>g && c>t) || (c==t && c>g && c>a) || (c==a && c==g && c>t) || 
					(c==a && c==t && c>g) || (c==t && c==g && c>a) || (c==a && c==g && c==t)){ newDNA = newDNA+"C"; }
			else if((g==a && g>c && g>t) || (g==t && g>c && g>a) || (g==a && g==t && g>c)  ) { newDNA = newDNA+"G"; }
			else if(a==t && a>g && a>c) { newDNA = newDNA+"A"; }
		}
		this.dna = newDNA;
		return this;
	}
	
	//distance - Zaehlt die Hammingdistanz
	public double distance (Vector v){
		int hd = 0;
		//Falls die Strings unterschiedlich lang sind.
		if(this.dna.length() != ((DNA)v).dna.length()){
			return -1;
		}
		//Zaehler
		for(int i = 0; i < this.dna.length(); i++){
			if(this.dna.charAt(i) != ((DNA)v).dna.charAt(i)){
				hd++;
			}
		}
		return hd;
	}
	
	//toString
	public String toString(){
		return dna;
	}
}


Und hier die VectorSet:
code:
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:
public class VectorSet {
	
	//Instanzvariablen
	int size;
	Vector[] set;
	
	//Konstruktor
	public VectorSet (int size){
		this.size = size;
		set = new Vector[size];
	}
	
	//add - Fuegt die Vectoren nacheinander in ein Array
	public void add (Vector v){
		for(int i = 0; i < size; i++){
			if(set[i] == null){
				set[i] = v;
				break;
			}
		}
	}
	
	//average - add und div Methode vom jeweiligen Vector
	public Vector average(){
		Vector v = new Vector();
		int realSize = 0;
		for(int i = 0; i < set.length; i++){
			if(set[i] != null){
				v = v.add(set[i]);
				realSize++;
			}
			else{
				break;
			}
		}
		return v.div(realSize);
	}
	
	public VectorSet cluster(int n){
		return this;
	}
	
	//toString
	public String toString(){
		String output = "";
		for(int i = 0; i < set.length; i++){
			if(set[i] == null){
				break;
			}
			else{
				output  = output+set[i].toString()+" ";
			}
		}
		return output;
	}
	
}
Auf diesen Beitrag antworten »
eulerscheZahl

Deine lange ODER Verkettung könntest du weglassen, wenn du darüber einfach ein <= nimmst. Trotzdem scheint dein ODER richtig.
code:
1:
2:
for (int i = 0; i < dna.length() / n; i++) {
	for (int j = i; j < dna.length(); j = j + dna.length() / n) {

Damit geht j bis zum allerletzten Zeichen von dna. Du solltest das Ende aber einfach ignorieren, wenn es nicht aufgeht.
Auf diesen Beitrag antworten »
Shizmo

Hmm warum, es soll ja alle Zeichen "dividen".

Das Problem ist ja:
code:
1:
2:
3:
4:
>> Expected result <<
CGATGCGGAT TGAGCTAAGG TGCCACTGAC 
>> Your result <<
CGAGCCGGGG TGAGCTAAGG TGCCACTGAC


Ich würd gern wissen, warum nur der erste String anders ist, bei allen möglichen Beispielen die mir einfallen funktioniert dieses div ja wunderbar... verwirrt
Auf diesen Beitrag antworten »
eulerscheZahl

Weil du weitere Zeichen mitzählst, die du abschneiden sollst.
Versuche mal j < dna.length()/n*n
Auf diesen Beitrag antworten »
Shizmo

Kommt exakt der selbe Fehler:

code:
1:
2:
3:
4:
>> Expected result <<
CGATGCGGAT TGAGCTAAGG TGCCACTGAC 
>> Your result <<
CGAGCCGGGG TGAGCTAAGG TGCCACTGAC 


//: Aber j wird ja immer um einen Teiler von n erhöht, dass heißt erst zählt es die:
Zitat:
CGATGCGGATTGAGCTAAGG

dann die:
Zitat:
CGATGCGGATTGAGCTAAGG

usw.

Also es zählt alle Zeichen an der "ersten" Stelle, dann an der zweiten, etc.
Also sollte es so schon passen oder?
Auf diesen Beitrag antworten »
eulerscheZahl

Mal ein einfaches Beispiel:
du willst GTAGC mit div(2) aufrufen.
Die Länge ist 5, also muss erst das C am Ende gestrichen werden: GTAG, sodass dann G,A unt T,G verglichen werden. Du willst für das erste Zeichen G,A,C vergleichen, was zu einem C führt.
Auf diesen Beitrag antworten »
Shizmo

Hmm interessant du hast recht, allerdings lag der Fehler wo anders.

Das Problem lag an add & div der DNA-Klasse, hier mal die add:

Vorher:
code:
1:
2:
3:
4:
	public Vector add(Vector v){
		this.dna = this.dna + ((DNA)v).dna;
		   return this;
		}

Jetzt:
code:
1:
2:
3:
	public Vector add(Vector v){
		   return new DNA(this.dna + ((DNA)v).dna);
		}


Dadurch, dass ich es zwischengespeichert habe, hat es beim mehreren Aufrufen von add und average zu Fehlergebnissen gefuehrt. Mit direktem Return hat es funktioniert.

Vielen Dank nochmal fuer deine Hilfe!!
Auf diesen Beitrag antworten »
eulerscheZahl

Hm, das habe ich übersehen unglücklich
Danke für die Rückmeldung.
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »