ISBN Berechnung JAVA

Crusade

Hack User
10 Dec 2015
447
200
#1
Hey, muss für die Uni ein Programm zur berechnung der Prüfziffer von ISBN10/13 schreiben, hab da aber ein problem mit genau der Methode die zur berechnung zuständig ist, finde meinen eigenen Fehler aber nicht.. Hat jemand eine idee?

Beispiele:
386680192-? z10 = 1⋅3 + 2⋅8 + 3⋅6 + 4⋅6 + 5⋅8 + 6⋅0 + 7⋅1 + 8⋅9 + 9⋅2 = 198 = 0 mod 11
383622862-? z10 = 1⋅3 + 2⋅8 + 3⋅3 + 4⋅6 + 5⋅2 + 6⋅2 + 7⋅8 + 8⋅6 + 9⋅2 = 196 = 9 mod 11

Bei mir kommt statt 198 nur 189 und statt 196 nur 164 raus.

Java:
public static long ueberpruefeISBN(long isbn) {

            long sum = 0;
            int i = 0;
          while(isbn >0) {
              sum +=  isbn % 10 * i;
              isbn /= 10;
              i++;

            } return sum;
 
7 Jan 2015
4,615
3,902
#2
Sorry aber irgendwie verstehe ich nicht wie du über deine Beispielrechnung auf diesen Code kommst?
Der macht doch ganz was anderes...
Du solltest über die einzelnen Ziffern iterieren und diese jeweils mit dem Index der Ziffer multiplizieren.
Java:
int sum = 0;
for(int i=0; i<isbn.length; i++) {
   sum += isbn[i] * i;
}
Ist am Handy und vermutlich mehr js als Java geschrieben, siehst als pseudo
 
Likes: Crusade

Logxn

Honorable
22 Jul 2016
1,528
1,796
#3
Sorry aber irgendwie verstehe ich nicht wie du über deine Beispielrechnung auf diesen Code kommst?
Der macht doch ganz was anderes...
Du solltest über die einzelnen Ziffern iterieren und diese jeweils mit dem Index der Ziffer multiplizieren.
Java:
int sum = 0;
for(int i=0; i<isbn.length; i++) {
   sum += isbn[i] * i;
}
Ist am Handy und vermutlich mehr js als Java geschrieben, siehst als pseudo

und nach der schleife: return sum % 11
dann kriegste da die prüfziffer raus.
 

Crusade

Hack User
10 Dec 2015
447
200
#4
verstehe ich nicht wie du über deine Beispielrechnung auf diesen Code kommst?
jetzt wo ich ihn mir nochmal durchlese weiß ich das auch nicht mehr lol. Hätte die Aufgabe vlt besser durchlesen sollen. Habs jetzt so ähnlich wie vorgeschalgen hinbekommen danke an euch zwei. Wir sollten halt die ISBN von der Dialog klasse als long übergeben und von der logischen Klasse ein String returnen.

Verbesserungsvorschläge?

Momentane Lösung :

Java:
public static String ueberpruefeISBN(long isbn) {

            int checkDigit = 0;
            for (long i = 9, n = isbn; i > 0; i--, n /= 10) {
                checkDigit += i * (n % 10);
            }
            checkDigit %= 11;

            if (checkDigit== 10){
                return "X";
            }

            return  " " + checkDigit;
        }
 
7 Jan 2015
4,615
3,902
#5
jetzt wo ich ihn mir nochmal durchlese weiß ich das auch nicht mehr lol. Hätte die Aufgabe vlt besser durchlesen sollen. Habs jetzt so ähnlich wie vorgeschalgen hinbekommen danke an euch zwei. Wir sollten halt die ISBN von der Dialog klasse als long übergeben und von der logischen Klasse ein String returnen.

Verbesserungsvorschläge?

Momentane Lösung :

Java:
public static String ueberpruefeISBN(long isbn) {

            int checkDigit = 0;
            for (long i = 9, n = isbn; i > 0; i--, n /= 10) {
                checkDigit += i * (n % 10);
            }
            checkDigit %= 11;

            if (checkDigit== 10){
                return "X";
            }

            return  " " + checkDigit;
        }
Java:
public static int checkISBN(String isbn) {
    int sum=0;
    
    for(int i=0; i<isbn.length(); i++) {
        int curNum = Character.getNumericValue(isbn.charAt(i));
        sum += (i+1) * curNum;
    }
    
    return sum%11;
}
So würde ich es machen, Java auf 4 Wochen online Kurs Niveau.
 

Logxn

Honorable
22 Jul 2016
1,528
1,796
#6
jetzt wo ich ihn mir nochmal durchlese weiß ich das auch nicht mehr lol. Hätte die Aufgabe vlt besser durchlesen sollen. Habs jetzt so ähnlich wie vorgeschalgen hinbekommen danke an euch zwei. Wir sollten halt die ISBN von der Dialog klasse als long übergeben und von der logischen Klasse ein String returnen.

Verbesserungsvorschläge?

Momentane Lösung :

Java:
public static String ueberpruefeISBN(long isbn) {

            int checkDigit = 0;
            for (long i = 9, n = isbn; i > 0; i--, n /= 10) {
                checkDigit += i * (n % 10);
            }
            checkDigit %= 11;

            if (checkDigit== 10){
                return "X";
            }

            return  " " + checkDigit;
        }
Warte warte warte warte.
Du führst eine Berechnung aus und erwartest in deiner "logischen Klasse" nen String?????.
Das hört sich sehr sehr falsch an.

Nimm die Lösung von Mantarochen Mantarochen und arbeite damit dann in deiner Logik-Klasse.
if(ueberpruefeISBN(...) == 10) => bla.

aber bitte keinen string....


So habe ich das gerade in 2min hingerotzt.
Aber so würde ich mir das vorstellen, vorrausgesetzt ich kenne die Prüfziffer

C#:
        static void Main(string[] args)
        {
            string isbn = "344619313"; // Hier ist eine standard ISBN Nummer ohne Prüfziffer

            if(checkISBN(isbn) == 8) // Vollständige ISBN wäre "ISBN 3-446-19313-8"
            {
                Console.WriteLine("Gültige ISBN Nummer");
            }

            while (true) ;
        }

        static double checkISBN(string isbn)
        {
            int sum = 0;
            for(int i = 0; i < isbn.Length; i++)
            {
                int currNum = int.Parse(isbn[i].ToString());
                sum += ((i + 1) * currNum);
            }

            return sum % 11;
        }

Also mein Ablauf wäre wie folgt:

1. Nimm eine ISBN nummer als string an
(OPTIONAL) entferne alle "-"
2. Entferne die letzte Zahl des strings. (Das ist die Prüfziffer)
3. Berechne nun die Prüfziffer mithilfe der obigen Funktion und schau ob sie mit der von dir entfernten Prüfziffer von Schritt 2 übereinstimmt.
4. Wenn ja => gültige ISBN
 
Last edited:

Crusade

Hack User
10 Dec 2015
447
200
#7
Nimm eine ISBN nummer als string an
Hätte auch lieber den string übergeben und dann die sachen rausgepickt aber die Aufgabenstellung erlaubt das leider nicht..
"Übergeben Sie der Methode die zu prüfende Zahl als long-Zahl und geben Sie die errechnete Prüfziffer als String zurück"
Ich hab dann jetzt aufgrund der kritik die Methode ein int returnen lassen und dann in der Dialog Klasse bei 10 einen string mit "X" ausgeben lassse.. Denke das ist das geringste übel dass ich mit der Aufgabenstellung hinbekomme.

Hab leider erst vor nem monat mit java aufgrund des Studiums angefangen und mache daher noch behinderte Fehler x)
 
7 Jan 2015
4,615
3,902
#8
Wenn du es als Long nehmen musst macht der Kram mit modulo 10 und /10 auch Sinn.
https://stackoverflow.com/a/3389287
Beachte dass du die Reihenfolge ändern musst, oder den Index anders berechnest in der Schleife.

sum += number * (ISBN.length() - i);
 
7 Jan 2015
4,615
3,902
#9
Crusade Crusade hier mal ne etwas sauberer Umsetzung von deinen Vorgaben:
Java:
public class Main
{
    public static void main(String[] args)
    {
        System.out.print(ISBN.checkDigit(344619313));
    }
}
public class ISBN
{
    private static int length(long number) {
        long x = 1;
        int length = 0;
        while(x <= number) {
            x *= 10;
            length++;
        }
        return length;
    }
  
    public static int checkDigit(long isbn) {
        int sum=0;
        int length = length(isbn);
        for(int i=0; i<length; i++) {
            int curNum = (int) (isbn % 10);
            isbn /= 10;
            sum += (length - i) * curNum;
        }
        return sum%11;
    }
}
Du könntest die helper methode 'getLength(long number)' auch rauswerfen, wenn du sicher bist dass deine inputs immer Länge = 9 haben. Da aber kein Check drinnen ist und ich sowas statisches hasse ists mit drinnen.

Hier noch ein Ansatz der eher OOP ist. Im Konstructor könntest du noch den Check für die Länge einbauen. Dann kannst du die length methode rausnehmen und eine statische länge nehmen.

Java:
public class Main
{ 
    public static void main(String[] args)
    {
        ISBN isbn = new ISBN(344619313);
        System.out.print(isbn.checkDigit());
    }
}

public class ISBN
{
    private long isbn;

    public ISBN(long isbn) {
        this.isbn = isbn;
    }

    private int length() {
        long x = 1;
        int length = 0;

        while(x <= this.isbn) {
            x *= 10;
            length++;
        }

        return length;
    }
  
    public int checkDigit() {
        int sum=0;
        int length = this.length();

        for(int i=0; i<length; i++) {
            int curNum = (int) (this.isbn % 10);
            isbn /= 10;
            sum += (length - i) * curNum;
        }

        return sum%11;
    }
}