Discussione tradurre codice python a C++

Davide27

Utente Bronze
4 Marzo 2022
38
17
1
20
Salve a tutti per caso qualcuno riuscirebbe a darmi una mano a "tradurre" questo codice da python a C++?
Python:
import random

lista = []

print("Inserire numero studenti")
studenti = int(input())

for i in range (studenti):
  lista.append(i+1)
 
while (True):
  print("Selezionare \'*' per generare un' estrazione o 0 per uscire")
  azione = input()
  if (azione == '*'):
    numero = random.choice(lista)
    print(numero)
    lista.remove(numero)
  else:
    break
Grazie a tutti!
 

Kode

Utente Emerald
10 Dicembre 2013
1,225
80
369
623
Spiego un pò il codice cosi da non farti perdere tempo nella sua comprensione:
1. Il tipo list in python è dinamico, ossia non ha una dimensione fissa, la cosa più simile in c++ è la classe vector
2. La libreria random di Python è molto più ad alto livello, in C++ si utilizza rand()%max per indicare un numero da 0 a max - 1, poi per accedere all'elemento si applica l'operatore [] (accesso indicizzato)
3. Il remove di un elemento è abbastanza facile in Python, in C++ bisogna gestirlo tramite iterati e shift per mantenere la struttura consistente e realizzare lo stesso effetto di del .remove di Python, ho scritto una funzione ad-hoc per la rimozione di un elemento da un vettore generico e per una posizione prefissata.
4. La funzione .choice di random in Python definisce le dimensioni correnti, in C++ ti devi mantenere tale valore e aggiornarlo ad ogni eliminazione, ecco perché ho aggiornato la variabile studenti andando a decrementarla ad ogni rimozione.

Giusto per informazione, il tuo codice non fa distinzioni tra 0 e altri simboli differenti da * per la terminazione. Inoltre, quando si scrivono tanti * quanti sono gli elementi del vettore, si ha una floating point exception (quindi nel caso basta fare un controllo che se la dimensione degli elementi correnti è 0, il ciclo termina a prescindere dalla chiave inserita).

C++:
#include <iostream>
#include <vector>
using namespace std;

template <typename T>
void remove(typename std::vector<T>& vec, size_t pos)
{
    typename std::vector<T>::iterator it = vec.begin();
    advance(it, pos);
    vec.erase(it);
}

int main(void){
    int studenti;
    cout << "Inserire numero studenti: ";
    cin >> studenti;
    cout << "Numero studenti: " << studenti << "\n";
    vector<int> lista;
    for(int i = 0; i < studenti; i++){
        lista.push_back(i+1);
    }
    
    while(true){
        cout << "Selezionare \'*\' per generare un\' estrazione o 0 per uscire\n";
        char azione;
        cin >> azione;
        if(azione == '*'){
            int random = rand()%(studenti); // accessi 0 a studenti - 1
            int numero = lista[random];
            cout << numero << "\n";
            remove(lista, random);
            studenti = studenti - 1;

        } else break;

    }
    return 0;
}
 

Kode

Utente Emerald
10 Dicembre 2013
1,225
80
369
623
non ho capito molto bene questa parte:
C++:
template <typename T>
void remove(typename std::vector<T>& vec, size_t pos)
{
    typename std::vector<T>::iterator it = vec.begin();
    advance(it, pos);
    vec.erase(it);
}
Allora:
1. I vettori si scandiscono tramite iterator (un oggetto che scandisce i termini di una collezione, in questo caso del nostro vector)
2. advance è una built-in che va avanzare l'iterazione fino ad un determinato elemento determinato da pos, quindi quello che fa è avanzare fino ad una posizione data, un pò come si fa con il ciclo for fino ad una posizione x.
3. vec.erase(it) rimuove l'elemento puntato dal nostro iterator che, ricordiamo, era sul vettore vec passato al punto 1.
4. La funzione prende un tipo di dato generico (T) quindi può essere utilizzati su qualsiasi tipo di vettore (intero, floating point...), per farla generica, la funzione specifica un template che definisce il markup del tipo generico (ossia T).

In sostanza: Prende in input una lista di elementi e un indice (quello da cancellare), scandisce i termini fino ad arrivare a quell'indice, e lo elimina.
 

Davide27

Utente Bronze
4 Marzo 2022
38
17
1
20
Allora:
1. I vettori si scandiscono tramite iterator (un oggetto che scandisce i termini di una collezione, in questo caso del nostro vector)
2. advance è una built-in che va avanzare l'iterazione fino ad un determinato elemento determinato da pos, quindi quello che fa è avanzare fino ad una posizione data, un pò come si fa con il ciclo for fino ad una posizione x.
3. vec.erase(it) rimuove l'elemento puntato dal nostro iterator che, ricordiamo, era sul vettore vec passato al punto 1.
4. La funzione prende un tipo di dato generico (T) quindi può essere utilizzati su qualsiasi tipo di vettore (intero, floating point...), per farla generica, la funzione specifica un template che definisce il markup del tipo generico (ossia T).

In sostanza: Prende in input una lista di elementi e un indice (quello da cancellare), scandisce i termini fino ad arrivare a quell'indice, e lo elimina.
grazie mille!
Messaggio unito automaticamente:

Allora:
1. I vettori si scandiscono tramite iterator (un oggetto che scandisce i termini di una collezione, in questo caso del nostro vector)
2. advance è una built-in che va avanzare l'iterazione fino ad un determinato elemento determinato da pos, quindi quello che fa è avanzare fino ad una posizione data, un pò come si fa con il ciclo for fino ad una posizione x.
3. vec.erase(it) rimuove l'elemento puntato dal nostro iterator che, ricordiamo, era sul vettore vec passato al punto 1.
4. La funzione prende un tipo di dato generico (T) quindi può essere utilizzati su qualsiasi tipo di vettore (intero, floating point...), per farla generica, la funzione specifica un template che definisce il markup del tipo generico (ossia T).

In sostanza: Prende in input una lista di elementi e un indice (quello da cancellare), scandisce i termini fino ad arrivare a quell'indice, e lo elimina.
poi un altra roba... qua nel while perchè hai messo true?

Codice:
while(true){  //perchè true?
        cout << "Selezionare \'*\' per generare un\' estrazione o 0 per uscire\n";
        char azione;
        cin >> azione;
        if(azione == '*'){
            int random = rand()%(studenti); // accessi 0 a studenti - 1
            int numero = lista[random];
            cout << numero << "\n";
            remove(lista, random);
            studenti = studenti - 1;

        } else break;

    }
 

Kode

Utente Emerald
10 Dicembre 2013
1,225
80
369
623
grazie mille!
Messaggio unito automaticamente:


poi un altra roba... qua nel while perchè hai messo true?

Codice:
while(true){  //perchè true?
        cout << "Selezionare \'*\' per generare un\' estrazione o 0 per uscire\n";
        char azione;
        cin >> azione;
        if(azione == '*'){
            int random = rand()%(studenti); // accessi 0 a studenti - 1
            int numero = lista[random];
            cout << numero << "\n";
            remove(lista, random);
            studenti = studenti - 1;

        } else break;

    }
Perché te hai messo true nel while di Python e dato che volevi che il programma continuasse finché scrivi "*", ho mantenuto la tua logica... dato che la richiesta se non sbaglio era proprio quella di tradurre il programma da Python a C++.
 

Davide27

Utente Bronze
4 Marzo 2022
38
17
1
20
Perché te hai messo true nel while di Python e dato che volevi che il programma continuasse finché scrivi "*", ho mantenuto la tua logica... dato che la richiesta se non sbaglio era proprio quella di tradurre il programma da Python a C++
si ma quindi anche in c++ posso mettere il true nel while?