# Ringspeicher



## random3212 (22. Jun 2012)

Hallo,

ich soll eine gegebene main Klasse ausführbar mache, indem ich einen Ringspeicher implementiere. Bevor ich jetzt anfange und aber in die falsche Richtung programmiere, wollte ich einmal fragen, ob man es folgend machen kann:

In der main Methode wird ein Objekt erstellt mit 

```
KlasseInterface schlange = new Klassebearbeiten();
```
Ich habe also drei Klassen. Ein Interface, eine Klasse Klassebearbeiten und die Klasse Haupt, in der die main Methode ist. 
Nun soll der Ringspeicher zur Programmierung einer Schlange im Supermarkt implementiert werden. Ich habe mir gedacht, einfach ein Stringarray zugehörig zur Klasse Klassebearbeiten zu erstellen, damit ich dort die Namen der Kunden, die sich in die Schlange reihen, eintragen kann.
In der main Methode gibt es dann zwei Aufrufe mit:

```
schlange.anstellen("susi");
schlang.verlasse("peter");
```

Wenn sich also jemand anstellt, würde ich ganz einfach ihn in das String array eintragen, wenn er geht, wieder austragen (grob gesagt). Ist das die Idee eines Ringarrays?


----------



## Fab1 (22. Jun 2012)

Ich musste zwar jetzt erstmal nachschlagen was mit Ringspeicher gemeint ist, aber nun würde ich es auch so implementieren wie du gesagt hast.

Allerdings würde ich anstatt eines normalen Arrays eine ArrayList empfehlen. Da man ein Array immer neu erzeugen muss und eine ArrayList kann dynamisch Elemente aufnehmen (add) oder entfernen (remove).

Bei der verlassen() Methode wird der Speicher des Objekts ja wieder freigegeben oder? Sollten die Methoden nicht schon vorgegeben sein, wäre ratsam auf das zu achten.


----------



## njans (22. Jun 2012)

Ist nicht gerade die beschränkte Anzahl an  Plätzen elementar wichtig an einem RingBuffer?

Das mit einer ArrayList zu machen erscheint mir gänzlich falsch, sofern ich kein falsches Konstrukt im Kopf habe.


----------



## random3212 (22. Jun 2012)

String[] Array scheint mir sinnvoller, weil die Liste eben beschränkt sein soll.

@Fab1
Was meinst du jetzt mit Speicher des OBJEKTES freigegeben? Ich hätte einfach den Namen irgendwie überschrieben bzw. verlässt ein Mensch ja die Reihe, wenn er ganz vorne steht. Und da entdecke ich auch den Fehler:


```
schlange.dequeue()
```
muss es heißen.


----------



## njans (22. Jun 2012)

Normalerweise soeicherst du dann ein Array und einen dazugehörigen index, der angibt wo das Ende/Anfang des Ringes in. Wenn du nun ein Element einfügst, dann machst du das vom startindex so lange, bis du wieder bei diesem ankommst. Wenn dann noch ein Element eingefügt wird, dann  überschreibst du das Element am Startindex und musst den Startindex um eins verschieben (das älteste Objekt wird überschrieben)


----------



## Fab1 (22. Jun 2012)

Mein Kommentar hat sich erledigt, ich habe mir dazu Digitaler Ringspeicher ? Wikipedia durchgelesen und mit diesem wenn auch kurzen Wiki Beitrag wäre mein Lösungsvorschlag (denke ich) nachvollziehbar.

Wenn man sich allerdings Warteschlange (Datenstruktur) ? Wikipedia anschaut, fällt klar auf was gemeint ist und auch was gemacht werden muss.


----------



## njans (22. Jun 2012)

Kann passieren Fabi.






Das illustriert noch mal die Idee des RingBuffers. Wenn 3 eingefügt wird, dann fliegt 37 raus. Dabei war die erste eingefügte Zahl eben die 37 (sie ist die älteste Zahl im Speicher).


----------



## random3212 (23. Jun 2012)

Dann muss ich aber ein abgeänderte Version des RingBuffers implementieren bzw. verstehe ich dann überhaupt nicht die Namensgebung in der Aufgabenstellung.

Ich soll nämlich eine Warteschlange im Supermarkt programmieren. Wenn aber die Länge der Schlange maximalen Wert hat, dann kann sich keiner mehr anstellen, es fliegt also keiner raus. Mit Ringspeicher hat das meiner Meinung dann nicht mehr so viel zu tun.


----------



## njans (23. Jun 2012)

Ich gebe dir absolut Recht. Das Modellieren einer Warteschlange mit RingBuffer ist ... komisch, im besten Fall. Auch deine Aufrufe, spezielle das Löschen mittels Namen, macht auch nicht wirklich Sinn. Das Einfügen ist durchaus angebracht, wenn du Namen in dem RingBuffer speicherst. 
Also entweder meint deine Aufgabe keinen RingBuffer/RingSpeicher, sondern ein Array, oder die Aufrufe sind falsch, oder aber der Aufgabensteller, weiß0 nicht, was er tut.


----------



## random3212 (23. Jun 2012)

Also RingBuffer oder ähnliches sollen wir glaube ich nicht verwenden. Wie gesagt, ich habe es jetzt mit einem String-Array gelöst und die main-Methode wird ausgeführt.


----------



## random3212 (23. Jun 2012)

Nach Durchlesen der Aufgabenstellung bin ich nun doch ein bisschen verunsichert.
Aufgabe: 
Implementieren Sie das Interface Queue durch einen Ringspei-
cher der Länge 5, so dass das Programm Shopping übersetzt und ausgeführt werden kann. Es
muss die folgende Ausgabe liefern:

Meine Klasse Auszuführen sieht so aus:

```
class Auszuführen implements Queue{
String[] warteschlange;
public void enqueue(...){
...
}
public void dequeue(){
...
}
```


```
class Shopping{
...
}
```

Hab ich die Aufgabe damit richtig gelöst, wenn es heißt, man soll das Interface "durch" einen Ringsspeicher implementieren?


----------



## ThreadPool (23. Jun 2012)

njans hat gesagt.:


> Ich gebe dir absolut Recht. Das Modellieren einer Warteschlange mit RingBuffer ist ... komisch, im besten Fall. [...]



Einen Queue mithilfe eines Ringspeichers zu implementieren ist eine normale Sache und nicht im geringsten komisch. Eine Implementierung als RS eignet sich vorallem wenn größenbeschränkte Queues verwendet werden sollen.


----------



## random3212 (23. Jun 2012)

Bleibt für mich noch die Frage, ob es so richtig ist, wie ich es gemacht habe. Sprich: Ein String Array erstellen und dort die Namen einzutragen?


----------



## !GH!Budd (23. Jun 2012)

Vielleicht postest du doch mal die komplette Aufgabenstellung. Vermutlich hat der Aufgabensteller euch ein interface zur Verfügung gestellt, damit er es hinterher testen kann? Vielleicht gibt es dann auch Vorgaben, was gespeichert werden soll. Wenn deine Queue nur Strangs speichern soll, ist das ganze nicht vergehrt. Normalerweise wird sowas aber eher allgemein mit objects oder anderen Klassen gemacht.


----------



## random3212 (23. Jun 2012)

Nutzen Sie zur Lösung der folgenden Aufgaben das Interface Queue.java und die Klasse
Shopping.java von der Moodle-Seite.
a) CircularBufferQueue.java: Implementieren Sie das Interface Queue durch einen Ringspei-
cher der Länge 5, so dass das Programm Shopping übersetzt und ausgeführt werden kann. Es
muss die folgende Ausgabe liefern:
10.00 Uhr: < >
Susi stellt sich an
Fritz stellt sich an
Eva stellt sich an
10.05 Uhr: < Susi Fritz Eva >
Susi wurde bedient
10.07 Uhr: < Fritz Eva >
Egon stellt sich an
Pia stellt sich an
10.09 Uhr: < Fritz Eva Egon Pia >
Lara stellt sich an
10.10 Uhr: < Fritz Eva Egon Pia Lara >
ACHTUNG: Einfuegen Fred nicht moeglich: Queue voll
10.11 Uhr: < Fritz Eva Egon Pia Lara >
Fritz wurde bedient
Eva wurde bedient
10.15 Uhr: < Egon Pia Lara >
Paul stellt sich an
Erich stellt sich an
10.20 Uhr: < Egon Pia Lara Paul Erich >
Egon wurde bedient
Pia wurde bedient
Lara wurde bedient
Paul wurde bedient
10.30 Uhr: < Erich >
Erich wurde bedient
10.35 Uhr: < >
ACHTUNG: Entnahme nicht moeglich: Queue leer
11.00 Uhr: < >


```
class Shopping {

  public static void main(String[] args) {
    // fuer b) aendern zu ListQueue
    //Queue shoppers = new CircularBufferQueue();
    Queue shoppers = new ListQueue();
    System.out.println("10.00 Uhr: " + shoppers);
    shoppers.enqueue("Susi");
    shoppers.enqueue("Fritz");
    shoppers.enqueue("Eva");
    System.out.println("10.05 Uhr: " + shoppers);
    shoppers.dequeue();
    System.out.println("10.07 Uhr: " + shoppers);
    shoppers.enqueue("Egon");
    shoppers.enqueue("Pia");
    System.out.println("10.09 Uhr: " + shoppers);
    shoppers.enqueue("Lara");
    System.out.println("10.10 Uhr: " + shoppers);
    shoppers.enqueue("Fred");
    System.out.println("10.11 Uhr: " + shoppers);
    shoppers.dequeue();
    shoppers.dequeue();
    System.out.println("10.15 Uhr: " + shoppers);
    shoppers.enqueue("Paul");
    shoppers.enqueue("Erich");
    System.out.println("10.20 Uhr: " + shoppers);
    shoppers.dequeue();
    shoppers.dequeue();
    shoppers.dequeue();
    shoppers.dequeue();
    System.out.println("10.30 Uhr: " + shoppers);
    shoppers.dequeue();
    System.out.println("10.35 Uhr: " + shoppers);
    shoppers.dequeue();
    System.out.println("11.00 Uhr: " + shoppers);
  }

}
```


```
public interface Queue {

  // Falls eine Operation wegen voller / leerer Queue nicht
  // ausfuehrbar ist, soll eine entsprechende Ausschrift ausgegeben
  // und die Operation ignoriert werden
  public void enqueue(String data);
  public String dequeue();

}
```


----------



## AquaBall (23. Jun 2012)

Also must du die Klasse 
	
	
	
	





```
ListQueue
```
 schreiben.

Wie du das intern verwaltest ist ihm egal.

Ich würde ein ArrayList verwenden.
weil da anfügen und vorne löschen am einfachsten zu realisieren ist.

Array würd ich nicht verwenden, weil du da immer umkopieren musst, und Queues mit weniger als Max eine Sonderbehandlung brauchen.

Konstruktoren:

```
ListQueue() {
  this(5);
}
ListQueue(int myCount) {
  this.maxCount=myCount;
}
```


```
void enqueue(String newMember) 
{ ... // Hinten anhängen (wenn Platz ist)
}
String dequeue() 
{ ... // den ersten rausschmeißen
}
String toString()
{ ... // Members auflisten
}
```


----------



## !GH!Budd (23. Jun 2012)

Jetzt ist doch schon etwas klarer, was du brauchst. Ja, du hast es richtig gemacht, einen String Array anzulegen. Allerdings stimmt die Signatur deiner Methoden nicht: dequeue muss ja einen String zurückgeben (vgl. Interface).
Habe mich gewundert, warum deine Klasse Auszuführen heißt. Dein Aufgabensteller hat wohl gemeint, die Klasse sollte CircularBufferQueue heissen. (Vgl. Aufgabenstellung)


----------



## ThreadPool (23. Jun 2012)

random3212 hat gesagt.:


> Bleibt für mich noch die Frage, ob es so richtig ist, wie ich es gemacht habe. Sprich: Ein String Array erstellen und dort die Namen einzutragen?



Es ist völlig egal wie du das implementierst solange du dich an die Semantik der definierten Schnittstelle hältst die in deinem Fall durch ein Java-Interface - Queue.java - gegeben ist. Den Queue sollst du durch einen Ringspeicher realisieren der selbst wiederrum auf mehrere Arten gebaut werden kann z.B. als Array oder verkette Liste.

Vll. schreibst du dir also eine Klasse die sich Ringspeicher (o. RingBuffer) nennt und implementierst dort die Funktionalität eines Ringspeichers. Dann könntest du die Klasse "CircularBufferQueue" erstellen die das Interface Queue implementiert und durch Komposition und Delegation die Klasse Ringspeicher verwenden um einen Queue zu erstellen der durch einen Ringspeicher verwirklicht wurde.


----------



## njans (23. Jun 2012)

ThreadPool hat gesagt.:


> Einen Queue mithilfe eines Ringspeichers zu implementieren ist eine normale Sache und nicht im geringsten komisch.


Da stimme ich dir zu, und hier kommt das aber: Nicht zur Modellierung einer Warteschlange in einer Schuhl/Uni-Aufgabe. Du hast da nicht unendlich viele Personen die warten, ein Speicherproblem kriegst du da damm eh nicht. 



ThreadPool hat gesagt.:


> Eine Implementierung als RS eignet sich vorallem wenn größenbeschränkte Queues verwendet werden sollen.


Z.B. in einigen DatenBanken als Buffer. Aber eben nicht als Modell für eine echte Warteschlange.


----------



## ThreadPool (23. Jun 2012)

njans hat gesagt.:


> Da stimme ich dir zu, und hier kommt das aber: Nicht zur Modellierung einer Warteschlange in einer Schuhl/Uni-Aufgabe. Du hast da nicht unendlich viele Personen die warten, ein Speicherproblem kriegst du da damm eh nicht.
> 
> Z.B. in einigen DatenBanken als Buffer. Aber eben nicht als Modell für eine echte Warteschlange.



Na anscheinend wird ein Ringspeicher wohl doch in einer Uni-/Schulaufgabe gefordert wie man an diesem Thread unschwer erkennen kann. Und ich sehe keinen Grund weshalb man mit einem Ringspeicher keine "echten" Warteschlangen modellieren können soll. Da die Wahl Ringspeicher oder nicht ein Implementierungsdetail ist.


----------



## Vendetta (23. Jun 2012)

es ist sehr dreist das du hier die aktuellen algorithmen und datenstrukturen aufgaben postest , schau dir die vorlesung an, du sollst den ringspeicher mit inner/outer implementieren.


----------



## AquaBall (23. Jun 2012)

Vendetta hat gesagt.:


> es ist sehr dreist das du hier die aktuellen algorithmen und datenstrukturen aufgaben postest , schau dir die vorlesung an, du sollst den ringspeicher mit inner/outer implementieren.



Uups! Wurde da jemand ertappt?

Aber, lieber Vortragender (wenn ich das aus dem Unterton richtig rauslese),
sehen wir's mal von der positiven Seite: Er informiert sich!

Und das ist ja genau der Grund, warum wir hier keine Hausaufgaben lösen, sondern nur Denkanstöße geben.

Das "Problem" ist, dass dieses Forum so gut besucht ist, dass es bei jeder Suche mit Google ganz oben erscheint. Ich find das gut!


----------



## Vendetta (23. Jun 2012)

es ist gut wenn man um hilfe bittet, wenn man es nicht versteht, aber nicht indem man die aufgabenstellung postet sondern einfach fragt wie man am besten einen ringspeicher implementieren kann.

guck dir folie 108 an, da fängt inner/outer an. wenn du damit aber nicht klar kommst, dann musst du es halt mit einem string array probieren, gibt zwar punktabzug, weil wir hier von datenstrukturen reden.


----------



## njans (23. Jun 2012)

An dieser Stelle muss ich jedoch einwerfen, dass wir hier oft Studenten/Schüler haben, die mit ihren Aufgaben nicht weiter kommen. Oftmals wissen diese selbst nicht genau, was sie machen sollen. Das mag zum teil am mangelnden Verständnis der Aufgabe liegen, allerdings auch an Dozenten/wissenschaftlichen Mitarbeitern, die diese Aufgaben unklar formulieren.
Daher ist es, in den meisten Fällen, doch sehr hilfreich, die Aufgabenstellung zu kennen um auf den eigentlichen Sinn und Zweck der Aufgabe zu kommen.


----------

