Doppioni

Stato
Discussione chiusa ad ulteriori risposte.

RedSkull

Utente Electrum
1 Aprile 2008
177
19
0
103
Volevo provare a creare un programmino che dato un file (mail.txt) contenente una lista di mail controllasse (una riga sotto l'altra) se ci fossero doppioni.
ma il metodo controlla fà un eccezione ritornando come errore : null
come mai ?
l'array è gestito bene mi pare.
scusate ma sto ancora imparando xD
ps:Ditemi se il metodo di scrivere il programma può andare bene.


http://paste2.org/p/190327
 
Codice:
 for(i=0;i<=array.length;i++)
io metterei
Codice:
 for(i=0;i<array.length;i++)
#edit.. comunque l'implementazione è errata
Codice:
 public void controlla()
    {
        String stringa;
        int i,turno;
        try
        {
            stringa = leggo.readLine();
            turno=0;
            while (stringa != null)
            {
                
                for(i=0;i<=array.length;i++)
                {
                    if (!(array[i].equals(stringa)))
                    {
                        array[turno]=stringa;
                    }
                }
                
                stringa = leggo.readLine();
                turno++;
            }
        }catch(Exception e){
            System.out.println("c)Errore: "+e.getMessage());
            System.exit(1);
        }
    }
non va bene
dovrebbe essere
Codice:
 public void controlla()
    {
        String stringa;
        int i,turno;
        try
        {
            stringa = leggo.readLine();
            turno=0;
            bool is_in_array=false;
            while (stringa != null)
            {
                is_in_array=false;
                i=0;
                while(i<array.length && !is_in_array) {
                       if (array[i].equals(stringa))
                          is_in_array = true;
                       i++; 
                }

                if(!is_in_array)
                    array[turno]=stringa;                

                stringa = leggo.readLine();
                turno++;
            }
        }catch(Exception e){
            System.out.println("c)Errore: "+e.getMessage());
            System.exit(1);
        }
    }
 
Si Stoner me ne sono accorto ora, ma era una svista durante l'ultima prova, anche se levo = ritorna sempre null.
 
decisamente no...sintassi ancora errata.Per l'ennesima volta ti dico che è inutile fare:
Codice:
class File{
...
}
class doppioni{
...
}
fai una sola classe con tutti i metodi e il main compreso.Poi dato che richiami di fila apri(),controlla(),scrivi() e chiudi() è inutile fare 4 metodi separati,fai un solo metodo controlla() che si occuperà di aprire il file,di controllaro di scrivere e di chiudere.Fai metodi separati per ogni cosa quando li usi in più punti e in modo non sequenziale tipo:apri il file e fai altro,poi ad un input dell'utente fai il controllo ecc ecc...
 
Niente ritorna ancora null.
ho aggiunto questa riga in apri:
for(int p=0;p<500;p++) array[p]="";

(l'array non era popolato)
ora funziona tranne per una cosa:
se nel file ci sono queste email:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

il file editato riotornerà:
[email protected]
[email protected]
[email protected]

[email protected]

come è possibile vedere c'è uno spazio, come levare lo spazio ?

EDIT:* RITIRO TUTTO FATTO :)
http://paste2.org/p/190338
 
ma la funzione è questa?
Codice:
public void scrivi()
    {
        try
        {
            for(int k=0;k<array.length;k++)
            {
                scrivo.println(array[k]);
                scrivo.flush();
            }
        }catch (Exception e){
            System.out.println("s)Errore: "+e.getMessage());
            System.exit(1);
        }
    }
anche questa è errata..
dovrebbe essere così..
Codice:
public void scrivi()
    {
        try
        {
            int k=0;
            while(array[k] != "") {
                   scrivo.println(array[k]);
                   scrivo.flush();
                   k++;
            }
        }catch (Exception e){
            System.out.println("s)Errore: "+e.getMessage());
            System.exit(1);
        }
    }
#edit nel metodo precedente pure c'è un altro piccolo errore che ho visto solo ora.
corretto verrebbe...
Codice:
public void controlla()
    {
        String stringa;
        int i,turno;
        try
        {
            stringa = leggo.readLine();
            turno=0;
            bool is_in_array=false;
            while (stringa != null)
            {
                is_in_array=false;
                i=0;
                while(i<array.length && !is_in_array) {
                       if (array[i].equals(stringa))
                          is_in_array = true;
                       i++; 
                }

                if(!is_in_array) {
                    array[turno]=stringa;                
                    turno++;
                }
                stringa = leggo.readLine();
                
            }
        }catch(Exception e){
            System.out.println("c)Errore: "+e.getMessage());
            System.exit(1);
        }
    }

con queste due modifiche non dovresti aver problemi .

Ciao.
 
Sigh mi è stato suggerito da un amico il metodo di scrittura.
quindi devo fare tutto dentro la classe principale ?
Ok ho grazie adesso la rifaccio :)
Edit:Stoner il metodo scrivi funziona perfettamente, perchè è errato ?
 
stoner ha detto:
ma la funzione è questa?
Codice:
public void scrivi()
    {
        try
        {
            for(int k=0;k<array.length;k++)
            {
                scrivo.println(array[k]);
                scrivo.flush();
            }
        }catch (Exception e){
            System.out.println("s)Errore: "+e.getMessage());
            System.exit(1);
        }
    }
anche questa è errata..
dovrebbe essere così..
Codice:
public void scrivi()
    {
        try
        {
            int k=0;
            while(array[k] != "") {
                   scrivo.println(array[k]);
                   scrivo.flush();
                   k++;
            }
        }catch (Exception e){
            System.out.println("s)Errore: "+e.getMessage());
            System.exit(1);
        }
    }

non capisco perchè questa tua avversione riguardo al for...
alla fine come scrive redskull non è sbagliato, è solo un altro modo per fare la stessa cosa...
 
E' errato perchè se tu hai un array da 500 posizioni e ne occupi 10 sul file ne scrive 500 di cui 490 di righe vuote.
Comunque c'è un altro errore, ho editato ora, scusa, ma lo sto scrivendo qui sul forum e non ci ho fatto caso prima.

Gian ha detto:
non capisco perchè questa tua avversione riguardo al for...
alla fine come scrive redskull non è sbagliato, è solo un altro modo per fare la stessa cosa...

No è sbagliato a livello logico quello che fa. All'inizio era del tutto errato l'agoritmo. Cercava che UN elemento dell'array fosse diverso da quello letto e lo inseriva. Quando in realtà TUTTi gli elementi dell'array devono essere diversi da quello letto affinchè la stringa letta vada inserita.

Tra l'altro, ho usato il while perchè lo sto scrivendo sul posto e non posso mettermi a modificare mezzo programma soltanto perchè a te piace il for, perchè tu non sai quante posizioni occupi dell'array, ma sai soltanto che quelle non occupate sono a null.

Se io ho un array da 500 posizioni e ne occupo soltanto una, perchè andare da 1 a 500? (tra l'altro scrivendo anche 499 righe vuote nel file).
 
stoner ha detto:
No è sbagliato a livello logico quello che fa. All'inizio era del tutto errato l'agoritmo. Cercava che UN elemento dell'array fosse diverso da quello letto e lo inseriva. Quando in realtà TUTTi gli elementi dell'array devono essere diversi da quello letto affinchè la stringa letta vada inserita.
qui ti dò ragione, non men'ero accorto.

stoner ha detto:
Tra l'altro, ho usato il while perchè lo sto scrivendo sul posto e non posso mettermi a modificare mezzo programma soltanto perchè a te piace il for, perchè tu non sai quante posizioni occupi dell'array, ma sai soltanto che quelle non occupate sono a null.

Se io ho un array da 500 posizioni e ne occupo soltanto una, perchè andare da 1 a 500? (tra l'altro scrivendo anche 499 righe vuote nel file).

qui invece dipente tutto dalla formattazione del file...
se voglio scriverlo così il tuo algoritmo mi prende solo la prima email e mi sega tutto il resto...

inoltre non dovresti riscrivere il programma di redskull, ma consigliarlo sulle parti che potrebbe scrivere meglio, o su quelle in cui non riesce...
se glielo modifichi tutto, cosa impara? ;)
 
Infatti la struttura del file non c'entra nulla con la struttura dell'array (che è quella di cui stavo parlando prima, ed è l'unica della quale ho parlato tra l'altro).
L'array è popolato inizialmente a null. Poi vengono inserite al suo interno tutte le email lette dal file non ripetute. Quindi le prime n posizioni saranno occupate da email. Le restanti 500-n saranno vuote. Quindi la prima stringa vuota è quella che a livello logico determina la fine dell'array.

Inoltre nel metodo di controllo, l'autore ha scritto una cosa del genere
Codice:
 stringa = leggo.readLine();
 turno=0;
 while (stringa != null) {
    //varia roba
    stringa = leggo.readLine();
 }
quindi in quel caso l'algoritmo inserisce una sola email dentro l'array, non tutte. Andrebbe rivista questa cosa, ma la struttura del file l'ha decisa l'autore non io, se a lui sta bene così a me sta ancora meglio, mi sono limitato a correggere gli errori più evidenti (di algoritmo tra l'altro, visto che lui ipotizza un file composto da n email, una per riga, rileggiti il primo post).
Per quanto riguarda la seconda domanda, mi sembra che li sto spiegando gli errori.. o no?
Che sei l'avvocato di RedSkull92, se non ha capito niente può anche chiedermi lui di spiegargli cosa ho fatto, non credo di essermi mai ritirato per una spiegazione.
 
Si li ho capiti gli errori commessi. cmq ho notato che deve per forza esserci
for(int p=0;p<500;p++) array[p]="";
altrimenti restituisce null.
cmq grazie stoner ho capito adesso.
ps: ma se li volessi fare tutto dentro la classe principale (Doppioni) mi basta mettere tutto dentro una classe ?
e creare un costruttore ?
es:
public Doppioni(String nome)
{
this.nome= nome;
}

questo inserito nella classe principale
e dopo public void controllo()
{
...
}

per poi nel main inserire questo:
Doppioni file = new Doppioni("File.txt");
file.controllo();
no ?
 
mi è venuto in mente che per fare una cosa fatta bene, si potrebbe usare EOF e non null...
(anche se in java non ricordo come si usa, al momento...)
perchè secondo me può capitare che letture in mezzo al file tornino null, magari per errori di formattazione del file, o solo per la legge di murphy... xD

[ot]
stoner ha detto:
[...]
Che sei l'avvocato di RedSkull92, se non ha capito niente può anche chiedermi lui di spiegargli cosa ho fatto, non credo di essermi mai ritirato per una spiegazione.
O.O
ti ha punto una zanzara?[/ot]
 
RedSkull92 ha detto:
Si li ho capiti gli errori commessi. cmq ho notato che deve per forza esserci
for(int p=0;p<500;p++) array[p]="";
altrimenti restituisce null.
cmq grazie stoner ho capito adesso.
ps: ma se li volessi fare tutto dentro la classe principale (Doppioni) mi basta mettere tutto dentro una classe ?
e creare un costruttore ?
es:
public Doppioni(String nome)
{
this.nome= nome;
}

questo inserito nella classe principale
e dopo public void controllo()
{
...
}

per poi nel main inserire questo:
Doppioni file = new Doppioni("File.txt");
file.controllo();
no ?
boh... a me non piace un approccio del genere, tanto vale non usare per niente una classe secondaria. Anche perchè il tuo modo di programmare ad oggetti lascia un pò a desiderare. Sembra un ibrido tra programmazione procedurale e programmazione ad oggetti, ti manca un pò di teoria della seconda, ti consiglierei di studiarti qualcosa in merito a questo prima di intraprendere la programmazione ad oggetti.

Poi ho letto che hai modificato il post mettendo il programma modificato..
http://paste2.org/p/190338
adesso, io non vorrei essere ripetitivo o fare il guasta feste, ma di fatto questa cosa non ha senso
Codice:
 for(int k=0;k<array.length;k++)
            {
                if (array[k].equals(""))
                {
                    scrivo.print(array[k]);
                    scrivo.flush();
                }
                else
                {
                    scrivo.println(array[k]);
                    scrivo.flush();
                }
            }
ora, fin quando hai un array da 500 elementi il problema non si pone, ma se hai un array di 300.000.000.000 di elementi, con due sole email diverse tra loro, avrai un array popolato da 2 elementi, ma tu continui a scorrerne 300.000.000.000 e aumentare il tempo di risposta del programma.

Fosse per me puoi farlo come ti pare, ma è sbagliato così.
 
No stoner quello lo avevo modificato prima che facessi tutte le modifiche...
cmq come mi consiglieresti di farlo ?
perchè ancora _( non ho compreso affondo come programmare in stile OO
Non capisco perchè non riesco a capire... xD
 
ah ok allora D:

Vabè, tornando al discorso precedente, l'errore sta nel fatto che programmi ad oggetti come se stessi facendo programmazione procedurale, con la sola differenza che metti tutto dentro a class name { /*code*/ }. Questo è l'errore che fai.

Posso consigliarti di leggerti per bene la teoria su un libro qualsiasi e magari sbirciare i programmi scritti ad oggetti per vedere come sono fatti. Aiuta molto.
 
Grazie stoner... in verità ti dico che dal libro che sto leggendo è un pò diverso lo stile per esempio usa il main per fare l'intero programma (cosa sconsigliata da razor) per esempio questo:
Codice:
import java.io.*;

class Analisi
{
	public static void main(String argv[])
	{
		InputStreamReader input = new InputStreamReader(System.in);
		BufferedReader tastiera = new BufferedReader(input);
		String testo;
		char carattere;
		int vocali = 0;
		int spazi = 0;
		double freqVocali, freqSpazi;
		
		System.out.println("Inserisci il testo da analizzare:");
		try
		{
			testo = tastiera.readLine();
		}
		catch(IOException e) {}
		
		testo.toLowerCase();
		for(int i=0; i<testo.length();i++)
		{
			carattere = testo.charAt(i);
			switch (carattere)
			{
				case 'a':
				case 'e':
				case 'i':
				case 'o':
				case 'u': vocali++;
						  break;
				case ' ': spazi++;
				          break;
			}
		}
		System.out.println("\nNumero di caratteri = " + testo.length());
		
		System.out.println("\nNumero vocali = " + vocali);
		freqVocali = (double) vocali / testo.length();
		freqVocali = (double) Math.round(freqVocali*100) / 100;
		System.out.println("\t Frequenza di vocali = " + freqVocali);
		
		System.out.println("\nNumero di spazi = " + spazi);
		freqSpazi = (double) spazi / testo.length();
		freqSpazi = (double) Math.round(freqSpazi*100) / 100;
		System.out.println("\tFrequenza di spazi = " + freqSpazi);
	}
}
dove potrei guardare per avere una buona idea sullo stile da adottare ?
 
boh.. non so che libro consigliarti. Ma su ogni libro di programmazione viene affrontato il concetto di classe, ne basta uno qualsiasi.

In quel caso comunque è normale che il tuo libro usi soltanto il metodo main per fare una cosa del genere, non vedo come suddividere il programma in più funzioni, o più classi, quel codice è banale, inoltre se hai comprato un libro che parte dall'abc del Java è ancor più normale.

Il fatto è che penso che tu sappia già programmare, quindi se il tuo libro fa quella roba vuol dire che parte proprio dalle basi, saltala e vai alla parte relativa alla programmazione ad oggetti (ereditarietà, polimorfismo, overloading, overriding).
 
Stato
Discussione chiusa ad ulteriori risposte.