Errore logico java if clause

di il
2 risposte

Errore logico java if clause

Salve a tutti, questo è il codice

import java.util.Scanner;
import helpers.Helpers;
public class Esercizio5 {
public static final int NUMERO = 85134;
	public static void main(String[] args){
		Scanner tastiera = new Scanner(System.in);
		System.out.println("Indovinare il numero da 5 cifre.");
		System.out.println("Scrivere ripetitivamente numeri a 5 cifre,");
		System.out.println("Verranno dati la quantità di numeri nella posizione corretta");
		System.out.println("e la loro somma. Il programma finirà quando verrà scritto");
		System.out.println("il numero giusto.");
		int risposta = tastiera.nextInt();
		int somma = 0;
		int count = 0;
		do {
			if (Math.floor(Math.log10(risposta)) == 4) {                     // Se il numero è di 5 cifre
				for (int indice = 1; indice != 6; indice++) {
					if (Helpers.Cifra(risposta, indice) == Helpers.Cifra(NUMERO, indice)) {               // Se la cifra coincide
						somma = somma + risposta;                                                           // Aggiungo valore cifra alla somma
						count++;                                                                          
					}
				}
			}
			else {                                                          // Se il numero non è di 5 cifre
				System.out.println("Inserire un numero di 5 cifre.");
			}
			System.out.println(count);
			System.out.println(somma);
			risposta = tastiera.nextInt();
		} while (risposta!=NUMERO);
		tastiera.close();
	}
	

}

Helpers.Cifra(numero, posizione) restituisce il valore della cifra alla posizione x nel numero n.

Il problema sta nell'if all'interno del ciclo for, infatti quando avvio il programma il problema si ha solamente se inserisco un valore di 5 cifre. Quando lo faccio il programma non risponde più, e mi permette di inserire numeri che non restituiscono nulla.
Sapete dirmi cosa c'è che non va? Sono inoltre accettati suggerimenti per migliorare il programma.
Grazie mille.

2 Risposte

  • Re: Errore logico java if clause

    SrJustEasy ha scritto:


    [...] quando avvio il programma il problema si ha solamente se inserisco un valore di 5 cifre. Quando lo faccio il programma non risponde più, e mi permette di inserire numeri che non restituiscono nulla.
    Cosa vuol dire questa parte ? Se io inserisco un numero di cinque cifre (ad esempio "11111") il programma stampa "1" , va a capo, stampa "11111", va a capo e aspetta il nuovo inserimento. Quindi cosa intendi con "non resituiscono nulla" ? Ti si blocca il ciclo senza che stampi nulla a video ?
    Se sì è probabile che il metodo Helpers.Cifra() sia quello che blocca l'esecuzione, ma non avendo il codice si può solo fare supposizioni (a proposito sarebbe meglio postare anche un metodo esterno se lo utilizzi nel codice, proprio perché lì può esserci un errore).

    SrJustEasy ha scritto:


    Sapete dirmi cosa c'è che non va?
    A parte quel problema a cui facevi riferimento, che dovresti chiarire, ci sono almeno altri due errori nel codice. Se io appunto scrivo "11111" come numero ottengo subito che somma vale "11111" alla prima iterazione. Errore banale, stai sommando a somma la variabile risposta (il numero intero!) invece che sommare la singola cifra corrispondente del numero esatto.
    Ma anche se avessi scritto quella parte correttamente, aggiungendo il valore della cifra nella posizione corretta, ci sarebbe un altro errore. Infatti se io scrivo alla prima iterazione "11111" e poi lo scrivo ancora, e ancora, etc. ottengo che somma (e anche il numero di cifre corrette, in questo caso particolare) valgono prima 1, poi 2, poi 3, etc. Quindi dopo 6 volte il programma mi dice che ho indovinato 6 cifre su 5, ma sono ancora là che scrivo
    Riusciresti a sistemare questa parte (non è particolarmente complicato) ?

    SrJustEasy ha scritto:


    Sono inoltre accettati suggerimenti per migliorare il programma.
    Primo suggerimento: stampare a video count e somma senza altre indicazioni confonde abbastanza, soprattutto quando si cominciano ad avere molti numeri inseriti (anche se nell'introduzione dicevi cosa viene stampato a video). Abituati a scrivere messaggi informativi, aiutano anche nella fase di debug: molto meglio vedere a video qualcosa come questo ad ogni iterazione:
    
    numero cifre esatte (nella posizione corrispondente): 2
    somma dei valori delle cifre esatte (nella posizione corripondente): 13
    
    Il numero non è corretto. Inserire un nuovo numero > 
    
    Questo era solo di presentazione in realtà, ma aiuta comunque.

    Altra cosa: è un requisito che ti è stato imposto il dover usare un int per la tua combinazione ? Quando si utilizza un pin numerico, ad esempio di cinque cifre, questo NON è un intero, è una sequenza di caratteri.
    Ad esempio "00000" è ben diverso da "0", ma visto come intero il numero è uguale.
    Oltre a essere teoricamente più corretto (dal mio punto di vista), usare una stringa ha diversi vantaggi:
    - ti evita quel giro di floor e log, decisamente poco gradevole, permettendoti di controllare solo se la length() è pari a 5.
    - non devi utilizzare un metodo ulteriore per leggere il valore della cifra alla n-esima posizione, basta confrontare con == i caratteri presi dalle stringhe con il metodo charAt(int n).
    - leggere sempre stringhe da Scanner con nextLine() ti evita alcuni problemi a cui andresti incontro mischiando le operazioni di lettura con nextLine() e operazioni di lettura con nextInt(). Questa parte è più tecnica e non la conosco neanche troppo bene, ma se non sbaglio quando fai nextInt() e digiti invio, nel buffer rimane il carattere di terminazione, che può dare problemi in futuro se vuoi leggere stringhe per un altro motivo.

    Ovviamente se leggi una stringa dovrai poi convertire la singola cifra in intero per poterla aggiungere a somma, ma è molto semplice da fare (e il confronto tra risposta e numero non andrà più fatto con ==, ma con equals(), che viene utilizzato per confrontare gli oggetti). Dovrai inoltre assicurarti che la stringa inserita contenga solo numeri (anche questo è banale comunque, sia che tu lo faccia "a mano", sia che usi un metodo già pronto).

    Infine trovo un po' insolito usare il diverso come condizione di terminazione di un ciclo come il tuo, ovviamente nel caso in esame è la stessa cosa fare <6 o !=6, ma devi fare attenzione a non toccare per sbaglio indice, a non incrementarlo due volte etc, per non rischiare di fare un loop infinito (su questo comunque si potrebbe discutere, era tanto per dire).
  • Re: Errore logico java if clause

    Ansharja ha scritto:


    Cosa vuol dire questa parte ? Se io inserisco un numero di cinque cifre (ad esempio "11111") il programma stampa "1" , va a capo, stampa "11111", va a capo e aspetta il nuovo inserimento. Quindi cosa intendi con "non resituiscono nulla" ? Ti si blocca il ciclo senza che stampi nulla a video ?
    Se sì è probabile che il metodo Helpers.Cifra() sia quello che blocca l'esecuzione, ma non avendo il codice si può solo fare supposizioni (a proposito sarebbe meglio postare anche un metodo esterno se lo utilizzi nel codice, proprio perché lì può esserci un errore).
    A parte quel problema a cui facevi riferimento, che dovresti chiarire, ci sono almeno altri due errori nel codice. Se io appunto scrivo "11111" come numero ottengo subito che somma vale "11111" alla prima iterazione. Errore banale, stai sommando a somma la variabile risposta (il numero intero!) invece che sommare la singola cifra corrispondente del numero esatto.
    Ma anche se avessi scritto quella parte correttamente, aggiungendo il valore della cifra nella posizione corretta, ci sarebbe un altro errore. Infatti se io scrivo alla prima iterazione "11111" e poi lo scrivo ancora, e ancora, etc. ottengo che somma (e anche il numero di cifre corrette, in questo caso particolare) valgono prima 1, poi 2, poi 3, etc. Quindi dopo 6 volte il programma mi dice che ho indovinato 6 cifre su 5, ma sono ancora là che scrivo
    Riusciresti a sistemare questa parte (non è particolarmente complicato) ?
    Avevi ragione, c'era un errore in Helpers.Cifra(); ho corretto quello ed il resto.

    Ansharja ha scritto:


    Altra cosa: è un requisito che ti è stato imposto il dover usare un int per la tua combinazione ? Quando si utilizza un pin numerico, ad esempio di cinque cifre, questo NON è un intero, è una sequenza di caratteri.
    Ad esempio "00000" è ben diverso da "0", ma visto come intero il numero è uguale.
    Oltre a essere teoricamente più corretto (dal mio punto di vista), usare una stringa ha diversi vantaggi:
    - ti evita quel giro di floor e log, decisamente poco gradevole, permettendoti di controllare solo se la length() è pari a 5.
    - non devi utilizzare un metodo ulteriore per leggere il valore della cifra alla n-esima posizione, basta confrontare con == i caratteri presi dalle stringhe con il metodo charAt(int n).
    - leggere sempre stringhe da Scanner con nextLine() ti evita alcuni problemi a cui andresti incontro mischiando le operazioni di lettura con nextLine() e operazioni di lettura con nextInt(). Questa parte è più tecnica e non la conosco neanche troppo bene, ma se non sbaglio quando fai nextInt() e digiti invio, nel buffer rimane il carattere di terminazione, che può dare problemi in futuro se vuoi leggere stringhe per un altro motivo.

    Ovviamente se leggi una stringa dovrai poi convertire la singola cifra in intero per poterla aggiungere a somma, ma è molto semplice da fare (e il confronto tra risposta e numero non andrà più fatto con ==, ma con equals(), che viene utilizzato per confrontare gli oggetti). Dovrai inoltre assicurarti che la stringa inserita contenga solo numeri (anche questo è banale comunque, sia che tu lo faccia "a mano", sia che usi un metodo già pronto).
    Si, dovevo utilizzare un int, comunque ne ho fatto un altro con le stringhe ed è decisamente molto più facile.

    Ansharja ha scritto:


    Infine trovo un po' insolito usare il diverso come condizione di terminazione di un ciclo come il tuo, ovviamente nel caso in esame è la stessa cosa fare <6 o !=6, ma devi fare attenzione a non toccare per sbaglio indice, a non incrementarlo due volte etc, per non rischiare di fare un loop infinito (su questo comunque si potrebbe discutere, era tanto per dire).
    Si ho pensato che non fosse un problema utilizzare l'uno o l'altro, ma probabilmente hai ragione... E' più sicuro


    In ogni caso grazie mille, ho risolto tutto. Ecco il programma.

    Helpers.Cifra :
    
    	public static int Cifra(int n, int cifra) {
    		String numero = Integer.toString(n);
    		char Cifra = numero.charAt(cifra-1);
    		int c = Character.getNumericValue(Cifra);
    		return c;
    
    Programma :
    
    import java.util.Scanner;
    import helpers.Helpers;
    public class Esercizio5 {
    public static final int NUMERO = 85134;
    	public static void main(String[] args){
    		Scanner tastiera = new Scanner(System.in);
    		System.out.println("Indovinare il numero da 5 cifre.");
    		System.out.println("Scrivere ripetitivamente numeri a 5 cifre,");
    		System.out.println("Verranno dati la quantità di numeri nella posizione corretta");
    		System.out.println("e la loro somma. Il programma finirà quando verrà scritto");
    		System.out.println("il numero giusto.");
    		int risposta = tastiera.nextInt();
    		do {
    			int somma = 0;
    			int count = 0;
    			if (Math.floor(Math.log10(risposta)) == 4) {                 
    				for (int indice = 1; indice < 6; indice++) {
    					if (Helpers.Cifra(risposta, indice) == Helpers.Cifra(NUMERO, indice)) {            
    						somma = somma + Helpers.Cifra(risposta, indice);                                                           
    						count++;                                                                          
    					}
    				}
    			}
    			else {                                                     
    				System.out.println("Inserire un numero di 5 cifre.");
    			}
    			System.out.println("Numero cifre nella posizione esatta: " + count);
    			System.out.println("Somma dei valori delle cifre nella posizione esatta: " + somma);
    			risposta = tastiera.nextInt();
    		} while (risposta!=NUMERO);
    		tastiera.close();
    	}
    	
    
    }
    
    
Devi accedere o registrarti per scrivere nel forum
2 risposte