# Perfekte Zahlen mit Teiler ausgeben!



## Xerxes20 (4. Nov 2010)

Hallo liebe Gemeinde,

ich bin ganz neu in Java und habe folgendes Problem:

In einer Aufgabe, muss ich Perfekte Zahlen berechnen lassen, allerdings muss in der Ausgabe auch die Teiler stehen.

Ich habe mich hier im Forum schon umgesehen und bin auch auf einen Code gestoßen, den habe ich dann versucht zu modifizieren, dass er die Teiler ausgibt. 

Das tut er auch, leider folgen nach der Ausgabe der Teiler eine Reihe von 1en und das verstehe ich nicht.

Hier der Code:


```
public class Perfekt   { 
	public static void main(String[] args)
    {
        
        int k;
        int n;
        int summe = 0;
        
        System.out.print("Bitte eine Ganzzahl eingeben: ");
        n = In.readInt();
        
        for(int j = n; j > 1; j--)
        {
            
            for(int i = 1; i < j; i++)
            {
			    
                if(j%i == 0)
                {
				
                    summe = summe + i;
					System.out.println("Teiler ist" +i);
			
                }
                if(summe > n )
                break;
            }
            if(summe == j)
            {
                    System.out.println("Die Zahl: " +j+ " ist eine perfekte Zahl!");
            }
        }
    }
}
```


----------



## Andi_CH (4. Nov 2010)

Der Code gibt doch viel zu viele Faktoren aus, aber vielleicht habe ich auch etwas nicht verstanden.

Fehler 1: Dich interessiere die Faktoren - also nicht aufsummieren sondern multipilizieren

Fehler 2: mit break beendest du nur den inneren loop - was der äussere soll ist mir unklar

Wie auch schon an anderer Stelle gesagt - pack doch die eigentliche Funktionalität in eine procedure - das macht das ganze viel einfacher testbar (ich weiss nicht was In ist, das gibt es bei mir nicht)

Alsi IN ausserhalb und dann die procedure aufrufen
Der Code macht sicher noch nicht das, was du willst, aber er bestimmt die Faktoren richtig

Was ich auch nicht verstehe ist, dass im letzten sysout j ausgegeben wird - aber es geht ja eigentlich um n?


```
public class Perfekt   {
	
	public static void Faktorzerlegung(int pInt)
	{
		int n;
		int produkt = 1;

		System.out.println("Eingabe ist: " + pInt);
		n = pInt;
		for(int j = n; j > 1; j--)
		{
			for(int i = 1; i < j; i++)
			{
				if(j%i == 0)
				{
					produkt = produkt * i;
					System.out.println("Teiler ist " +i);
				}
				if(produkt > n )
					return;
			}
			if(produkt == j)
			{
				System.out.println("Die Zahl: " +j+ " ist eine perfekte Zahl!");
			}
		}
	}
	
	public static void main(String[] args) {
		Faktorzerlegung(30);
	}
}
```


----------



## Xerxes20 (4. Nov 2010)

Hi,

also ich habe den Code ja nicht selber geschrieben (wenn ich das tuen würde, würde alles irgendwie daneben gehen)

Der macht es ja richtig in dem er ausgibt, ob die eingegebene Zahl eine Perfekte Zahl ist und wenn keine wird das Programm beendet.

Das In. ist eine klasse die der Lehrer hochgeladen hat, damit wir die in unsere Programme einbinden könne. Sie bewirkt, dass beim Start des Programms etwas eingegeben wird.

Also anstatt :

n = In.readInt();

hätte da auch :

int x =Integer.parseInt(args[0]);

stehen können.

Zum Sys-out:

Ja da kann man auch n reinschreiben, kommt das selbe heraus.


Edit:

Ich habe es teilweise geschafft, hier der neue code:


```
public class Perfekt   { 
	public static void main(String[] args)
	{
		int i;
		int k;
		int n;
		int summe = 0;
		
		System.out.print("Bitte eine Ganzzahl eingeben: ");
		n = In.readInt();
		
		for(int j = n; j > 1; j--)
		{
			
			for( i = 1; i < j; i++)
			{
				
				if(j%i == 0)
				{
				
					
					System.out.println("Teiler ist" +i);
					summe = summe + i;
					
				}
				if(summe > n )
				break;
			}
			if(summe == n)
			{
					System.out.println("Die Zahl: " +j+ " ist eine perfekte Zahl!");
			}
			if ( i==n) {
			break;
			}
		}
	}
}
```



So jetzt gibt er die Teiler untereinander aus, ich will aber,dass er die nebeneinander in einer println aufschreibt (also 6=1+2+3)

ich habe einfach daraus :

System.out.println("Teiler ist" +i);

das gemacht:

System.out.print(i+"+");

Aber dann gibt er 1+2+3+ aus, wie kriege ich das 3.Plus da weg?


----------



## Glückskeks (4. Nov 2010)

Lies dir jede Zeile des Programmes durch und überlege, was sie tut. Da sind ganz unnütze Dinge in deinem Code. Mit etwas Liebe und gesundem Menschenverstand wirst du deine Probleme lösen können.


----------



## Xerxes20 (4. Nov 2010)

Leider hänge ich schon 1 Woche dran und verstehe trotzdem nur Bahnhof. Ich finde leider auch nieamnden der mir das auch erklären kann, hätte gehofft, dass wir hier ein Programm zusammen basteln können damit ich es endlich verstehe :bahnhof:


----------



## Glückskeks (4. Nov 2010)

Hätt ich grundsätzlich auch Lust drauf...verstehen mein ich. Besonders was die Variable k betrifft: Kannst du mir sagen was sie tut? ^^


----------



## Xerxes20 (4. Nov 2010)

Hi,

die tut garnichts 

Ich war ein bisschen am rumexperimentieren, deswegen steht die noch da warscheinlich 

Okay sollen wir dann von ganz von vorne anfangen?

Ich beginne mal:


```
public class Perfekt   { 
    public static void main(String[] args)
    {
        int i;
        int k=1;
        int n;
		int w;
        
        
        System.out.print("Bitte eine Ganzzahl eingeben: ");
        n = In.readInt();
        
        while (n>0) {
		n=n-k;
		
		
		}
         
}		 
}
```

So der erste Schritt heißt ja nix anderes, als höre nicht auf n=n-k auszuführen bis n kleiner als 0 wird.

als nächstes hätte ich dann eine for Schleife eingebaut, die sagt, dass wenn n durch die in der schleife entstandenen zahlen geteilt wird, diese dann ausgegeben werden, falls sie keine Kommazahlen sind. 

Problem:

Wie mache ich das?


----------



## Glückskeks (4. Nov 2010)

Um eine int-Variable um 1 kleiner zu machen kannst du auch Speicherchen sparen und schlicht n--; oder --n; schreiben. Uhm, ich habe gerade erst erlesen, was eine perfekte Zahl ist. Um eine darauf zu prüfen muss ich also zunächst alle Teiler finden und sie summieren und anschließend prüfen, ob die Summe gleich der Zahl ist?
Dann braucht man also 2 Variablen: Die Zahl und die Summe.
Man muss jeden Wert bis zu dem der Zahl prüfen, also was schleifenartiges, while klingt gut.
Dann eine if-Prüfung, die Zahl und Summe vergleicht.

Das war's dann schon?


----------



## Xerxes20 (4. Nov 2010)

nicht ganz, das errechnen geht ja eigentlich leicht. Das schwierige ist die Ausgabe der Rechnung.
Also am Ende muss z.B. 6=3+2+1 stehen!


----------



## XHelp (4. Nov 2010)

Warum ist die Ausgabe schwierig? Wenn du die Teiler, wie du sagst, problemlos finden kannst, dann wirst du wohl doch schaffen ein 
	
	
	
	





```
System.out.print
```
 hinzuschreiben :bahnhof:


----------



## Xerxes20 (4. Nov 2010)

Das hört sich leichter an als es ist (für mich).

Ich bin wie gesagt ein totaler Anfänger in diesem Gebiet und die Ausgabe mit den Teilern habe ich schon versucht (siehe Beitrag 3)

Allerdings schaffe ich es nicht den Part:

System.out.println("Teiler ist " +i);


ind diesen:

System.out.println("Die Zahl: " +j+ " ist eine perfekte Zahl!");

zu integrieren. Wie denn auch? Wenn ich ein einfaches "i" dahinter setze spuckt er eine 6 einfach aus, wenn man eine 6 eingibt


----------



## XHelp (4. Nov 2010)

Macht auch sinn, weil nach der Schleife ist i genau so groß wie dein j.
Außerdem bringt die eine einzelne Zahl gar nichts, da es ja eine Menge von Teilern gibt.
Plan a: Teiler in eine Liste zu speichern und bei jeder neuen Zahl die Liste leeren. Dann hast du diese auch nach der Schleife.
Plan b, unschön, aber als copy&paste realisierbar: wenn die Zahl als perfekt erkannt wurde, nochmal die Teiler berechnen lassen und diese dabei in der gewünschten Form ausgeben.


----------



## Andi_CH (5. Nov 2010)

Xerxes20 hat gesagt.:


> Leider hänge ich schon 1 Woche dran und verstehe trotzdem nur Bahnhof. Ich finde leider auch nieamnden der mir das auch erklären kann, hätte gehofft, dass wir hier ein Programm zusammen basteln können damit ich es endlich verstehe :bahnhof:



Was hast du die ganze Woche gemacht??? SCNR

Wenn ich Code nicht verstehe starte ich den Debugger und schau mir an was so während dem Ablauf passiert. 
Bedingung um damit überhaupt anzufangen ist allerdings, dass man die Problemdomäne verstanden hat (das kann dir aber nur der ermöglichen, der dir den Auftrag gegeben hat) um zu wissen was man erwartet und dann Abweichungen festzustellen - das ist genau wie im realen Leben später.


----------



## noobadix (5. Nov 2010)

Okay, dein Programm braucht eine weitere Variable, die mehrere Werte speichern kann, deren Anzahl vorher nicht bekannt ist. Ein Vector bietet sich an, dem du die Teiler hinzufügst. Für die Ausgabe würde ich dann einen StringBuffer verwenden.


```
int inputZahl, summe;
Vector<Integer> teiler = new Vector<Integer>();

...//hier der ganze Rechenkram und bestimmen der Werte der drei Variablen und nun die Ausgabe:

StringBuffer sb = new StringBuffer();
sb.append(inputZahl + "ist eine perfekte Zahl, denn: "+inputZahl+" = ");
for(int index=0;index<teiler.size();index++){
    sb.append(teiler.elementAt(index)+"");
    if(index<teiler.size()-1) sb.append("+");
}
System.out.println(sb.toString());
```

Was ich bislang völlig vernachlässigt habe, sind Prüfungen der Werte, dazu solltest du dir noch Gedanken machen.


----------



## Landei (5. Nov 2010)

- ArrayList statt Vecor nehmen
- einfach immer Teiler und "+" an den StringBuilder hängen
- Das letzte "+" lässt sich dann mit sb.setLength(sb.getLength()-1)) beseitigen.


----------



## noobadix (5. Nov 2010)

Was ist an DEINER ArrayList besser als an MEINEM Vector, he? ^^


----------



## Xerxes20 (5. Nov 2010)

Wir dürfen leider keine Arrays benutzen, sowas kennen wir garnicht, deswegen verstehe ich deinen Code auch nicht


----------



## XHelp (5. Nov 2010)

Xerxes20 hat gesagt.:


> Wir dürfen leider keine Arrays benutzen, sowas kennen wir garnicht, deswegen verstehe ich deinen Code auch nicht



Dann musst du eben nicht alle einzelnen Teiler speichern, sondern direkt eine Ausgabe generieren (beim Teiler finden entweder an den StringBuilder oder nur String die Teiler dranhängen) und wenn es eine perfekte Zahl ist, dann einfach die generierte Ausgabe auf die Konsole schreiben.

@noobadix, ArrayList ist schneller und die Threadsicherheit vom Vektor braucht man hier wohl kaum.


----------



## Landei (5. Nov 2010)

noobadix hat gesagt.:


> Was ist an DEINER ArrayList besser als an MEINEM Vector, he? ^^



Sie ist schneller (da nicht synchronisiert).


----------



## noobadix (5. Nov 2010)

Xerxes20 hat gesagt.:


> Wir dürfen leider keine Arrays benutzen, sowas kennen wir garnicht, deswegen verstehe ich deinen Code auch nicht



CheGuevara dreht sich ja im Grabe um...nee, kleiner Spass.^^ Aber StringBuffer dürfte erlaubt sein, weil er nur eine Erleichterung für _meinString = meinString + " mal was neues"_ ist.
Denn irgendwo, irgendwie musst du die Teiler ja speichern, oder?


----------



## Xerxes20 (5. Nov 2010)

kann mir keiner das programm dazu ohne arrays kurz schreiben? Ihr seht doch ich habe gebe mir mühe aber es klappt einfach nicht!


----------



## XHelp (5. Nov 2010)

Poste mal was du bis jetzt hast... zumindestmal so, dass die perfekten Zahlen richtig erkannt werden. Dann lassen sich auch konkretere Ratschläge geben.


----------



## Andi_CH (5. Nov 2010)

Keine Arrays? Unbekannte Anzahl Werte speichern? Wie soll sowas gelöst werden? Da steh ich auch an.

Mir stellt sich da immer die Frage "What is he fishing for" - was will der da für eine Lösung sehen.

Ich nehme an rekursive Programmierung kennt ihr auch noch nicht?


----------



## XHelp (5. Nov 2010)

Andi_CH hat gesagt.:


> Kein Arryay? Unbekannte Anzahl Werte speichern? Wie soll sowas gelöst werden? Da steh ich auch an.



Du musst mit den Werten ja nicht arbeiten, d.h. die an einen String zu packen reicht völlig aus :bahnhof:


----------



## Andi_CH (5. Nov 2010)

hm - stimmt ja auch wieder - gleich ausgeben geht auch.


----------



## noobadix (5. Nov 2010)

Mmh, wie du selbst fest gestellt hast: Es ist ein simples Programm. Habt ihr schonmal was von Pseudocode-Verfahren gehört? Das ist ein Verfahren, bei dem man die Aktionen des gewünschten Programms von "sehr menschenlesbar" zu konkretem Code verändert.

Ich möchte eine Zahl gesagt bekommen. Vom höchsten Wert dieser Zahl möchte ich alle darunter liegenden bis Null prüfen, ob sie Teiler der Zahl sind und, wenn ja, ausgeben lassen und summieren und anschließend prüfen, ob die Summe gleich der Zahl ist.

Ich möchte eine int-Variable namens inputZahl einlesen und diese mit "=" ausgeben lassen. Während die Bedingung inputZahlKopie>0 erfüllt ist, soll inputZahlKopie um 1 dekrementiert werden und wenn inputZahl%inputZahlKopie==0, soll inputZahlKopie und, wenn inputZahlKopie nicht das letzte Element ist, auch ein "+" ausgegeben werden, außerdem soll inputZahlKopie dem Wert der int-Variablen summe hinzusummiert werden. Anschließend sollen die Werte inputZahl und summe verglichen und bewertet werden.

Wenn also 1 erreicht ist, brauchst System.out.print(" + ") nicht ausführen.


----------



## Xerxes20 (5. Nov 2010)

@XHelp:

siehe post 1

Da habe ich ein Programm, dass die Werte berechnet, aber den Rechenweg nicht angibt. Ich habe allerdings halbwegs geschafft dass die richtigen Teiler gefunden werden, nur ist die Ausgabe der Perfekten Zahl in der darauffolgenden Schleife und da kann ich das dann nicht mehr hinpacken!

Falls ich das heute nicht schaffen sollte, kann der Thread ruhig geschlossen werden, da ich dann keine Lust mehr habe mich damit rumzuschlagen, will endlich vorankommen, so bin ich ja in einer nicht endenden while schleife :noe:


----------



## XHelp (5. Nov 2010)

So ein wenig angelehnt an den Code vom 1. Post:

```
String s;
int k;
....
for () {
  s = "";
  for () {
    if (j%i)==0 {
      summe+=i;
      s+=i+"+";
    }
    ...
  }
  if (summe==j) {
    s = s.substr(0,s.length()-1);
    System.out.println(s+"="+j)
  }
}
```

(ohne es aber getestet zu haben)


----------



## Andi_CH (5. Nov 2010)

Ich wiederhole mich zum dritten mal heute:
Bitte zu Ende lesen - das Folgende ist NICHT abschätzig gemeint.

Programmieren beginnt mit Stift und Papier - bevor du nicht begriffen hast was die eigentliche Aufgabe ist, musst du nicht beginnen - das Begreifen einer Aufgabe ist der wichtigste und oft auch schwierigste Schritt überhaupt!
Beginn doch bitte damit.

Mein kurze Ausführung zu analyse Design und Impementation findest in einem anderenThread.

Noch was: Wenn wir hier die Lösung präsentieren hast du nichts dazugelernt.


----------



## Xerxes20 (5. Nov 2010)

Ich weiß was in der Aufgabe von mir verlangt wird, mir fehlt halt die Idee wie ich es umsetzen soll. Glaub mir ich habe mir schon genug Gedanken gemacht und irgendwann hat man halt keine Lust mehr, weil es keinen Sinn hat, wenn einem die Idee ausgehen.

Ich würde mich ja nicht hier melden, wenn ich noch ein paar Ideen auf Lager hätte


----------

