suche nicht dynamisch Datenstruktur

Status
Nicht offen für weitere Antworten.

Kapitän

Bekanntes Mitglied
hallo,

ich möchte eine Funktion schreiben, die aus den letzten 10 übergebenen Werten den Durchschnitt berechnet.

Code:
int durchschnitt(int neuerWert) {

// speichere Wert
// berechne Durchschnitt

return durchschnitt;
}


Jetzt suche ich eine passende Datenstruktur.

Am besten wäre eine Queue mit festgelegter Größe. Dh. sobald das elfte Element hinzugefügt wird, wird das älteste Element rausgeschmissen.

Welche Datenstruktur ist dafür geeignet?
 
Ich würde's wahrscheinlich gleich so ähnlich machen:
Code:
private int[] history10 = new int[10];
private int historySize = 0;
private int historyOff = 0;

int durchschnitt(int neuerWert) {
  history10[historyOff] = neuerWert;
  historyOff = (historyOff + 1) % 10;
  historySize += historySize > 10 ? 0 : 1;
  // hier berechnen
}
Code ist ungetestet!
 
Code:
public class VanishingMean{
	
	private Number[] values;	//archiv mit zahlen, (halten wir's mal etwas allgemeiner)
	private double sum;			//braucht man nicht jedes mal komplett neuzuberechnen
	private boolean rewriting;	//bei der ersten runde false, danach immer true
	private int currentPointer;	//aktueller index, damit die ältesten überschrieben werden
	private int unrefreshed;	//wie lange wurde nix mehr neuberechnet?
	
	private final int REFRESH_LIMIT=10000;	//nach so vielen schritten wird alles neuberechnet, um rundungsfehler klein zu halten 
	
	public VanishingMean(int maxValues){
		values=new Number[maxValues];
		reset();
	}
	
	// alles neustarten
	public void reset(){
		for(int i=0; i<values.length; i++) values[i]=0;
		sum=0;
		rewriting=false;
		currentPointer=0;
		unrefreshed=0;
	}
	
	// alle paar tausend mal die summe komplett neuberechnen, um auf dauer rundungsfehler zu vermeiden
	public void refresh(){
		sum=0;
		for(Number n:values){
			sum+=n.doubleValue();
		}
		unrefreshed=0;
	}
	
	// zahl eingeben, statistik ausgeben
	public double feed(Number n){
		sum+=n.doubleValue()-values[currentPointer].doubleValue();	//alten wert abziehen, neuen drufaddieren
		values[currentPointer]=n;	//ins "archiv" legen, um später zu löschen
		
		if(++currentPointer>=values.length){
			rewriting=true;
			currentPointer=0;
			if(++unrefreshed>REFRESH_LIMIT){
				refresh();
			}
		}
		
		if(rewriting){
			return sum/values.length;
		}else{
			return sum/currentPointer;
		}	
	}
	
	// kleiner test mit so einer art "gedämpften statistikschwingung"
	private static String bar(int h){
		String res="#";
		for(int i=0; i<h; i++,res+="|");
		return res;
	}
	
	public static void main(String... _){
		VanishingMean v=new VanishingMean(200);
		double output,input;
		for(int i=0; i<500; i++){
			input=(Math.cos(i/5d)+1)*50;
			System.out.printf("feeding: %7.2f output: %7.2f %s\n",input,(output=v.feed(input)),bar((int)output));
		}
	}
}
sowas würd ich mal vorschlagen. ist sofort kompilierbar.
 
Mein Vorschlag 🙂

Code:
class x{

private int[] speicher = new int[10];
private int zeiger = 0;


private void addNummer(int n){

 speicher[zeiger] = n;
  
  if(zeiger > 9){
     zeiger = 0;
    }
  else{
    zeiger++;
  }

}

private double berechneDurschnitt(){.............}

}
 
Anonymous hat gesagt.:
Classennamen großschreiben.
Keine magic-numbers a'la "9" verwenden, das endet immer mit ArrayIndexOutOfBoundsException.
Richtig Einrücken schadet der Übersicht nicht.
Ferner wollte der OP eingabe der neuen zahl und ausgabe des Durchschnitts in einer methode haben. Aber ein zusätzlicher getter würde auch echt nicht schaden, da muss ich dir recht geben :toll:
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben