[C++] Eliminare componente vettore

Cip Upupa
Ciao a tutti, mi chiedo come posso eliminare una componente di un vettore di dimensione $dim$ in modo che il vettore risulti di dimensione $dim-1$.

Nello specifico, mi si chiede di implementare un algoritmo che dato un vettore raddoppi consecutivamente i multipli di tre e cancelli le altre componenti.

Ad esempio, $(3, 4, 5, 3, 12, 8)$ diventerebbe $(3, 3, 3, 3, 12, 12)$

Il mio codice è il seguente:

#define dim = 10 //ad esempio, poi può essere a dim arbitraria

int vett[dim]

for(int i=0; i<dim; i++)
{
     if (vett[i]%3=0)
         vett[i++]=vet[i]
     
     else {/*codice mancante*/}
}


Ovviamente dove ho scritto codice mancante voglio inserire un algoritmo che cancelli tali dati, non nel senso di azzerarli, ma proprio toglierli dal vettore.

Inoltre, come posso implementare una funzione che conti le componenti rimaste?

Posso aggiungere nel ciclo for, dopo else, un codice del tipo newdim=dim-1; e fuori dal ciclo for cout << newdim; ?

P.S. ne approfitto per una delucidazione sugli array. Un array dinamico è un vettore tale che la sua dimensione può essere definita dall'utente in runtime, giusto?

Quindi ad esempio se avessi voluto che $dim$ fosse caricata in input da tastiera, avrei dovuto scrivere:

int dim;
int *vett;

cin >> dim;
vett = new int[dim];

for(int i=0; i<dim; i++){
     cout << "inserisci dato i-esimo: ";
     cin >> vett[i];
}


E' corretto? Grazie!

Risposte
Raptorista1
Ti è imposto di usare gli array o puoi anche usare la classe [inline]std::vector[/inline]?

In caso negativo, secondo me la cosa più facile da fare è costruire un altro vettore che riempi appropriatamente mentre leggi il primo.

vict85
Un commento veloce: nell'if hai usato l'assegnazione = invece dell'operatore di uguaglianza == .

Cip Upupa
Non mi è stato imposto niente ma la classe vector l'abbiamo vista piuttosto alla spicciola... grazie per la segnalazione

Raptorista1
La classe [inline]vector[/inline] contiene molte funzioni utili come [inline]push_back[/inline] e [inline]pop[/inline], che rendono immediate operazioni comuni sui vettori. Anche in questo caso, credo che la cosa più rapida da implementare sia la costruzione di un secondo vettore.

Super Squirrel
P.S. ne approfitto per una delucidazione sugli array. Un array dinamico è un vettore tale che la sua dimensione può essere definita dall'utente in runtime, giusto?


Un array dinamico e un array allocato dinamicamente sono due cose diverse. Un array allocato dinamicamente è un array statico (a dimensione fissa) creato durante l'esecuzione del programma (come correttamente mostrato nell'esempio da te postato).
La dimensione di un array dinamico invece viene aggiornata automaticamente nel momento in cui si aggiungono o rimuovono elementi all'array. Inoltre mentre un array statico è un'entità base del C++, un array dinamico deve essere implementato usando un'apposita classe/struttura (vedi classe vector). In pratica tra i dati membro di questa classe dovranno figurare un puntatore che punterà al primo elemento dell'array e due interi che terranno conto della dimensione e della capacità dell'array. Quando andiamo a rimuovere o aggiungere elementi, a variare sarà solo la dimensione, mentre la capacità rimarrà la stessa. Se poi la dimensione dovesse diventare maggiore della capacità, allora viene allocato dinamicamente un nuovo array statico più grande e il suddetto puntatore punterà al primo elemento di questo nuovo array.

A questo punto,visto che non credo che tu debba usare array dinamici, sei obbligato ad usare array statici. Detto ciò due sono le strade percorribili (chiamiamo n il numero di elementi multipli di 3):
- detto dim il numero di elementi da inserire nell'array, crei un array di 2*dim elementi (nel caso in cui tutti gli elementi siano multipli di tre). A questo punto dopo che l'algoritmo avrà fatto il suo compito considererai solo i primi 2*n elementi;
- se invece vuoi che il vettore risultante non abbia spazi inutilizzati sei costretto a scorrere l'array di partenza due volte. La prima volta ricaverai n e potrai quindi allocare dinamicamente un array di 2*n elementi, la seconda volta copierai gli n elementi nel nuovo array.

Dopo aver deciso in che modo vuoi risolvere l'esercizio allora si potrà anche entrare nel merito dell'algoritmo.

Cip Upupa
Ok, ho più o meno seguito il discorso sulla differenza tra i vari array.

Per quanto riguarda il mio problema, mi sembra più semplice creare un array di dimensione 2*dim.

Non è possibile invece scrivere un programma che controlli se un numero è multiplo di tre, e in caso affermativo lo trascriva in due componenti successive di un nuovo vettore?

Ho provato a scrivere un po' di codice, sono sicuro che faccia schifo ma spero che l'idea dietro sia decente. Inizializzo un secondo vettore di dimensione doppia mettendoci dentro tutti float uguali tra loro, chiamiamoli (qualcosa), tranne che per il primo elemento, inizializzato a un float differente. Adesso, con un ciclo for controllo tutti gli elementi del primo vettore: per il caso in cui trovo un multiplo di tre, con un nuovo ciclo for vado a porre il primo elemento di vsecond diverso dal float (qualcosa) (e quindi iniziando dal primo) e quello immediatamente successivo uguali a tale numero. Essendo degli int, sicuramente ora al prossimo if la condizione è rispettata fino all'ultima componente del secondo vettore riempita precedentemente.

#define dim = 10 //ad esempio, poi può essere a dim arbitraria

int vett[dim];
int vsecond[2*dim];
const float a=(qualcosa);

vsecond[0]=(un'altra cosa);
for (int i=1; i<2*dim; i++)
vsecond[i]=a; 

for(int i=0; i<dim; i++)
{
     if (vett[i]%3=0){ //se trovi un elemento divisibile per tre
         do{ 
             for(int j=0; j<2*dim; j++)
             {       
                  vett[i]=vsecond[j];
                  vett[i]=vsecond[j++];
             }
             } while(vsecond[j] != a); 
}


Spero di non beccarmi troppi insulti, è un mero tentativo fallimentare. La prima parte dell'esame sarà domani quindi ormai mi lancio senza avere più nulla da perdere :D

Super Squirrel
Scusami, ma ad un'occhiata veloce non sono riuscito a capire il ragionamento che c'è dietro, in ogni caso il codice mi sembra contenga parecchi errori :roll:

Per quanto riguarda il mio problema, mi sembra più semplice creare un array di dimensione 2*dim.

Non è possibile invece scrivere un programma che controlli se un numero è multiplo di tre, e in caso affermativo lo trascriva in due componenti successive di un nuovo vettore?


Indicando con n sempre il numero di elementi multipli di 3 io avrei fatto qualcosa del genere:

#include <iostream>

using namespace std;

int main()
{
    const int dim = 6;
    int n = 0;
    int v[dim];
    int v2[2 * dim];
    for(int i = 0; i < dim; i++)
    {
        cout << "v[" << i << "] = ";
        cin >> v[i];
        if(v[i] % 3 == 0)
        {
            v2[2 * n] = v[i];
            v2[2 * n + 1] = v[i];
            n++;
        }
    }
    cout << "v2:" << endl;
    for(int i = 0; i < 2 * n; i++)
    {
        cout << v2[i] << " ";
    }
}

Cip Upupa
Ho capito il tuo codice. Ti ringrazio per il tuo tempo.
Non ho troppe difficoltà a leggere il codice di altri, ma quando si tratta di scrivere, sono abbastanza perso. Immagino sia questione di pratica :-D

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.