[Fortran] "Selection sort" e dubbio valore finale contatori

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

[Fortran] "Selection sort" e dubbio valore finale contatori

Messaggio da joe »

Vorrei proporvi un quesito riguardante un programmino semplice semplice
in fortran, ma il discorso vale penso anche per altri linguaggi.

abbiamo un vettore contenente N valori numerici (reali o interi che siano
non penso faccia differenza).
Si vuole riordinare il vettore in modo che i valori risultino disposti in
ordine decrescente quindi dal più grande al più piccolo.

Ho scritto il codice, e alla fine sono riuscito ad ottenere un risultato
che mi pare giusto, almeno vedendo il grafico (perchè ho un vettore piuttosto
ingombrante con migliaia di elementi...).
Vi metto di seguito il pezzo del codice riguardante l'ordinamento del vettore
con l'algoritmo "selection sort":

Codice: Seleziona tutto

      ! Ordinamento array in ordine decrescente.
      !
      write(*,*)
      write(*,*) 'Ordinamento array'
      write(*,*) n, n-1
      write(*,*)

                                        open(unit=3,file='contatori',status='replace')
      do i=1,n-1
        max=i
        do j=i+1,n
          if (q(j)>q(max)) then
            max=j
          endif
        end do
        if (max/=i) then
          temp=q(i)
          q(i)=q(max)
          q(max)=temp
        endif
      end do
                                        write(3,*) i,j
                                        close(3)
Qual è il problema:
gli ultimi valori che i due contatori dovrebbero assumere sono rispettivamente:

i=n-1
j=n

invece nel file di controllo che ho chiamato "contatori", dove scrivo alla fine i valori di
"i" e "j", ecco che leggo:

n n+1

Anche se alla fine il risultato dovrebbe essere giusto perchè il vettore contiene ancora "n"
elementi, non mi torna questo punto.
Visto che non programmo in fortran da anni e mi sono dovuto rivedere un bel po' di roba,
potrebbe semplicemente essere normale che uscendo dai cicli "do", i contatori vengano incrementati
di un'unità....
Non mi ricordavo di questo comportamento, ma potrebbe anche essere.
Vorrei semplicemente chiedervi una conferma se avete voglia di spiegarmelo in due righe di numero.

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: [Fortran] "Selection sort" e dubbio valore finale contat

Messaggio da joe »

Penso che il problema sia intrnseco al ciclo "do" del fortran.
Infatti ho fatto una prova del nove con un semplicissimo codice:

Codice: Seleziona tutto

$ cat ciclodo.f
      program ciclodo
      do i=1,5
        write(*,*) i
      end do
      write (*,*) 'adesso i vale:'
      write (*,*) i
      end program
Se lo fate girare vedrete che il valore finale di "i" è 6.
Ora io da ignorante avrei detto che sarebbe stato "5" perchè il ciclo era impostato da 1 a 5...
Invece sembra che uscendo dal ciclo i venge incrementato ulteriormente di un'unità, e non ne capisco la causa.
Ne sapete nulla?

Graziein anticipo

Avatar utente
SIV
Linux 3.x
Linux 3.x
Messaggi: 921
Iscritto il: mer 25 apr 2007, 14:07

Re: [Fortran] "Selection sort" e dubbio valore finale contat

Messaggio da SIV »

Non conosco il Fortran ma non è così anche in C (per esempio)?

Codice: Seleziona tutto

int i;
for(i=1;i<=5;i++)
       printf("...\n");

printf("Valore di i: %d",i); //Come risultato restituisce i=6
È proprio l'ultimo incremento che manda i=6 e conseguentemente fa diventare falsa la condizione (i<=5) in modo che il ciclo possa terminare.

Spero di aver capito il problema e non aver fatto Capitan Ovvio

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: [Fortran] "Selection sort" e dubbio valore finale contat

Messaggio da joe »

Probabile, io conosco pochissimo il C e non ricordo assolutamente neanche i rudimenti, diciamo che lo conosco di svista. ;)
Probabilmente come dici tu ha un certo senso...
Forse è solo la sintassi del fortran che inganna:
mentre nel tuo ciclo "for" si vede che i viene reiterato di un'unità e la condizione diventa falsa quando i ha un'unità in più rispetto alla condizione di uscita, pertanto deve per forza essere incrementato altrimenti no esce dal ciclo...
Bè invece nella sintassi del fortran "do i=1,N". Io lo leggevo (probabilmente sbagliando a sto punto) come per i che va da 1 a N. O ancora meglio per rendere l'idea, per i uguale a 1, 2, 3,..., N.
Un po' come in bash: "for i in 1 2 3 4 ... N".
Il ciclo for com'è scritto in C mi fà pensare quasi alcostrutto "while do" del tipo fintanto che i è minore o uguale a 5, incrementa i e fai le tue cosette....

Non so se mi sono spiegato.
Comunque la tua risposta è apparentemente ovvia, come vedi la stessa cosa può essere vista con due sfumature differenti che ne stravolgono il significato...
Per cui approfondirò questo aspetto del ciclo do del fortran.

Se vuoi aggiungere commenti ulteriri non esitare, io non conosco tanti linguaggi e in generale ho solo dei rudimenti di programmazione strutturata, per cui immagino tu ne sappia più di me.
Intanto Grazie! :D

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: [Fortran] "Selection sort" e dubbio valore finale contat

Messaggio da joe »

Avevi proprio ragione: ho consiltato un bel documento trovato in rete (di Biagio Raucci: il linguaggio fortran 90/95).
La variabile di controllo all’uscita del ciclo
Un problema che insorge dopo aver lasciato un ciclo a conteggio riguarda il valore della variabile
contatore. A tal riguardo è bene notare che:
• La variabile indice del ciclo DO viene fissata al suo valore iniziale prima che venga presa
qualsiasi decisione se eseguire o meno il ciclo.
• La variabile indice viene aggiornata alla fine di ogni passaggio attraverso il ciclo, ma
sempre prima che sia deciso se eseguire o meno un altro passaggio.
• La variabile indice non viene modificata in nessun altro punto del programma.
La seconda condizione descritta implica che il valore di "i" viene reiterato prima che la condizione di uscita venga verificata.
Ciò comporta che il valore finale di i sia 6 e non 5 come io invece mi aspettavo.
Come sempre ho fatto bene a chiedere conferma qua, in ogni caso fortunatamente nonstante i miei dubbi il codice portava a risultato giusto e questa "anomalia" è invece il comportamento normale e corretto del fortran (come di altri linguaggi).

Avatar utente
SIV
Linux 3.x
Linux 3.x
Messaggi: 921
Iscritto il: mer 25 apr 2007, 14:07

Re: [Fortran] "Selection sort" e dubbio valore finale contat

Messaggio da SIV »

Esatto. Con un while di noterebbe ancora di più:

Codice: Seleziona tutto

int i=1;
while(i<=5)
{
   Qualcosa;
   i++;
}
É evidente che prima di uscire dal ciclo ci sia un'incremento "di troppo".

Per analogia mi è venuto in mente l' "errore della staccionata" che lessi per la prima volta sul libro "L'arte dell'hacking".

É presente anche online, pagina 112.

Rispondi