Primo codice, utilizzo dell'ereditarietà e polimorfismo

di il
46 risposte

46 Risposte - Pagina 3

  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Che io sono il primo a dire di dover studiare ma da li a pensare di non sapere nemmeno le cose più elementari, quando magari programmatori di vecchia data per scrivere un programma così semplice in assembky, pascal, BASIC che conosco bene, dovevo buttare giù moltissime linee di codice, poi i vettori, i cicli e tutte quelle cavolate sono la base e sintatticamente non sono nemmeno molto differenti uno dall'altro... Quindi, giusto per tranquillizzare tutti, l'ABC della programmazione c'è, il java è anche più semplice e li sto studiando bene ed essere fraintesi capita specie quando non si conosce bene la persona con cui si parla
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Michele Genchi ha scritto:


    Che io sono il primo a dire di dover studiare ma da li a pensare di non sapere nemmeno le cose più elementari, quando magari programmatori di vecchia data per scrivere un programma così semplice in assembky, pascal, BASIC che conosco bene, dovevo buttare giù moltissime linee di codice, poi i vettori, i cicli e tutte quelle cavolate sono la base e sintatticamente non sono nemmeno molto differenti uno dall'altro... Quindi, giusto per tranquillizzare tutti, l'ABC della programmazione c'è, il java è anche più semplice e li sto studiando bene ed essere fraintesi capita specie quando non si conosce bene la persona con cui si parla
    Allora, prova a scriverlo in Pascal E BASIC (l'assembler te lo abbuono ).

    Cosi' ti possiamo dare delle indicazioni su come si fanno le stesse cose in Java!

    E come esempio per fare il test, ecco qui' 3 interi (in basi diverse) da convertire in esadecimale

    36#am1khuds
    10#831625743376
    2#1100000110100000110000011100110000010000



    Nota: Java deve essere usato come un nome proprio. Non si dice il java o la java!
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Ciao, stabilire se un numero è in virgola mobile non è così semplice come sembra.
    Ad esempio in java un numero in virgola mobile potrebbe essere nella forma:
    234 234,5 .234 +2.4 -.3 17E10 2E-3 -.6E2
    Ti mostro un metodo molto grezzo, ma che non necessita conoscenze approfondite, per poter risolvere il problema.
    Per prima cosa devi prendere carta e penna e disegnare un automa a stati finiti che rappresenti un numero in virgola mobile. Se hai fatto un itis a indirizzo informatico dovresti già sapere di che si parla; è argomento di terza.
    Un numero in virgola mobile si può rappresentare così:

    Se non sai come funziona un automa ti faccio un brevissimo sunto:
    prendi in input il numero come una stringa poi parti da q0 (stato iniziale), consumi il primo carattere, se c'è una transizione valida con quel carattere (una freccia etichettata con il carattere che da q0 ti porta in un altro stato qn) ti sposti in quello stato altrimenti sai che quella stringa non appartiene al linguaggio (non è un numero in virgola mobile); riesegui il tutto finchè, carattere dopo carattere, consumi tutta la stringa (oppure ti fermi prima perchè trovi una transazione non valida). A questo punto controlli in che stato sei arrivato: se sei in uno stato accettante (uno stato rappresentato con il doppio cerchio) allora accetti la stringa (fa parte del linguaggio), no altrimenti.
    NOTA: 0-9 rappresenta 0,1,2,...,9
    Es con 2E-3:
    parti da q0, consumi il 2 (rimane E-3) , con il carattere 2 vai in q2;
    da q2, consumi E (rimane -3) con il carattere E vai in q5;
    da q5, consumi - (rimane 3) con il carattere - vai in q6;
    da q6, consumi 3 (rimane la stringa vuota) con il carattere 3 vai in q7;
    Hai consumato tutto l'input e ti ritrovi in q7; è uno stato accettante quindi accetti la stringa (è un numero in virgola mobile).

    Comunque è una spiegazione molto terra terra, se ti interessa l'argomento trovi molto materiale anche on line; ti basta cercare DFA o automi a stati finiti.

    In java puoi rappresentarlo con uno switch sugli stati:
    
    public static boolean scan(String s) {
            int state = 0;
            int i = 0;
            while (state >= 0 && i < s.length()) {
                final char ch = s.charAt(i++);
                switch (state) {
                    case 0:
                        if (Character.isDigit(ch))
                            state = 2;
                        else if (ch == '+' || ch == '-')
                            state = 1;
                        else if (ch == '.')
                            state = 3;
                        else if (ch == ' ')
                            state = 0;
                        else
                            state = - 1;
                        break;
                    case 1:
                        if (Character.isDigit(ch))
                            state = 2;
                        else if
                                (ch == '.')
                            state = 3;
                        else
                            state = - 1;
                        break;
                    case 2:
                        if (Character.isDigit(ch))
                            state = 2;
                        else if (ch == '.')
                            state = 3;
                        else if (ch == 'E')
                            state = 5;
                        else if (ch == ' ')
                            state = 8;
                        else
                            state = - 1;
                        break;
                    case 3:
                        if (Character.isDigit(ch))
                            state = 4;
                        else
                            state = - 1;
                        break;
                    case 4:
                        if (Character.isDigit(ch))
                            state = 4;
                        else if (ch == 'E')
                            state = 5;
                        else if (ch == ' ')
                            state = 8;
                        else
                            state = - 1;
                        break;
                    case 5:
                        if (ch == '+' || ch == '-')
                            state = 6;
                        else if (Character.isDigit(ch))
                            state = 7;
                        else
                            state = - 1;
                        break;
                    case 6:
                        if (Character.isDigit(ch))
                            state = 7;
                        else
                            state = - 1;
                        break;
                    case 7:
                        if (Character.isDigit(ch))
                            state = 7;
                        else if (ch == ' ')
                            state = 8;
                        else
                            state = - 1;
                        break;
                    case 8:
                        if (ch == ' ')
                            state = 8;
                        else
                            state = - 1;
                        break;
                }
            }
            return i == s.length() && (state == 2 || state == 4 || state == 7 || state == 8);
    }
    
    È un approcio non OOP, poco leggibile e non riutilizzabile (esistono approci molto più sofisticati ed eleganti per gestire il problema ma che necessitano di conoscenze teoriche molto più ampie) ma spero che ti possa essere d'aiuto per inquadrare il problema.
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Ziovine virgulto, un DFA e' un sistema tutt'altro che grezzo
    Se conosci i DFA, sai che cosa sono le grammatiche. Quindi basta che leggi uno dei post precedenti per capire che questo approccio e' gia' stato proposto!

    Inoltre, non serve scomodare i DFA, bastano un po' di espressioni regolari.
    Definire un numero mediante una serie di RE e' decisamente piu' semplice che usare un'unico DFA!
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Ciao migliorabile,
    mi sa che mi sono espresso male, quando ho detto che era un metodo molto grezzo intendevo la rappresentazione di un DFA tramite switch e una serie infinita di if, non il DFA in sè e per sè .
    Comunque avevo già letto il tuo post in cui spiegavi come realizzare il tutto tramite una grammatica libera dal contesto, ma per capire cos'è una CFG servono solide basi teoriche solide e ,senza offesa, l'autore del post non sembra che le abbia.
    Dato che una stringa rappresentante un numero in virgola mobile appartiene a un linguaggio regolare mi è sembrato più semplice e intuitivo fargli un esempio a partire da un DFA (ripeto, se uno ha fatto l'itis informatica li conosce per forza).
    Inoltre, non serve scomodare i DFA, bastano un po' di espressioni regolari.

    Alla fine sono due modi equivalenti per rappresentare la stessa cosa. Una regexp equivale a DFA e un DFA equivale a una regexp.
    Definire un numero mediante una serie di RE e' decisamente piu' semplice che usare un'unico DFA!
    Questo secondo me è opinabile: in alcuni casi è più facile scrivere direttamente le regexp, in altri invece è più facile disegnare un DFA, in altri è più semplice disegnare un NFA e poi trasformarlo in DFA, in altri ancora è più facile scrivere una CFG (tanto un linguaggio regolare è un sottoinsieme di un linguaggio libero dal contesto).
    Secondo me dipende molto dal modo di ragionare , che cambia da persona a persona.
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Ma è un botta e risposta tra Voi geni o una gara a chi offende di più... Cmq i ragionamenti i cicli e gli if sono la base, usare tutte le meraviglie di Java, come per esempio le eccezioni personalizzate non è la stessa cosa... Ora facciamo distinzione tra programmatore procedurale, programmatore Oop e programmatore Java... Dopodiché passate agli insulti
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Chi è che sta offendendo e insultando? Mi sa che mi son perso qualcosa...
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Public static void main(String[] args) {
    // TODO Auto-generated method stub
    String mioNumero="56,94";
    System.out.println("La cifra da convertire "+mioNumero);
    if (binario.okBinario(mioNumero))
    System.out.println("E' un numero binario");
    if (decimale.okDecimale(mioNumero))
    System.out.println("E' un numero decimale");
    if (ottale.okOttale(mioNumero))
    System.out.println("E' un numero ottale");
    if (esadecimale.okEsadecimale(mioNumero))
    System.out.println("E' un numero esadecimale");
    }

    final static public boolean okBinario(String numero) {
    try {
    for (char x:numero.toCharArray())
    Cifra.isBinario(x);
    return true;
    } catch (gestoreEccezioni e) {
    // TODO Auto-generated catch block
    System.out.println(e.toString()+" in binario");
    return false;}
    }

    final static public void isBinario(char carattere) throws gestoreEccezioni {
    boolean nonUguale=false;
    for (char x:CIFRE_BINARIE)
    if (x!=carattere)
    nonUguale=true;
    else {
    nonUguale=false;break; }
    if (nonUguale)
    throw new gestoreEccezioni(carattere);
    }

    Spero che così vada meglio!!! Il compito va meglio così ?
    Ora devo capire come gestire i numeri strani con la E e come passare da uno stato all'altro del DFA
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Michele Genchi ha scritto:


    Spero che così vada meglio!!! Il compito va meglio così ?
    No, purtroppo non va granché bene. E come pensare di usare una motosega per tagliare il pane ... afferrato?

    Poi comunque il codice non l'hai postato completo. Cosa sarebbero 'binario', 'decimale' ecc.. che usi negli if nel main? okBinario è statico ... perché dovresti invocarlo su un reference? (ammesso che sia un reference ad un oggetto)
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Non posso postare tutto il codice, binario è una classe con metodo statico okbinario che ritorna un booleano di conferma se è un numero binario, per saperlo confronto ogni cifra della stringa con un vettore di caratteri, usando la classe cifra e se non è compreso nel vettore scatta un'eccezione...
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Questo è quello che farei, al minimo, io .... (mettendoli in una classe separata di utilità es. StringUtilities)
    public static boolean isBinary(String str) {
        for (int i = 0; i < str.length(); i++) {
            if (!isBinary(str.charAt(i))) {
                return false;
            }
        }
    
        return true;
    }
    
    public static boolean isBinary(char ch) {
        return ch == '0' || ch == '1';
    }
    Pulito, semplice e "filante". Confrontalo con il tuo ....
    Vedi eccezioni? Vedi strani giri con array? break? variabili booleane di "flag"?
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    Tu mettetesti a confronto un giocatore della primavera con uno di serie A. Al limite capiresti che è un confronto inutile, dovresti confrontarti con chi ha la tua stessa esperienza, a me invece consigli e mi fai crescere:-) e ti ringrazio, il mio modo di programmare è senza esperienza ed è legato a vecchie filosofie di programmazione... Cerca di vedere se ci sono margini di miglioramento, ed il mio grado di preparazione, poi le finezze le acquisisco anch'io col tempo...
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    E già che ci sono, ti spiego anche perché un isBinary(String) / isBinary(char) non dovrebbero lanciare una eccezione se non è un digit binario.

    Queste funzionalità sono "stupide", senza alcuna nozione del contesto in cui potrebbero essere usate. Il fatto che una stringa o un carattere non sia "binario" non è un errore tale da giustificare una eccezione. Cioè può capitare l'uno o l'altro caso. Se uno dei due è un "errore" grave lo sa solo chi ha maggior nozione del contesto.

    Io potrei voler sfruttare il isBinary(char) in un altro metodo che verifica che un array di char NON contenga cifre binarie. Quindi il caso migliore, quello che mi aspetto, porterebbe a dover gestire tutte eccezioni! E in generale nella JVM, la gestione delle eccezioni è "costosa".
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    @Michele: oltre a quello che ha detto @adbin, il tuo attuale approccio ha un'altro diffetto fondamentale:

    non e' in grado di distinguere tra numeri di basi diverse ma che utilizzano lo stesso insieme di cifre

    Come prima:

    100

    il tuo codice lo interpreterebbe come binario, mentre invece, se usi la sintassi definita per le costanti numeriche in Java, e' un numero in base 10.

    Quindi, PRIMA di scrivere il codice, devi avere chiaro come distinguere numeri in basi diverse!

    Per prima cosa, devi definire la SINTASSI dei diversi formati dei numeri, in modo non equivoco.

    Secondo, devi usare le ESPRESSIONI REGOLARI per definire le varie sintassi. Potresti usare un DFA o anche un NFA (anche se voglio vedere chi e' in grado di convertire un NFA in un DFA di media complessita' e non progettato solo per fare esercizi ), ma non ne vale la pena.

    Per quanto riguarda la gestione delle eccezzioni, @adbin ha perfettamente ragione!
    Non si usano se non sono estremanente necessarie.

    Ad esempio, in questo caso, per fare le cose corrette, l'eccezzione dovrebbe essere sollevata SOLO se la stringa che stai analizzando NON E' UN NUMERO. Questo per essere compatibile con i vari Integer.parseInt, Double.parseDouble, ...
  • Re: Primo codice, utilizzo dell'ereditarietà e polimorfismo

    100 è un numero decimale, binario ed esadecimale
    per quanto riguarda i numero con la E, sono numeri espressi dalle calcolatrici dove la E vale 10, spero di aver applicato al meglio i consigli ricevuti... Una volta stabilite le cifre giuste per ogni base, resta da capire l'ordine con cui devono essere scritte le cifre o i caratteri rappresentativi... Specialmente in decimale che ha diverse varianti di rappresentazione
Devi accedere o registrarti per scrivere nel forum
46 risposte