Java: Probleme, Fehler, Fragen

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Java: Probleme, Fehler, Fragen

      Hallo MCore, ich komme bei einer Aufgabe nicht mehr weiter und weiß nicht, wie ich es geschickt lösen soll.

      Aufgabe schrieb:


      Aufgabe 4.3 (C):
      In der vorherigen Aufgabe wurde die Summe aller auf 1 gesetzter Bits gezählt. Für diese Aufgabe sollen sie nun eine Methode static int countLongestSequenceOfBitsSetToOne(int bits) implementieren, welche, die Länge der längsten Folge auf 1 gesetzter Bits, in der Binärdarstellung einer Ganzzahl bits, ermittelt.

      Test:
      Zahl: 3309
      Zahl in Bits: 00001100 11101101
      Ergebnis: 3


      Code

      Quellcode

      1. public class Bitoperationen {
      2. /**
      3. * Die Methode prüft, ob der Bit an einer bestimmten Position auf 1 gesetzt ist
      4. * @param bits gibt die Zahl an, bei der die Bits geprüft werden sollen
      5. * @param bitPosition gibt die Position des Bits an, der geprüft werden soll
      6. * @return liefert "true", wenn der bit an der Position bitPosition 1 ist. Wenn nicht, liefert return "false"
      7. */
      8. static boolean checkIfBitIsSet(int bits, int bitPosition){
      9. return ((1<<(bitPosition-1)) == (bits & (1<<(bitPosition-1))));
      10. }
      11. /**
      12. * Die Methode soll bei einer ganzen Zahl die Summe aller Bits auf 1 zurückgeben
      13. * @param bits ist die ganze Zahl, auf die die Methode angewendet wird
      14. * @return gibt die Summe aller Bits auf 1 aus
      15. */
      16. static int countBitsSetToOne(int bits){
      17. int n=1;
      18. int sum=0;
      19. while(n<17){
      20. if (checkIfBitIsSet(bits,n)==true){
      21. sum=sum+1;
      22. }
      23. else sum=sum;
      24. n++;
      25. }
      26. return sum;
      27. }
      28. /**
      29. * Diese Methode gibt die längste Folge von auf 1 gesetzten Bits als Zahl an
      30. * @param bits ist die Zahl, auf der die Methode eingesetzt wird
      31. * @return gibt die Summe aus
      32. */
      33. static int countLongestSequenceOfBitsSetToOne(int bits){
      34. int a=1;
      35. int b=1;
      36. int sum=0;
      37. while(a<17){
      38. if (checkIfBitIsSet(bits,a)==true){
      39. while(checkIfBitIsSet(bits,b)==true){
      40. sum=sum+1;
      41. b++;
      42. }
      43. }
      44. else ;
      45. a++;
      46. }
      47. return sum;
      48. }
      49. public static void main(String[] args) {
      50. //Aufgabe 4.3 a
      51. System.out.println("Test von Aufgabe 4.3(a):");
      52. System.out.println("Beispiel 1: " + checkIfBitIsSet(1, 1));
      53. System.out.println("Beispiel 2: " + checkIfBitIsSet(2, 1));
      54. System.out.println("eigenes Beispiel:" +checkIfBitIsSet(8,4));
      55. //Aufgabe 4.3 b
      56. System.out.println("Test von Aufgabe 4.3(b):");
      57. System.out.println("Beispiel 1: " + countBitsSetToOne(1));
      58. System.out.println("Beispiel 2: " + countBitsSetToOne(3));
      59. System.out.println("Beispiel 3: " + countBitsSetToOne(17));
      60. System.out.println("Beispiel 4: " + countBitsSetToOne(21845));
      61. //Aufgabe 4.3 c
      62. System.out.println("Test von Aufgabe 4.3(c):");
      63. System.out.println("Beispiel 1: " + countLongestSequenceOfBitsSetToOne(1));
      64. System.out.println("Beispiel 2: " + countLongestSequenceOfBitsSetToOne(3));
      65. System.out.println("Beispiel 3: " + countLongestSequenceOfBitsSetToOne(17));
      66. System.out.println("Beispiel 4: " + countLongestSequenceOfBitsSetToOne(3309));
      67. }
      68. }
      Alles anzeigen



      Meine Überlegung ist folgende:
      Die Methode überprüft, ob an der Stelle a die Methode checkIfBitIsSet(bits, a) ein true liefert. Wenn es true liefert, probiert die Methode es erneut und testen mit der While schleife die nächste Stelle und bricht ab, wenn keine 1 mehr da steht. Sum ist dann die länge der Sequenz, die aus den 1en besteht.
      Mein Problem ist, dass ich so nur die erste Sequenz von Einsen kriege. Es könnte ja sein, dass am Anfang eine 1 steht und in der Mitte eine Sequenz von 3 einsen. Diese Sequenz von 3 Einsen soll ausgegeben werden, es wird aber die erste Eins ausgegeben (siehe "Beispiel 4: "+countLongestSequenceOfBitsSetToOne(3309)).
      Hat jemand eine Idee, wie ich weiter mache und kann mir helfen?

      Ich bin nun auf die Idee gekommen Arrays zu benutzen und die Methode sieht im Moment so aus:

      Quellcode

      1. static int countLongestSequenceOfBitsSetToOne(int bits){
      2. int sum = 0;
      3. int i = 1;
      4. int arr[] = new int[17]; // arr ist ein Array mit der Länge 17, da das erste Element eine 0 ist.
      5. //Die For-schleife legt auf die Bitposition 1-16 auf den arr[i] ein true,
      6. //wenn an der Position i eine 1 steht.
      7. for(i; i<arr.length; i++)
      8. arr[i] = checkIfBitIsSet(bits,i);
      9. return sum;
      10. }
      Alles anzeigen

      Nun bin ich stark am überlegen, wie ich die längste Sequenz herrausfinde, wo die Arrays den selben Wert (hier "true") haben.

      Ich kann es natürlich ganz umständlich machen mit:

      Quellcode

      1. If(arr[1]==arr[2]) return sum=2;

      und so alle Kombinationen durchgehen. Das wäre aber total umständlich und es geht sicherlich viel eleganter.

      oder in einer While Schleife:

      Quellcode

      1. while(arr[i]==arr[i+1]){
      2. sum=sum+1;
      3. i++;
      4. }
      Da hab ich aber wieder das selbe Problem, dass ich die Sequenzen mitten drin nicht beachte.
    • Werbung zur Unterstützung des Forums ( Bitte AddBlocker deaktivieren )

    • Ich mache aus einer ganzen Zahl, in diesem Fall 3309 eine Bitzahl und überprüfe jedes einzelne Bit. Wenn du es etwas abänderst, sollte es zu deiner Aufgabenstellung passen. Ergebnis ist, wie von dir oben genannt, natürlich 3.

      Der Code ist allerdings in C++ geschrieben.

      Quellcode

      1. static int countLongestSequenceOfBitsSetToOne(int zahl)
      2. {
      3. int bitsInRow = 0;
      4. int tempBitsInRow = 0;
      5. bool inRow = false;
      6. for(int i=(sizeof(zahl) * 8) - 1; i >= 0;i--)
      7. {
      8. if((zahl & (1 << i)) > 0)
      9. {
      10. if(inRow == false)
      11. {
      12. inRow = true;
      13. tempBitsInRow = 1;
      14. }
      15. else
      16. {
      17. tempBitsInRow++;
      18. }
      19. }
      20. else
      21. {
      22. inRow = false;
      23. if(tempBitsInRow > bitsInRow)
      24. {
      25. bitsInRow = tempBitsInRow;
      26. }
      27. }
      28. }
      29. return bitsInRow;
      30. }
      Alles anzeigen


      Erklärung zum Code:

      int i = (sizeof(zahl)*8) - 1 ergibt die Anzahl an Bits.
      sizeof(zahl) bzw. eher sizeof(int) (in diesem Fall int, da "zahl" ein Integer ist) ergibt 4.
      4*8 = 32
      32 - 1 = 31. (Da von 0 angefangen also ebenfalls 32 :) )

      Meine Bitzahl wäre also 00000000 00000000 00001100 11101101. Vorne rangestellt sind halt die Nullen, welche aber nicht weiter stören.

      if((zahl & (1 << i)) > 0) überprüft das momentane Bit darauf, ob es > 0, also 1 ist.

      Den Rest kannst du dir ja eigentlich denken, der sollte sofort leserlich und verständlich sein. Ansonsten frag in der Chatbox nach und ich werde es denn, wenn ich es lese, hier editieren. :)
    • Quellcode

      1. public static int countLongestSequenceOfBitsSetToOne(int n) {
      2. int max = 0, cur = 0;
      3. for (int i = 1; i <= n; i *= 2) {
      4. if ((n & i) == i) {
      5. cur++;
      6. if (cur > max) {
      7. max = cur;
      8. }
      9. } else {
      10. cur = 0;
      11. }
      12. }
      13. return max;
      14. }
      Alles anzeigen


      Der Teil mit dem "max = cur" könnte man noch optimieren, eigentlich muss man das nur wieder wenn cur auf 0 gesetzt wird und am Ende (falls der Fall nie eintritt) machen.
    • @dowhile:
      So ähnlich habe ich es nachher auch geschafft, jedoch stehe ich nun vor ein neues Problem:

      Ich soll eine Methode entwickelt, die bei einer Zahl "int bits" den Binärcode nach einem bestimmten Muster "int bitPattern" überprüft.
      Beispiel:
      bits = 2641
      In Binärcode wäre bits 0000100110011101
      bitPattern = 110

      Man sieht, dass das Muster 110 in 2641 enthalten ist:
      0000100110011101
      Das es hier zweimal drin ist, ist egal - hauptsache es ist drin.

      Mein Problem ist eben, dass die 110 eine Ganzzahl ist. Darum muss ich es irgendwie schaffen int bitPattern (hier 110) in eine andere Ganzzahl zu wandeln, deren Binärcode wie 0...0110 aussieht also am Ende die Zahlenfolge 110 hat. In diesem Beispiel wäre die gesuchte Zahl die Zahl 6.
    • Hi,

      ich hab gar nicht gesehen, dass das Thema schon zwei Tage alt war. :|

      Mein Problem ist eben, dass die 110 eine Ganzzahl ist. Darum muss ich es irgendwie schaffen int bitPattern (hier 110) in eine andere Ganzzahl zu wandeln, deren Binärcode wie 0...0110 aussieht also am Ende die Zahlenfolge 110 hat. In diesem Beispiel wäre die gesuchte Zahl die Zahl 6.

      Hm, meine erste Idee wäre das:

      Quellcode

      1. [/COLOR] public static void main(String[] args) { int bitPattern = 110;
      2. int res = 0;
      3. int i = 1;
      4. while (bitPattern > 0) {
      5. res += ((bitPattern % 10 == 1) ? i : 0);
      6. bitPattern /= 10;
      7. i *= 2;
      8. }
      9. System.out.println(res);
      10. }
      Alles anzeigen
    • Vielen Dank! Es stimmt auf jedenfall und ich kann es benutzen, muss es nur noch genauer verstehen.
      "res += ((bitPattern % 10 == 1) ? i : 0);" Ist mir unklar
      Kannst du in der ersten Zeile der while Schleife das ":"; "+=" und das "?" erläutern? Das += hab ich schonmal gesehen, wurde aber nur kurz gezeigt, und nicht weiter erläutert/benutzt.
    • Btw: Hab mal den Thread für kleine Probleme, Fehler oder Fragen bzgl. Java angepasst.


      Hätte eine andere Frage bzw. ein nur kleines Problemchen:

      Quellcode

      1. public class AufgabeZwei {
      2. //aus 5.1
      3. static float[] createFloatArrayWithNumbers(int count){
      4. float[] numbers = new float[count];
      5. for(int i = (numbers.length-1); i>=0; i--){
      6. numbers[i]=(5.5f+i);
      7. }
      8. return numbers;
      9. }
      10. static boolean isSorted(float[] numbers, boolean ascending){
      11. boolean ausgabe;
      12. for(int i=(numbers.length-1); i<=0; i--){
      13. if(ascending == true){
      14. if((numbers[i] <= numbers[i-1])=true){
      15. ausgabe = true;
      16. }
      17. else ausgabe = false;
      18. }
      19. if(ascending == false){
      20. if((numbers[i] >= numbers[i-1])=true){
      21. ausgabe = true;
      22. }
      23. else ausgabe = false;
      24. }
      25. }
      26. return ausgabe;
      27. }
      28. public static void main (String[] args){
      29. System.out.println(isSorted(createFloatArrayWithNumbers(5), true));
      30. }
      31. }
      Alles anzeigen


      Der Compiler spuckt folgende Fehler aus:

      AufgabeZwei.java:30: error: unexpected type
      if((numbers <= numbers[i-1])=true){
      ^
      required: variable
      found: value

      AufgabeZwei.java:36: error: unexpected type
      if((numbers[i] >= numbers[i-1])=true){
      ^
      required: variable
      found: value
      2 errors

      In der if Anweisung will ich vergleichen, ob der Array numbers an der Stele i <= bzw >= dem Array davor ist. Sollte doch eigentlich stimmen.
    • Weiß zwar nicht wies in java is aber 1 denke ich muss du das ganze nicht noch mal mit true vergleichen, da die expression ja true oder false zurück liefert und 2. wenn dann mit == und nicht nur = was ja sonst eine zuweisung wäre. So versuchst du dem Ergebnis der expression den wert true zuzuweisen. Daher auch die Meldung das er eine variable und keinen wert braucht.

      Gesendet von meinem GT-I9300
    • Solche Fehler macht jeder mal, davon nicht unterkriegen lassen. Das sind übrigens auch die simplen Fehler, an denen man so lange sitzt, um sie zu beheben. :D

      EDIT: Du kannst natürlich, wie ihr beiden oben geschrieben habt, das true weglassen. Falls du es aus Gründen der Codelesbarkeit trotzdem machen willst, musst du == true abfragen, und nicht = true. Ist aber veraltet und sinnlos, da du sonst im Normalfall true == true bzw. false == true abfragst, und true ist auch true, ohne das abgefragt wird, ob true = true ist. *eine dunkle Wand an Verwirrung macht sich breit* :D