java-proggen: rekursionsaufruf funzt noch nicht

    • sholvar
      sholvar
      Bronze
      Dabei seit: 18.01.2005 Beiträge: 4.826
      Hi. Ich progge gerade eine Methode die jedes duale bit einer integer-variable wiedergeben soll.

      sie ist compilierbar, aber irgendwie funzt die ausgabe noch nicht. ich hab noch nie ne rekursion in java geschrieben und find den fehler jetzt nicht. das könnte auch daran liegen, dass ich seit gestern mittag an dieser methode sitze und nurnoch 0en und 1en sehe.

      wäre echt dankbar wenn mal einer 5 mins opfern könnte und gucken warum beim ausführen nach der eingabe einer zahl wie "10" (dezimale zehn) nicht als ausgabe kommt "0...0001010" (32 stellen)

      code:
          public String makemebinary(int z1, int i)
          {
      
             
             b = ((z1 & (1 << i)) == 0);
             if (i==31)
             {
                 if (b)
                 {
                      a=  "0";
                      return a;
                 }else{
                      a =  "1";
                      return a;
                 }
             }else{
                 a = (makemebinary(z1,++i) ) +  a;
                 return a;
             }
          }



      Exceptionausgabe in der Konsole: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space


      naja, lieber nochmal die ganze klasse falls die nötig ist und der fehler garnicht in der methode makemebinary ist:


      code:
      import java.io.*;
      
      /**
       * Beschreibung: testet die Funktionsfaehigkeit der Methode makemebinary
       * @author: E. Bernoth
       * @version: 1.0
       */
      
      public class makemebinarytestclass2
      {
          private int z1;
          //a = Ausgabevariable der Binaerzahl. Das Zusammensetzen geht in String am einfachsten, daher hab ich diesen Typ gewaehlt.
          private String a="";
          private boolean b;
          private int i = 0;
          //konstruktor
          public makemebinarytestclass2()
          {
      
          }
          
          public static void main(String args [])
          throws IOException
          {
             makemebinarytestclass2 bc = new makemebinarytestclass2();
             
             bc.start();
          }
          
          public void start()
          throws IOException
          {
             BufferedReader din = new BufferedReader (
                                  new InputStreamReader (System.in));
             System.out.println("Umwandler");
             System.out.println("\n\n wandelt eine Dezimalzahl in eine Binaerzahl um.\n");
             System.out.print("Dezimalzahl eingeben: ");
             z1 = Integer.parseInt(din.readLine());
             makemebinary(z1,i);
             System.out.println("\n");
             System.out.print("umgewandelt in binaer ergibt das: "+ a);
          }
          public String makemebinary(int z1, int i)
          {
      
             
             b = ((z1 & (1 << i)) == 0);
             if (i==31)
             {
                 if (b)
                 {
                      a=  "0";
                      return a;
                 }else{
                      a =  "1";
                      return a;
                 }
             }else{
                 a = (makemebinary(z1,++i) ) +  a;
                 return a;
             }
          }
      }
  • 32 Antworten
    • dayero
      dayero
      Bronze
      Dabei seit: 26.02.2005 Beiträge: 1.723
      hm, mir fällt zunächsteinmal auf, daß "a" nur ein einziges mal gesetzt wird, nämlich im innersten aufruf.
      danach wird aufgelöst

      funktion(31) a= "1" (oder "0")
      funktion(30) a="1" + ""
      funktion(29 a="1" + ""

      und so weiter.
      deine ausgabe könnte als auch bei funktionierendem programm nur "1" oder "0" sein.

      im übrigen: hast du die funktion mal "manuell" getestet, also einfach makemebinary(10, 0) aufgerufen? mal mit kleineren i probiert?

      sehr intuitiv finde ich übrigens, daß der boolean null=true und eins=false ist. :D
    • dusterl
      dusterl
      Bronze
      Dabei seit: 14.07.2006 Beiträge: 2.089
      Ist das unnötige Verpacken in Klassen und die Rekursion in der Aufgabenstellung gefordert? Das macht alles viel komplizierter, als es eigentlich nötig ist.
      Die Funktion als statische Methode auszulagern wäre viel einfacher.
    • FastFourier
      FastFourier
      Bronze
      Dabei seit: 04.11.2005 Beiträge: 804
      Die Abbruchbedingung und der Rekursionsschritt sind falsch wie dayero ja schon gesagt hat. Im Rekursionsschritt muss zurückgegeben werden Rekursion+Ziffer und im Abbruch-Fall nur die Ziffer.
      Der Heap-Fehler ist allerdings seltsam. Er scheint am Ende der Rekursion aufzutreten... ich vermute es hat was damit zu tun, dass a eine globale Variable ist. Für die Rekursion sollte da ein lokaler String sein...
    • TerminatorJAG
      TerminatorJAG
      Bronze
      Dabei seit: 16.05.2005 Beiträge: 307
      a muss in der Rekursiven Methode durch ne lokale Variable ersetzt werden, wie schon erwähnt.
      Was machst du da eigentlich bei der Berechnung von b?
    • FastFourier
      FastFourier
      Bronze
      Dabei seit: 04.11.2005 Beiträge: 804
      Original von TerminatorJAG
      Was machst du da eigentlich bei der Berechnung von b?
      Das ist schon richtig. b gibt an ob das i-te Bit gesetzt ist oder nicht.
    • TerminatorJAG
      TerminatorJAG
      Bronze
      Dabei seit: 16.05.2005 Beiträge: 307
      Was genau macht den z1 &(1<<i)?
      Bin mit den Operatoren nicht mehr ganz fit. << ist bitshift aber was ergibt sich daraus als resultat des gesamt ausdruck?
    • FastFourier
      FastFourier
      Bronze
      Dabei seit: 04.11.2005 Beiträge: 804
      Shift 1 um i AND Zahl -> i-tes Bit der Zahl
    • TerminatorJAG
      TerminatorJAG
      Bronze
      Dabei seit: 16.05.2005 Beiträge: 307
      Thx. Hätte erwartet, dass die Ausdrücke einzeln ausgewertet werden, dann wären ja beide immer true außer bei z1 = 0.
    • dusterl
      dusterl
      Bronze
      Dabei seit: 14.07.2006 Beiträge: 2.089
      Original von TerminatorJAG
      Thx. Hätte erwartet, dass die Ausdrücke einzeln ausgewertet werden, dann wären ja beide immer true außer bei z1 = 0.
      Du verwechselt das mit '<' und '&&'. '<<' und '&' sind keine logischen Operatoren sondern arbeiten auf Bit-Ebene.
    • TerminatorJAG
      TerminatorJAG
      Bronze
      Dabei seit: 16.05.2005 Beiträge: 307
      Als ich noch JAVA gelernt habe, konnte man '&' auch als logischen Operator verwenden. Kann sein, dass das vom Compiler im Zusammenhang mit bitshift entsprechend anders interpretiert wird.
    • dusterl
      dusterl
      Bronze
      Dabei seit: 14.07.2006 Beiträge: 2.089
      Original von TerminatorJAG
      Als ich noch JAVA gelernt habe, konnte man '&' auch als logischen Operator verwenden. Kann sein, dass das vom Compiler im Zusammenhang mit bitshift entsprechend anders interpretiert wird.
      Die Variablen sind hier aber nicht vom Typ Boolean. Daher ist das hier ein bitweises Und und kein logisches Und.
    • BlackBull
      BlackBull
      Bronze
      Dabei seit: 20.07.2006 Beiträge: 507
      Man kann sich es auch extrem kompliziert machen :D .

      Hab auch Java in der Schule und brauchte letzens ne Binärzahl aus ner Dezimalzahl.

      Das war mein Ergebnis nach geschätzen 2 Minuten ^^.

      code:
      public static String changetoString(int x){
      		String s = "";
      		int y = 128;
      		while (y != 0) {
      			if (x/y >= 1) {
      				s = s + '1'+ ' ';
      				x = x - y;}
      			else
      				s = s + '0'+ ' ';
      		y= y/2;
      		} 
      		return s;
      	}


      y hängt halt davon ab, was deine maximale größe bei x ist ist, im zweifel mach es riesig groß....
    • sholvar
      sholvar
      Bronze
      Dabei seit: 18.01.2005 Beiträge: 4.826
      code:
      public static String getdualdarstellungvon(int z1)
          {
                String Hans = "";
                for (int i = 31; i>=0; i--){
                     if ((z1 & (1 << i))!= 0){
                          Hans += 1;
                     }else{
                          Hans += 0;
                     }
                }
                return Hans;
          }


      so hab ich das jetzt gelöst.

      Danke für die Hilfe, aber die Jungs aus dem Jahrgang höher waren einfach schneller =)

      Ich würde es trotzdem lieber rekursiv lösen, aber das kann ich ja mal machen, wenn ich zuviel Freizeit hab...
    • TerminatorJAG
      TerminatorJAG
      Bronze
      Dabei seit: 16.05.2005 Beiträge: 307
      Die Variablen sind hier aber nicht vom Typ Boolean. Daher ist das hier ein bitweises Und und kein logisches Und.

      Bei C(++) ist jede Zahl !=0 True und 0 false, weils bei C keine echten bools gibt, von daher halt die verwechselung, hatte nicht gedacht das es bei Java anders ist, wobei ichs nie getestet habe.
    • BlackBull
      BlackBull
      Bronze
      Dabei seit: 20.07.2006 Beiträge: 507
      Original von sholvar
      code:
      public static String getdualdarstellungvon(int z1)
          {
                String Hans = "";
                for (int i = 31; i>=0; i--){
                     if ((z1 & (1 << i))!= 0){
                          Hans += 1;
                     }else{
                          Hans += 0;
                     }
                }
                return Hans;
          }


      so hab ich das jetzt gelöst.

      Danke für die Hilfe, aber die Jungs aus dem Jahrgang höher waren einfach schneller =)

      Ich würde es trotzdem lieber rekursiv lösen, aber das kann ich ja mal machen, wenn ich zuviel Freizeit hab...
      In viele Fällen ist ne Rekursion die elegantere Lösung, aber da durch Integer eh auf 4 Byte begränzt bist und dadurch die maximale Anzahl der durchläufe kennst, solltest du dir die Zeit lieber sparen.
      Wenn du mit so ner einfachen Methode so viel Zeit verbringst, dauert ein ganzes Projekt mir paar Klassen ja Wochen. :P

      Mich würd auch noch interessieren, für was du das Zeug brauchst ?
      Schule,LK o. GK, Studium, Azubi ?
    • TheOneAndOnlyMarkus
      TheOneAndOnlyMarkus
      Bronze
      Dabei seit: 20.02.2006 Beiträge: 3.784
      Ich weiß garnicht wieso hier alle eine Rekusion benutzen wollen.

      1. liegt hier keine strukturell rekursive Datenstruktur vor,
      2. wäre das Umwandeln des Problems in ein generativ rekursives Problem aufwendiger (und damit auch weniger 'elegant') als eine iterative Lösung und
      3. wäre es auch noch langsamer

      Sieht jemand hier einen Vorteil das generativ rekursiv zu lösen?
    • dusterl
      dusterl
      Bronze
      Dabei seit: 14.07.2006 Beiträge: 2.089
      Original von TerminatorJAG
      Die Variablen sind hier aber nicht vom Typ Boolean. Daher ist das hier ein bitweises Und und kein logisches Und.

      Bei C(++) ist jede Zahl !=0 True und 0 false, weils bei C keine echten bools gibt, von daher halt die verwechselung, hatte nicht gedacht das es bei Java anders ist, wobei ichs nie getestet habe.
      In C/C++ wäre das einzelne '&' aber genausowenig ein logisches, sondern ein bitweises Und.
      Das sind schlichtweg zwei paar Schuhe:

      code:
      #include <iostream>
      
      int main(){
      	int c = 6;
      	int d = 1;
      	std::cout<<(c&d)<<std::endl;
      	std::cout<<(c&&d)<<std::endl;
      	return 0;
      }
      
      Output:
      
      0
      1
      
      
    • sholvar
      sholvar
      Bronze
      Dabei seit: 18.01.2005 Beiträge: 4.826
      ... ich wäre so froh, wenn ich wenigstens einmal in wenigstens einem thread sogar von mir erstellt wurde das letzte Wort haben könnte... warum muss immer nochwas gesagt werden, wenn klar ist, dass der Thread beendet ist?
      Der Ziegenproblemthread geht auch schon wieder 1,5 Seiten obwohl das geklärt ist...

      naja... egal... xD
    • Seahake
      Seahake
      Bronze
      Dabei seit: 28.07.2005 Beiträge: 387
      Original von sholvar
      code:
      public static String getdualdarstellungvon(int z1)
          {
                String Hans = "";
       ...
                         Hans += 1;
      ...
                          Hans += 0;
                }
                return Hans;
          }

      ...

      Das funktioniert, das du zu einem String eine Integerzahl addierst?

      Die rekursive Lösung fehlt aber noch:

      code:
      function make_binary_output ( zahl  : in integer ;
                                    level : in integer := 0 ) return string is
      
        mystring : string ( 1..1 ) := "0" ;
      
      begin
           if ( ( zahl mod 2 ) = 1 )
           then
               mystring := "1" ;
           end if ;
      
           if ( level = 31 )
           then
               return mystring ;
           else
               return make_binary_output ( zahl  => zahl / 2 ,
                                           level => level + 1 ) & mystring ;
           end if ;
      
      end make_binary_output ;
      
      
    • 1
    • 2