Newsgroup: it.comp.lang.c++
Titolo: Inversione di un vettore

Come invertire (*) un vettore, utilizzando
sempre la stessa variabile vettoriale?
(*)
Es. 0.1, 2.34, 78.65, 100
diventa
   100, 78.65, 2.34, 0.1
Grazie
Ciao!

 wrote

il metodo piu' semplice e' quello di:
inizio=0 (primo elemento);
fine= ultimo elemento;
while(inizio<fine)
    scambia array[inizio], array[fine]
    incrementa inizio
    decrementa fine
Tommy

 sempre la stessa variabile vettoriale?
A naso:
#include <vector>
#include <algorithm>
std::vector< double > vettore;
std::reverse( vettore.begin(), vettore.end() );
Ciao!
-- 
---
*************** | Have you ever retired a human by mystake?
*** Azathot *** |
*************** | To contact me, ask me gently. Thanks.

     scambia array[inizio], array[fine]
Questo fa uso di una variabile in più (e quindi viola la richiesta di usare 
sempre la stessa variabile vettoriale).


 ha scritto nel messaggio
news:gia2cvsiebqjrc32i...@4ax.com...


 sempre la stessa variabile vettoriale).
Ma cosa dici.... ;-)
Io ho interpretato la richiesta come... non invertire l'array su di un altro
array, ma invertire l'array di origine.
(invertire su di un altro array e' ancora piu' banale).
Poi forse hai ragione tu... ed ho interpretato male io, ma se la richiesta
e' come dici tu, e' cmq una richiesta stupida ;-)
Tommy

 Tommy
Tuttavia mi scuso per aver risposto come se fossi sul NG di C.... infatti
pensavo di essere proprio li ;-)
il consiglio di usare std::reverse e' piu' appropriato al NG.
Tommy

> sempre la stessa variabile vettoriale).
vale anche per std::reverse. Probabilmente questo fara' uso di std::swap e
probabilmente questo fara' uso di una variabile di appoggio.
Tommy

 probabilmente questo fara' uso di una variabile di appoggio.
Dipende da come è implementato, è un dettaglio di cui sinceramente non mi 
cruccio. Per quanto mi riguarda potrebbe persino esservi una istanziazione 
specializzata del template vector per double o di reverse con double che 
NON fa uso di swap per invertire il vettore


>>> (invertire su di un altro array e' ancora piu' banale).
A presto,
Tommy

 fa uso o meno di una var di appoggio 
"reverse" non fa uso di MIE variabili di appoggio.
Il resto credo che sia fuffa.
Ciao!


 Il resto credo che sia fuffa.
Che cosa importa se sono TUE o sono dell'implementazione della standard
library.
Sono sempre variabili in un sorgente C++ !!!
E poi scusa, o non ci arrivi oppure dici cose sensa pensare...
Quando tu hai detto che "scambia array[inizio], array[fine]"
"fa uso di una variabile in più (e quindi viola la richiesta di usare
sempre la stessa variabile vettoriale)" non hai pensato che
scambia potrebbe essere:
std::swap(vettore[0],vettore[1]); // con vettore vectori di doubles.
In questo modo la variabile di appoggio (se c'e') non e' la MIA!
Non so cosa cambi, ma visto che a te cambia qualche cosa non vedo perche'
il mio esempio "violi le richieste" ed il tuo no?!? Mah, misteri della vita!
Poi, come ho detto, in un contensto C++ reverse e' piu' azzeccato...
solo non mi sono mai andate giu' risposte decise ma prive di senso e
dove le persone vanno avanti a difenderle senza aver argomentazioni valide.
Tommy

 
A proposito della famigerata variabile di appoggio :
Tutte le soluzioni fino ad ora viste operano in unte mpo proporzionale 
alla dimensione del vettore (e fin qui tutto ok).
Lo spazio di memoria utilizzato è costante (independente dalla 
dimensione del vettore) nel caso della variabile di appoggio usata da 
una eventuale swap.
È invece proporzionale alla dimensione del vettore nel caso di uso di un 
vettore temporaneo per la destinazione (soluzione decisamente da scartare).
Quindi ritengo l'uso della variabile di appoggio del tutto irrilevante 
per la questione "spazio".
Problema più subdolo: con la variabile di appoggio vengono chiamati 
molti costruttori di copia, con relativi problemi se il tipo contenuto 
in vector è attivo.
P.S. i principali vantaggi di Java e C# rispetto a C++ sono :
*non* hanno i template (per ora, poi coi generics ...)
*non* hanno il costruttore di copia e l'override di =

 
risposta OT:
il tuo sistema funziona solo se č applicabile xor
(o meglio ^ (č forse questo il cappellino famoso) )
quindi solo nel caso di tipi semplici
ma in questo caso č decisamente poco efficiente,
tanto piů che in x86 č prevista una istruzione XCHG
che scambia due registri a 32 bit

 non mi sono mai andate giu' 
Per questo tipo di problematiche, il newsgroup più indicato non è questo. Ti 
conviene vedere dalle parti di ".psicologia".


 *non* hanno il costruttore di copia e l'override di =
Duh.... ma il codice che ne esce fuori è "riusabile"?
Con tutto il rispetto eh... sono solo un povero studente.....

 
Il costruttore di copia e l'override di = sono purtroppo necessari a c++ 
data la sua struttura di oggetti allocati localmente su stack e la 
presenza dei puntatori.
In un modello a livello più alto come in Java o C# non sono più 
necessari, a prezzo però di altri svantaggi:
codice più lento (cone se si accedesse a tutti gli oggetti tramite 
puntatore, e gran numero di new e delete)
distruttori chiamati in modo non deterministico e non sicuro dal garbage 
collector.
Fose la cosa più importante e quindi difficie è capire quando usare C++ 
e quando Java o C# (non solo in base all'ambiente in cui il programma 
deve essere eseguito, ma soprattutto in base alla tipologia del problema 
da risolvere)

 da risolvere)
Il C++ è un ottimo investimento, in quanto un buon framework di classi 
ad-hoc per la risoluzione di problematiche comuni aggiunto alla intrinseca 
velocità del risultato della compilazione da sicuramente maggiori 
soddifazioni ai clienti di quegli sviluppatori che non si lasciano 
corrompere dalla diffusione (Java) e dalla potenza commerciale (C#).


sempre la stessa variabile vettoriale?
invece di girare un palazzo, spesso conviene 
spostarsi e guardare
il palazzo dall'altra parte.
sicuro di voler reversare il vettore?
non ti basta un reverse_iterator ?
sbirish

 temporanea in quanto sfrutta magari i registri della FPU.
Quali colpi di assembly ?!? Ma smettila ;-)
E poi non hai capito quello che ti ho detto:
Ti ho detto che il mio scambia potrebbe essere implementato con std::swap.
Il mio era pseudocode, non diceve *come* implementare scambia.
Se si usava std::swap era (parlando della var in piu') esattamente come
usare
std::reverse, della serie stupida: "se c'e' non e' mia pero'!".
Quindi la domanda e': come mai il mio pseudocodice violava le richieste ed
il tuo codice no?!?
Sei stato tu che mi hai detto che il mio pseudocodice usa una var in piu',
ma io non vedo
nessuna var nel pseudocodice... immagino ti riferissi a "scambia", ma
scambia potrebbe
essere std::swap (che a quanto dici, per motivi "ignoti" va bene...) oppure
una mia scambia che
non usa var di appoggio (anche se le avrei usate).
Tutto quello che volevo dire e' che tutto cio' che hai detto fino ad ora non
ha senso, a parte std::reverse che e' un buon consiglio.
- Hai detto che il mio pseudocodice usava una var di appoggio. Di questa non
c'e' traccia nel pseudocodice.
- Hai detto che se la var e' nei sorgenti della standard library va bene, ma
se la dichiari tu no...
- Hai detto che std::reverse va bene ma il mio pseudocodice no, mentre
avrebbe benissimo potuto utilizzare std::swap e essere quindi in quel senso
(var in piu') equivalente al tuo.
- Hai parlato di colpi di assembly nelle ex-stl.
- Tiri in ballo l'information hiding mentre non ha nulla a che fare.... ho
capito cosa volevi dire, ma non ha senso cmq.
- etc,.....
Tommy

 non ti basta un reverse_iterator ?
In ogni caso, può avere un senso invertire il vettore se è necessario 
operare notevoli operazioni sequenziali su di esso senza dover pagar pegno 
per ogni accesso...


 ha scritto nel messaggio
news:88cwa.89656$3M4.2...@news1.tin.it...


 ma io non vedo nessuna var nel pseudocodice... 
Del resto, c'era da immaginarselo.


 temporanea in quanto sfrutta magari i registri della FPU.
cosa pensi che sia l'uso di uno o piu' registri della cpu se non una
variabile cmq temporanea ??? cioe' non esiste uno scambio di valori senza
usare una variabile temporanea, seno' lo scambio sarebbe a perdita di 1
delle due informazioni.
almeno questo e' quello che mi hanno insegnato e che ho imparato in 8 anni
di programmazione e di elettronica, anche usando il dma per scambiare aree
di memoria si va cmq ad usare una zona temporanea di storing che null'altro
viene visto come variabile temporanea.

 di programmazione e di elettronica,
Spero sul serio che non ti abbiano spiegato in questo modo...


per ogni accesso...
alla luce del fatto che un attraversamento su vector con un iterator o
un reverse_iterator hanno la stessa complessità..
quale sarebbe il pegno da pagare?
sbirish.

 Ciao!
Però sono d'accordo con zeldan quando dice che la parte più difficile ed
importante è scegliere quale linguaggio usare.
Sono certo che il C++ non è IL linguaggio più adatto allo sviluppo di OGNI
applicazione, senza dubbio è molto versatile e molto potente, anche grazie
alla struttura multi-paradigma, e certamente è molto veloce, ma sono certo
che non può fare tutto.
Meglio conoscere più linguaggi e scegliere con cura di volta in volta
anziche affidarsi alla conoscenza di un unico linguaggio, che per quanto
potente non sarà mai adatto a tutte le necessità.

 da risolvere)
Se mi permetti una doppia citazione "mista":
simplicity is the trade-name of the incompleteness...
Ciao.
-- 
BSD is for UNIX lovers -- linux is for Windows haters.

 non ti basta un reverse_iterator ?
Si, e' vero. Dipende da cosa vuoi ....
Puo' essere pero' una soluzione.
Tommy

 Spero sul serio che non ti abbiano spiegato in questo modo...
perche' che c'e' di male nella mia preparazione ... non so tutto ma alcune
cose le so e si puo' sempre controbattere su un forum senza scartare subito
ponendo pregudizi sugli altri

Spero sul serio che non ti abbiano spiegato in questo modo...
Ho aperto un messaggio a caso di questo thread...
e tutto ad un tratto ho avuto la netta impressione
che non valga la pena leggere gli altri.
Andrea
PS:
  Riguardo al discorso degli scambi e a quanto
  sia "fiko" il triplo xor ci sono stati diversi 
  messaggi in passato. Credo sia addirittura una
  FAQ di it.comp.lang.c.



si tommy.. voleva solo essere una 
delle possibili soluzioni..
nulla di più..
ciao
sbirish

 temporanea in quanto sfrutta magari i registri della FPU.
ti sei fregato con le tue stesse mani....
e.... tutto questo discorso inutile sull'assembly, gli optimiser e tutto il
resto non e' quindi da tirare in mezzo.
Nella mia implementazione della standard library std::reverse chiama
std::iter_swap che a sua volta chiama std::swap che e' implementata cosi:
// TEMPLATE FUNCTION swap (from <algorithm>)
template<class _Ty> inline
void swap(_Ty& _Left, _Ty& _Right)
{
    // exchange values stored at _Left and _Right
    _Ty _Tmp = _Left;
    _Left = _Right, _Right = _Tmp;
 }
Ora mi dici dove sono i tue colpi di assembly!
Inoltre come vedi usa un oggetto temporaneo di appoggio.
Ultima cosa: cosa cambia se lo usa lui o lo usi tu? E' sempre codice
sorgente C++ che viene compilato, tuo o suo, non cambia nulla!
Detto questo, il mio optimiser se metto il codice da te scritto in main() mi
ignora completamente tutto, non mette proprio nulla in RAM!
Non usi le var e quindi lui le ignora. Poi ovvio che in casi pui' complessi
magari fara' come dici tu, ma l'esempio da te postato e' troppo trivial per
fregare un optimiser!
Tommy

 Del resto, c'era da immaginarselo.
Ok, non vale la pena di perdere tempo con te....
Tommy

 Non pare (vedi sopra).
Non pare cosa.....
Nella mia implementazione della standard library std::reverse chiama
std::iter_swap che a sua volta chiama std::swap che e' implementata cosi:
// TEMPLATE FUNCTION swap (from <algorithm>)
template<class _Ty> inline
void swap(_Ty& _Left, _Ty& _Right)
{
    // exchange values stored at _Left and _Right
    _Ty _Tmp = _Left;
    _Left = _Right, _Right = _Tmp;
 }
Ora mi dici dove sono i tue colpi di assembly!
Inoltre come vedi usa un oggetto temporaneo di appoggio.
Ultima cosa: cosa cambia se lo usa lui o lo usi tu? E' sempre codice
sorgente C++ che viene compilato, tuo o suo, non cambia nulla!
Sono troppo buono, sto perdendo tempo per te....
Tommy

 ponendo pregudizi sugli altri
Questa e' la frase migliore che tu potessi dire al nostro amico, bravo ;-)
Tommy

 E poi non hai capito quello che ti ho detto:
Tommy, stai perdendo il tuo tempo...
Come gią disse qualcuno:
"Non importa chi tu sia realmente.
Se ti comporti da Azimuth, sei Azimuth lo stesso" (cit.)
-- 
Gerolamo

 quale sarebbe il pegno da pagare?
Sarei molto interessato a vedere dove, nella specifica STL, questo è 
garantito. Sono convinto che saprai ben documentare la tua affermazione.


 potente non sarà mai adatto a tutte le necessità.
Meglio conoscere male tanti linguaggi o ottimamente uno solo? Non è una 
domanda filosofica... guardati intorno e rifletti sulla qualità media del 
software...


 mi ignora completamente tutto, non mette proprio nulla in RAM!
Prova a farci qualcosa di sensato. Vedrai che, se lo ignora, è un pessimo 
compilatore.


 Ha toppato piu' volte e non lo ha ammesso e non lo fara' mai....
Tommy, tommy... quanda pasta e fagioli devi ancora mangiare per diventare un 
programmatore C++... 


 Ok, non vale la pena di perdere tempo con te....
Guarda che mi sa che tra i due chi perde tempo sono io. 


 software...
Nè perfettamente uno, nè male tanti, meglio conoscere bene pochi linguaggi.
E quei pochi che siano buoni.

>>>temporanea in quanto sfrutta magari i registri della FPU.
std::swap, per definizione NON e' implementata a colpi di assembly. Hai
detto una cavolata (e molte altre in questo thread)... Basta!
Ora perche' continui a parlare di assembly? L'unico motivo per farlo era se
la tua affermazione fosse stata vera. Non e' cosi'!
Non puoi ammettere di aver sbagliato e farla finita con queste risposte da
bambino viziato che non sa ammettere di sbagliare?!?
Cresci!
Tommy

garantito. Sono convinto che saprai ben documentare la tua affermazione.
ciao Azathot,
dovresti sapere benissimo, che STL č un nome che non compare mai nello
standard, quindi parlare di specifiche STL č perlomeno una
imprecisione, in quanto nello standard si parla di standard library.
Non esiste alcun documento ufficiale che possa ricadere sotto il nome
di "specifica STL".
Se cmq ti avanzasse tempo per leggerti LO standard o perlomeno un 
draft, da un occhio a 23.1 table 65 e 24.4.1 e, sapendo che lo storage
di std::vector<T> č garantito essere contiguo (da una revisione dello
standard), prova a ripetere che usare un reverse_iterator č meno 
efficente di un iterator nell'attraversamento di un vector.
Ora.. mi spieghi cosa ti abbia fatto pensare che usare un
reverse_iterator possa essere meno efficente per attraversare un
vector?
Ti invito a mantenere un comportamento un pň piů distaccato, non č
piacevole leggere i tuoi insulti e provocazioni sul ng, specialmente
verso persone che "lavorano" per migliorarlo, e che hanno sicuramente
una buona preparazione ( e per quanto valga la mia stima ).
sbirish.

 una buona preparazione ( e per quanto valga la mia stima ).
Scusate eh, da estraneo che non vuole mettere assolutamente zizzania, ma
credo che azathot fino a quando non è stato aggredito gratuitamente si sia
comportato in linea con quello che è lo spirito del gruppo, tra l'altro ha
fornito soluzioni molto più IT di altri e sempre puntuali.
Ciao!
Z.

Per un uso frequente, avresti un calo di performances.
... no
sbirish.

 quindi senso.... perche' tu lo stai facendo?!?
Potresti essere meno offensivo? Grazie! Personalmente, trovo interessanti
gli interventi di azatot, perň non trovo invece molto piacevole il tono dei
tuoi messaggi! Credo che prima di tutto ci voglia il rispetto reciproco...
Ciao!
Z.

 Potresti essere meno offensivo?
La mia personale impressione e' che stai sbagliando bersaglio... o sei
un fake.
Ciao
Gian Michele

non ti basta un reverse_iterator ?
Dovrei usare le istruzioni standard;
ho trovato una possibile soluzione
ma non a me non funziona:
void Swap(int& a, int& b) {
  int temp = a;
  a = b;
  b = temp;
}
void InvertiVettore(TVettore vet, int nelem) {
  for (int i = 0; i < nelem/2; i++)
    Swap(vet[i], vet[nelem - i - 1]);
}
Grazie
Caio

 }
E' molto simile al mio algoritmo. Mi piace leggermente meno, ma sono gusti
personali, in realta' e' la stessa cosa ;-)
Ad ogni modo e' corretto e deve funzionare. Il principio e' identico al mio.
Arrivi fino a meta'!
Bene, se non ti funziona e' perche' devi passare il TVettore (che non so
cosa sia) come reference:
void InvertiVettore(TVettore &vet, int nelem) {
Altrimenti inverti una copia e non il vettore stesso!
Non so se hai notato ma il tuo post ha scatenato un casino, gente che ha
parlato di assembly, di optimisers, di FPU, di STL fatte a colpi di
assembly, di information hiding, etc..... Ah.... Finalmente il post e'
concluso e ne sono felice. La mia prima risposta era azzeccata, forse pochi
apprezzano il pseudocodice, ma almeno da la possibilita' a chi legge di
implementare invece di fare solo copia-incolla!
Ciao,
Tommy

Non so se hai notato ma il tuo post ha scatenato un casino
Chiedo scusa veramente a tutti, non volevo ovviamente
scatenare un putiferio; mi sono spiegato malissimo,
per "standard" intendevo utilizzare istruzioni fondamentali
Grazie a tutti ed ancora rinnovo le mie scuse sincere.

 wrote in message
q965cvog6lq90qsag...@4ax.com...

Non ti preoccupare questi si scannano una volta si e l'altra pure.
E se non ci sono loro ce ne sono altri a sostituirli.
Ma noi li perdoniamo perchč i loro consigli sono insostituibili a noi
profani.