Avatar billede theboy Nybegynder
04. august 2003 - 23:00 Der er 15 kommentarer og
1 løsning

spørgsmål om konventering

Kan man med en funktion sikre sig mod at det man indtaster i en prompt er et tal, og hvis det ikke er at man så få en besked om at det ikke er et tal man har indtastet?
Hvordan vil den se ud?
Avatar billede arne_v Ekspert
04. august 2003 - 23:02 #1
Sagtens der er flere forskellige metoder.

Du kan bl.a. læse en String og teste om alle tegn er tal.
Avatar billede arne_v Ekspert
04. august 2003 - 23:02 #2
Her er noget kode der tester 3 forskellige måder:

public class IntegerTest {
    private static final int antal = 1000000;

    private static final String goodtext = "12345";
    private static final String badtext = "12345a";

    private static void test(String text) {
        long start1 = System.currentTimeMillis();
        for (int i = 0; i < antal; i++) {
            int tal = test1(text);
        }
        long stop1 = System.currentTimeMillis();
        long start2 = System.currentTimeMillis();
        for (int i = 0; i < antal; i++) {
            int tal = test2(text);
        }
        long stop2 = System.currentTimeMillis();
        long start3 = System.currentTimeMillis();
        for (int i = 0; i < antal; i++) {
            int tal = test3(text);
        }
        long stop3 = System.currentTimeMillis();
        System.out.println("test 1 (try/catch)  = " + (stop1 - start1));
        System.out.println("test 2 (homemade)= " + (stop2 - start2));
        System.out.println("test 3 (isDigit()) = " + (stop3 - start3));
    }
    private static int test1(String s) {
        try {
            return Integer.parseInt(s);
        } catch (NumberFormatException e) {
            return -1;
        }
    }
    private static int test2(String s) {
        for (int j = 0; j < s.length(); j++) {
            if (s.charAt(j) < '0' || s.charAt(j) > '9') {
                return -1;
            }
        }
        return Integer.parseInt(s);
    }
    private static int test3(String s) {
        for (int j = 0; j < s.length(); j++) {
            if (!Character.isDigit(s.charAt(j))) {
                return -1;
            }
        }
        return Integer.parseInt(s);
    }
    public static void main(String[] args) {
        System.out.println("All good:");
        test(goodtext);
        System.out.println("All bad:");
        test(badtext);
    }
}
Avatar billede theboy Nybegynder
04. august 2003 - 23:03 #3
Jeg takker
Avatar billede arne_v Ekspert
04. august 2003 - 23:04 #4
De returnerer så -1 hvis det ikke er et tal.
Avatar billede twm Nybegynder
04. august 2003 - 23:06 #5
boolean isInteger(String strTest)
{
  try{
      new Integer(strTest);
      return true;
  }
  catch(NumberFormatException e)
  {
    return false;
  }
}

Uden at have testet burde denne test funktion virke til at kontrollere om en streng indeholder en integer værdi
Avatar billede twm Nybegynder
04. august 2003 - 23:09 #6
Ups lidt sent på den! :D
Avatar billede theboy Nybegynder
04. august 2003 - 23:10 #7
Det ser nemt ud "twm". Det vil gøre det nemmere, men holder det hele vejen?
Avatar billede arne_v Ekspert
04. august 2003 - 23:15 #8
Det er jo næsten samme teknik som i test1 i mit eksempel (han returnerer bare
true/false ikke værdien - mit kode eksempel er en hastigheds test så det var
for langsomt at konvertere strengen 2 gange - først for at teste - siden
for at bruge værdien).

Den virker udmærket.

Hvis man er meget hastighed fikseret, så ville man bruge:
  Integer.parseInt(strTest);
i stedetfor:
  new Integer(strTest);
Avatar billede twm Nybegynder
05. august 2003 - 07:34 #9
Det er samme funktionalitet, den ene bruger bare en klasse constructor og den anden en statisk funktion, så de skal jo begge allokere plads til en integer.

Og så har den ene en bool til at smage med og den anden en int.

Og ja de virker begge!

Da jeg svarede havde jeg ikke set arne_v's svar! ;)
Avatar billede arne_v Ekspert
05. august 2003 - 08:22 #10
En statisk metode der returnerer en simpel data type creater ikke
et objekt det skal garbage collectes.

Prøv selv:

public class IntegerTest {
    private static final int N = 100000000;

    private static void test() {
        long start1 = System.currentTimeMillis();
        for (int i = 0; i < N; i++) {
            boolean tal = test1("12345");
        }
        long stop1 = System.currentTimeMillis();
        long start2 = System.currentTimeMillis();
        for (int i = 0; i < N; i++) {
            boolean tal = test2("12345");
        }
        long stop2 = System.currentTimeMillis();
        System.out.println("test 1 (static)  = " + (stop1 - start1));
        System.out.println("test 2 (new)  = " + (stop2 - start2));
    }
    private static boolean test1(String s) {
        try {
            Integer.parseInt(s);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
    private static boolean test2(String s) {
        try {
            new Integer(s);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
    public static void main(String[] args) {
        test();
    }
}
Avatar billede arne_v Ekspert
05. august 2003 - 08:24 #11
På min maskine giver det 2 sekunders forskel for 100 mio. tal.

Bemærk at min pointe er kun at der er en forskel - ikke at det
er en forskel som betyder noget.

Jeg kan ikke forestille mig nogen virkelig applikation, hvor det gør
en forskel.
Avatar billede theboy Nybegynder
05. august 2003 - 09:57 #12
Jeg har prøvet at lave en funktion til dette nu, men funktionen retunere stadig 0 også selv om man har tastet rigtigt efter man har tastet forkert.
Funktionen "læsLinie()" læser input fra tastaturet.
-----------------

public int læsHelTal()
    {
        int tal = 0;
        String linie = læsLinie();
        if (undersøgTal(linie)==true)
        {
          tal = Integer.parseInt(linie);
        }
        else
        {
            System.out.println("Forkert indtastning. Prøv igen");
            læsHelTal();
        }
        return tal;
       
    }

    boolean undersøgTal(String s)
    {
        try{
            new Integer(s);
            return true;
            }
            catch(NumberFormatException e)
            {
                return false;
            }
        }
Avatar billede arne_v Ekspert
05. august 2003 - 10:14 #13
undersøgTal er OK.

Men der er ihvertfald en logisk fejl i koden.

Mit gæt er at den virker hvis du indtaster et tal i første forsøg.

Men returnerer 0 hvis du indaster garbage i første forsøg og et tal i
andet forsøg.

Forklaringen er at du ikke bruger resultatet af når du kalder læsHelTal
rekursivt !
Avatar billede arne_v Ekspert
05. august 2003 - 10:15 #14
public int læsHelTal()
    {
        int tal = 0;
        String linie = læsLinie();
        if (undersøgTal(linie)==true)
        {
          tal = Integer.parseInt(linie);
        }
        else
        {
            System.out.println("Forkert indtastning. Prøv igen");
            tal = læsHelTal();
        }
        return tal;
    }
Avatar billede arne_v Ekspert
05. august 2003 - 10:17 #15
Men jeg ville nok have kodet den som:

public int læsHelTal()
    {
        String linie = læsLinie();
        while (!undersøgTal(linie))
        {
            System.out.println("Forkert indtastning. Prøv igen");
            linie = læsLinie();
        }
        return Integer.parseInt(linie);
    }
Avatar billede theboy Nybegynder
05. august 2003 - 10:27 #16
Jo det giver mere mening i begge tilfælde
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester