Matrix, ArrayList, null-Zellen

Status
Nicht offen für weitere Antworten.

diggaa1984

Top Contributor
hiho,

ich hab grad ein kniffliges Problemchen. Und zwar habe ich eine Matrix, welche als Zelleninhalt Listen von Strings hält. Die Matrix selbst basiert ebenfalls auf Listenstrukturen, sieht also wie folgt aus:
Java:
private List<List<List<String>>> matrix;

liest sich blöde, aber is zumindest ein Versuch 🙂

So um nun bei ner größeren Matrix nicht alle Zellen mit irgendwelchen, größtenteils leeren, Listen zu erzeugen, dachte ich, ich erzeuge nur in den Zellen ein Listenobjekt, wo ich auch definitiv ne Information ablegen muss, also die Liste später mind. 1 Element beinhaltet.

So, das ganze muss nur eine obere Dreiecksmatrix sein, das bedeutet die Länge der Spalten entspricht exakt dem Spaltenindex+1 (Spalte 0 = 1 Reihe, Spalte 5 = 6 Reihen) .. daher auch "col+1" im Code. So leider hilft mir diese initiale Kapazität kein Stück, ausser das ArrayList-intern nichts erweitert werden muss. Die Size bleibt aber weiterhin 0 ... und genau das schlägt dann bei der Prüfung in Zeile 9 quer. Denn ich erhalte hier nicht ne Angabe ob das Element null ist oder existiert, sondern ich bekomme eine IndexOutOfBounds-Exception, was mir total nich weiterhilft 🙂
Java:
private void addToMatrix(String elem, int col, int row) {
	System.out.println(elem + "\t@ [" + col + "," + row + "] (col,row)");
	//setup column-size if neccessary (cells will be null)
	if (matrix.size() <= col)
		for (int i=matrix.size(); i<=col; i++)
			matrix.add(new ArrayList<List<String>>(col+1));
		
	//setup specified cell
	if (matrix.get(col).get(row) == null) { //hier kommt die Exception
		matrix.get(col).set(row, new ArrayList<String>(1));
				
	matrix.get(col).get(row).add(elem);
}//addToMatrix

Gibt es noch andere Datenstrukturen, mit sehr guter Zugriffszeit, welche in etwa mit obigem Code arbeiten lassen?! Also wenn eine Zelle null ist, dann leg ich eben ne neue Liste rein, sonst hänge ich etwas an die bestehende an.
 
Ich würde dir dringend empfehlen, diese Matrix in einem interface zu verstecken. Also z.B.
Code:
interface StringListMatrix
{
    List<String> get(int row, int col);
    ....
}
Oder ggf. generisch mit
Code:
interface Matrix<T>
{
    T get(int row, int col);
    ....
}

Dann kann man sich aussuchen, ob man das mit einem 1D-Array, einem 2D-Array, einem dreieckigen 2D-Array, einer List<List<List<String>>> oder einer Map<TwoInts, List<String>> speichert.

Ggf. kann man auch "bequeme" Methoden machen - z.B. könnte man eine Methode ins Interface packen wie
Code:
void add(int row, int col, String value)
die die "value" in Liste an der angegebenen Position legt - aber diese Liste auch automatisch erzeugt, falls sie noch "null" ist (und analog dazu, die Liste löscht, sobald sie leer wird). Aber das hängt stark vom Anwendungsfall ab.

Mit "dünn besetzen Matrizen" hantier' ich auch gerade rum - dabei geht es zwar um die Frage, wie man eine dünn besetzte 1000000x1000000-Matrix mit floats noch vernünftig im Speicher unterbringt (und ich gehe nicht davon aus, dass das mit den Strings in diesem Sinne speicherkritisch ist), aber deswegen hatte ich zufällig gerade Survey of Sparse Matrix Storage Formats offen - man sieht: Für solche Probleme haben sich die Leute schon ein paar Gedanken gemacht. Prinzipbedingt hat man oft den tradeoff zwischen speichereffizienter Verwaltung und einfacher Verwaltung. Implementiert ist das ganze natürlich auch schon, z.B. unter cern.colt.matrix (Colt 1.2.0 - API Specification) aber das wäre wohl ein Overkill.
 
was es net alles gibt 🙂 ... wenn meine Abfragen auf dieser Matrix dann funktionieren dann werd ich das bestimmt mal ver-interfacen ^^ ... momentan muss ich erst noch prüfen ob diese neue (kompromierte) Matrix auch zum selben Ergebnis führt wie meine aufgeblähte ... sonst hab ich n problem 😀

externe Libs werde ich vermeiden, aber dennoch danke für den tipp 🙂

meine matrizen haben im Schnitt 30-50 Spalten gross .. im Extremfall kann es aber schon passieren das die Nutzer der Software mal einfach ne Formel in Parser jagen, die aus vielen verknüpft ist und ma fix ein paar hundert Spalten in der Matrix erfordert ... daher muss ich zumindest in den Spalten massiv sparen.
Leere Spalten werden schon so gut wie möglich vermieden, sodass wirklich nur das nötigste in der Matrix erscheint.

Aber ich finds spannend den Standardalgorithmus derart umzubiegen das er extrem performanter wird als normal.

EDIT: worüber ich mir momentan noch Sorgen mache, ist die Tatsache, dass ich bei grossen Matrizen pro Spalte ein Hashtable habe. wenn das im worst-case n paar Hundert sind, weniger toll wa 😀 nur wie lösen ...
 
Zuletzt bearbeitet:
wow, solange mir mal nich der heap um die ohren knallt bei grossen matrizen, hab ich glaube den CYK-Algo grad voll gepimpt 😀 ... von standardmäßig 6200 effektiven Vergleichen (bei 6x6-Matrix und entsprechender Regelmenge der Grammatik) auf 35 effektive Vergleiche beschränkt .. man das fetzt ja urscht 😀

musst ich ma loswerden 😱
 
Zuletzt bearbeitet:
ich muss nochma was fragen, gibt es in Eclipse die Möglichkeit sich anzeigen zu lassen wieviel Speicherplatz denn eine bestimmte Datenstruktur/Variable zur Laufzeit belegt?!
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben