Newsgroup: it.comp.java
Titolo: numero più vicino

Ciao a tutti, ho questo esercizio da risolvere:
Scrivere un programma che letti gli elementi di un vettore v1 e un numero k 
determini l'elemento di v1 piů prossimo a k
Ho pensato di risolverlo cosě, ma non funziona:
/**
 * @(#)esercizio7.java
 *
 *
 * @author
 * @version 1.00 2009/1/7
 */
public class esercizio7
{
    public static void main(String[] args)
    {
     int k=0;
     int v1[]=new int[10];
     for(int i=0;i<10;i++)
     v1[i]=Console.readInt("\ninserisci un numero intero: ");
     System.out.println("\n\ni numeri che hai inserito sono:\n\n");
     for(int i=0;i<10;i++)
     System.out.print(" "+v1[i]);
     k=Console.readInt("\n\nscegli un numero: ");
     int differenza1=0;
     int differenza2=0;
     int prossimo=v1[0];
      for(int i=0;i<10;i++)
      {
       differenza1=k-v1[i];
       differenza2=k-v1[i+1];
       if(differenza1==0)
       {
         prossimo=v1[i];
         break;
       }
         else if(differenza2==0)
        {
         prossimo=v1[i+1];
         break;
        }
       else if(differenza2<differenza1) prossimo=v1[i];
      }
     System.out.println("\n\ntra i numeri contenuti nell'array, quello che 
si avvicina maggiormente a quello scelto e': "+prossimo);
    }
}
Questo l'output del programma:
i numeri che hai inserito sono:
 12 5 8 6 9 2 3 4 6 8
scegli un numero:  20
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
    at esercizio7.main(esercizio7.java:34)
Potete darmi un suggerimento?  Grazie. 

 Ho pensato di risolverlo così, ma non funziona:


		int v[]=new int[10];
		int val = 0;
		int minDiff = Integer.MAX_VALUE;
		int diff=0;
		for(int i=0;i<10;i++)
			v[i]=(int)(Math.random()*100);
		System.out.println("\n\ni numeri che hai inserito sono:\n\n");
		for(int i=0;i<10;i++)
			System.out.print(v[i]+" ");
		k=(int)(Math.random()*100);
		for(int i=0;i<10;i++)
		{
			diff = Math.abs(k-v[i]);
			if(minDiff > diff){
				minDiff = diff;
				val = v[i];
			}
		}
		System.out.println("\n\ntra i numeri contenuti nell'array, quello
che si avvicina maggiormente a [ "+k+" ] e': "+val);
	}
L' ArrayIndexOutOfBoundsException te la da perchè qui "differenza2=k-v1
[i+1]; " cerchi di leggere l'elemento v1[10] quando i = 9 mentre in
tuo array va da 0 a 9.

 Potete darmi un suggerimento?  Grazie.
L'eccezione che hai riportato ti dice già tutto.
Se non sai leggerla significa che non hai chiaro il concetto di array,
e quindi ti consiglio di ripassarlo opportunamente.

 array va da 0 a 9.
Complimenti, ora si che l'hai aiutato.


Gli ho detto il perchè dell'errore, questo non gli impedisce di
approfondire...anzi.

 Ho pensato di risolverlo cos�, ma non funziona:

i<10 ?
Ma per favore ....
E se hai un array di 23 elementi che fai? vai dal cliente modifichi il 
sorgente e ricompili? -_-

 sorgente e ricompili? -_-
Ma per favore...ti sembra un programma per un cliente?
In un esercizio del genere non c'e' nulla di male nel non utilizzare
valori parametrici (sebbene sia comunque meglio una costante come
MAX_ELEMENTS).

cicap ha scritto:

Immaginavo che non fosse un programma con una sua dimensione 
commerciale. È relativamente poco che faccio il programmatore per 
professione (circa sei anni), ma sviste così grosse non ne prendo più da 
tempo.
Ritengo solo che non sia una pratica da consigliare e che incapsulamento 
e riusabilità siano cose da perseguire.
Mettere i < 10 non mi pare molto riutilizzabile, a meno che uno non 
dichiari sempre array di 10 elementi.


Credo che per una persona che non ha ancora chiaro cosa sia
ArrayIndexOutOfBoundsException non sia ancora fondamentale parlare di
riusabilità e incapsulamento.
In questo contesto i < 10 non è una svista dal momento che questo è
(credo) un esempio fine a se stesso per prendere dimestichezza col
codice e iniziare a capire le possibilità del linguaggio; non credo
proprio sia parte di un modulo di un'applicazione commerciale o di un
framework.
Non credo gli sia quindi utile per ora ragionare su questi aspetti.
Magari è solo un mio punto di vista, essendo io molto meno esperto.

zav...@gmail.com
 ha scritto:

Ecco, io invece penso esattamente il contrario: Le pessime abitudini si 
prendono proprio all'inizio e poi uno se le sconta.
Il fatto che gli oggetti possano dire un sacco di cose riguardo se 
stessi imho è una delle prime cose da imparare.
usare una clausola come i < v1.length non ha nessun lato negativo 
rispetto a i < 10 e porta a pensare nella maniera corretta.
Il tutto IMHO chiaramente.
Se poi uno si trova meglio con i < 10 direi che siamo tutti contenti e 
pace :)

 
zava...@gmail.com
 ha scritto:

Bhe quello che dici ha sicuramente un senso, per me poteva pure usare
for(int i : v1), dico solo che probabilmente nemmeno conosce queste
possibilità e le si acquisisce un passo alla volta.
Punti di vista ovviamnete ^_^

zav...@gmail.com
 ha scritto:

ecco, ad esempio il foreach io non lo uso perché ormai sono abituato a 
fare i for con i < array.length e mi rendo conto che invece delle volte 
sarebbe comodo e potrei fare del codice più leggibile (della 
compatibilità con le JVM < 1.5 forse ormai ce ne si può infischiare).
È meglio imparare bene fin dall'inizio



Se non riesci neanche a passar da 
for (int i = 0; i < n; ++i) a for (String s : list)
non vedo come tu possa imparare un nuovo linguaggio di programmazione.
Continuando la discussione, ha ragione zavadvd: il ragazzo sta semplicemente
scrivendo i suoi primi codici sorgenti, per cui è ridicolo considerare errore
i < 10. 
Anzi sarebbe un errore costringerlo a considerare aspetti piu' complessi. 
Allo stato attuale ha bisogno di vedere numeri, stringhe e cose molto semplici, tra cui
imparare che un array può essere iterato da 0 a n-1. 
Null'altro.

 ha scritto nel messaggio 
news:gk528p$flm$1...@news.task.gda.pl...


 Grazie comunque a tutti per i consigli.
Un piccolo consiglio che credo ti possa tornare utile: se ordinavi gli 
elementi dell'array avresti potuto usare una ricerca binaria ed evitare 
di scorrerlo tutto per trovare l'indice voluto.

 di scorrerlo tutto per trovare l'indice voluto.
Ma per ordinarlo non avrebbe dovuto comunque scorrerlo?


si ma solo una volta (ovviamente considerando che l'array non si 
modifichi), mentre così ogni volta deve ripartire da zero. Inoltre la 
complessità di un ordinamento (n*log(n)) è di poco superiore ad una 
scansione, quindi già dalla seconda volta ci guadagna.

  }
Come mai fai quella serie di if con quel break(che a me personalmente
piace poco ^_^)?
Lo fai "solo" per evitare di scorrerti tutto l'array se trovi un
valore che è uguale a quello cercato?
A quel punto potresti metterle come condizioni di uscita del for:
for(int i=1;i<DIM && differenza1 != 0 && differenza2 != 0;i++) //
probabilmente ne basta 1 dei 2 ^_^

 wrote:

Scusami, ma forse non capisco io, ma pure ora lo scorre una sola volta
(lasciando perdere la stampa a video che comunque potrebbe essere
fatta nello stesso for).
Tu intendi nel caso l'array sia fisso e il valore k vari?
Cosa che comunque per come è implementato l'esempio non è prevista, se
non erro.

 Null'altro.
Beata pedagogia ...

 Beata pedagogia ...
Certo, certo.
Forse non hai mai visto un algoritmo dove il numero di elementi di un
array
è fissato a priori? Ad esempio nel gioco degli scacchi.
Se seguisse un tuo corso, finirebbe con il credere che bisogna sempre
piazzare una costante in un file di property. Il che  è una cazzata.

cicap ha scritto:

Eh, beato te che hai delle certezze nella vita :)
Io non tengo corsi (non per lavoro almeno)
Ho solo letto alcune righe riguardo le linee guida da seguire nella 
programmazione, ma effettivamente se poi il codice funziona ed è 
mantenibile si può dire che è questione di gusti, quindi stai pure 
tranquillo: hai ragione tu e torto io
Chiudo qui che sento l'ago del flame-o-meter che ticchetta, vado a 
guardare se è tarato.
Ciao :)

 probabilmente ne basta 1 dei 2 ^_^
Se lo metto come condizione in quel modo mi restituisce un errore di Out
of Index, e non so perchč. Ad ogni modo facendo cosě non so se
l'iterazione č terminata perchč ho trovato un valore uguale oppure perchč
ho letto tutto l'array. Inoltre se termina perchč ha trovato un valore
uguale non viene fatta l'assegnazione di "prossimo".
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 non erro.
intendevo che se fossero stati più numeri da cercare all'interno
dell'array allora sarebbe stato più vantaggioso averlo ordinato: non è 
necessario usare due variabili "differenza" in quando ne basta una e si 
cerca il minimo (con limite inferiore uguale a zero). In questo modo non 
sarebbe neppure uscita l'eccezione.
Avendo un array ordinato inoltre ci si può fermare prima anche senza 
usare una ricerca binaria in quanto appena la differenza incomincia a 
crescere nuovamente vuol dire che si è raggiunto il minimo.

 tranquillo: hai ragione tu e torto io
Non è questione di gusti. Mettere sempre e comunque le costanti in un
file di configurazione, invece che usare ad esempio
static final int MAX_ELEMENTS
è un'enorme stronzata (non opinabile). Se ti sembra di aver letto
linee guida del genere forse dovresti ritornarci e rileggere meglio.

 linee guida del genere forse dovresti ritornarci e rileggere meglio.
Ma chi ha mai detto nulla riguardo a costanti in file di configurazione?
Rileggiti quello che ho scritto :)
Inoltre volendo proprio seguirti su questo argomento che introduci tu 
adesso pensa al caso in cui scrivi una applicazione che va installata su 
X client che devono trovare il DBServer in base al nome di NetBios (ma 
potrebbe essere qualche altro parametro). Dove li archivi? io ho optato 
per un xml editabile con qualsiasi editor.
Tu cosa proponi invece?
Di fare programmi che gestiscano al massimo array di 10 elementi?
Di fare programmi che si possano connettere slo ad un server che si 
chiami «TUOPC»?
Di suggerire a chiunque voglia installare il programma su un diverso PC 
di portarsi dietro workstation, IDE, compilatore?
Sono sempre pronto ad imparare :)
Illuminami

  for(int i=0;i<DIM;i++)
Ripeti due volte 10: meglio così:
   int k=0;
   final int DIM=10;
   int v1[]=new int[DIM];


 Illuminami
ROTFL. Quando vedrò un programma di scacchi dove il numero delle
caselle è salvato su un file esterno per essere piu' dinamico, saprò
chi l'ha scritto (ed eviterò di usarlo).

 Di fare programmi che gestiscano al massimo array di 10 elementi?
Potrebbe essere una idea. Solo array di 10 elementi. ;{-).
Quello che ha implementato i Vector ci e' andato vicino  ;{-).
Fiuuuu! Temevo che il 3d terminasse. Dopo il tuo ticchettante
flame-o-meter. Vedo che c'e' speranza.;{-).
Attento pero' alla troppa illuminazione, puo' avere effetti collaterali
;{-))
Ciao.
--
ac

 uguale non viene fatta l'assegnazione di "prossimo".
Bhe utilizzabdo il tuo codice si può scrivere così:
 int differenza1=Math.abs(k-v1[0]);
 int differenza2 = 0;
 int prossimo=v1[0];
 int i=1;
 for( ;i<DIM && differenza1 != 0 ;i++)
 {
  differenza2=Math.abs(k-v1[i]);
  if(differenza2<differenza1)
  {
   prossimo=v1[i];
   differenza1=differenza2;
  }
 }
Non dovrebbe dare errori e per sapere se hai letto o meno tutto
l'array basta che controlli se differenza1 == 0 e puoi anche sapere a
che punto si è fermato il ciclo grazie ad i.

 MAX_ELEMENTS).
magari se intanto nel ciclo usa la proprietà length...

 magari se intanto nel ciclo usa la proprietà length...
Ci sono molti punti per cui quel codice fa schifo. MAX_ELEMENTS non era riferito a 
al ciclo for.

 al ciclo for.
eh, però il messaggio a cui rispondevi parlava del i<10 nel ciclo for.

 chi l'ha scritto (ed eviterò di usarlo).
Tieni conto che invece io per lavoro spesso devo maneggiare codice
scritto da ragazzetti che pensano come te.
Trovati tu in mezzo a qualche migliaio di righe, magari di PhPcrap e
cerca di capire come mai in quel punto c'è una chiamata ad un $i<4, non
documentato e di cui non riesci a capire (se non dopo ore) che in realtà
il 4 era un
count($arrayChenonCentraUnCazzoESiTrovaInUnFileChenonCentraNiente)
Che ovviamente si chiama $sonoUnaCosaTotalmenteDiversa o meglio
$varConTab
A me capita spesso.
Anche io vorrei poter avere la libertà di non usare simili crap-o-rama,
purtroppo ci lavoro.
Tu sentiti fortunato dato che puoi scegliere.
Adesso rispondi in modo alterato e a sproposito, così avrai anche
l'ultima parola, te la lascio volentieri :)

 Dove l'ho detto?
"E se hai un array di 23 elementi che fai? vai dal cliente modifichi il 
sorgente e ricompili?"
Siccome non sai nulla dell'esercizio, e affermi che c'e' il problema della
ricompilazione dal cliente, se ne può facilmente dedurre che per te le costanti 
non esistono.
Prova a confutare questo: ci sono molti algoritmi dove non ha senso rendere
configurabile la dimensione dell'array. 
Se non riesci a confutare, sopra hai scritto una cazzata che può confondere 
l'autore del post originario. 
Il resto delle tue farneticazioni non mi interessa.