DOMANDA Esercizi in c++

Programmazione

Domehobb88

Salve a tutti, sto riprendendo C++ per vari motivi, stavo facendo qualche esercizietto per rinfrescarmi un pò.
Uno dei primi che ho trovato è stato questo:
Es1)Inserire un numero intero positivo e stamparlo con le cifre invertite
Allora la soluzione più immediata che mi veniva in mente, sarebbe stata quella di prendere il numero, metterlo in un array, invertire l'array e restituire il numero, so che è un poco macchinoso e super inefficiente ma vorrei provare questa soluzione per rispolverare alcuni concetti perchè molte cose non le ricordo. Quindi stavo provando su questa strada ma così ma non funziona nulla praticamente. Cioè il numero di cifre viene calcolato e restituito ma quando vado a visualizzare l'array ho come risultato un numero errato rispetto a quello immesso da tastiere, ad esempio se metto 453 mi esce:
"-1163005939-5-5-".

(Modifica)

Allora ho provato ad eseguire questo codice sia su dev c++ che su un compiler online e funziona, non mi da quel numero strano, premetto che stavo provando a compilarlo con visual studio code

C++:
#include<iostream>

using namespace std;

int calcolaCifre(int num){

    int ncifre=0;
        while(num>0){
        num = num /10;
        ncifre++;
    }
    return ncifre;
}


void inizializzaVettore(int vett[], int nc, int numero){

    int temp = numero;

    for (int i= nc-1; i>=0; i--){
        vett[i]= temp%10;
        temp /= 10;
    }

}

void visualizzaVettore(int vett[], int nc){

    for(int i=0; i<nc; i++){
        cout<<vett[i]<<"-";
    }
}

int main(){

    long int num;
    int cifre;

    cout<<"Inserisci un numero intero: "<<endl;
    cin>>num;

    int ncifre = calcolaCifre(num);

    //ARRAY CARICATO DINAMICAMNTE
    int *vett = new int[ncifre];

    inizializzaVettore(vett, ncifre, num);

    visualizzaVettore(vett, ncifre);

}
 
Ultima modifica:
#1

BAT

Staff Forum
Utente Èlite
Domehobb88 ha detto:
Allora la soluzione più immediata che mi veniva in mente, sarebbe stata quella di prendere il numero, metterlo in un array, invertire l'array e restituire il numero,
abbi pietà di me 😅
esagerando col codice
C++:
#include <iostream>
using namespace std;

int main(void) {
   char tasto = '1';
   int k;
   cout << "\n----- INIZIO -----\n";
   do {
        cout << "\nInserisci un numero intero positivo --> ";
        cin >> k;
        if(k<=0) cout << "Avevo chiesto POSITIVO ossia MAGGIORE DI ZERO";
        else {
            cout << "Numero invertito = ";
            while(k>0){
                cout << k % 10;
                k /= 10;
            }
        }
    cout << "\n\nAncora? (1=SI, altro tasto=NO) --> ";
    cin >> tasto;
   } while(tasto == '1');
   cout << "\n------ FINE ------\n";
   return 0;
}
 
#2

Domehobb88

Bat, abbi pietà anche tu di me! 😂
 
Mi Piace: BAT
#3

DispatchCode

Staff Forum
Utente Èlite
Non so se è considerato barare questo:

C++:
#include <iostream>
using namespace std;
int main() {
    int n;
    cout << "\nInserisci un numero intero positivo --> ";
    cin >> n;
    string str = to_string(n);
    cout << string(str.rbegin(), str.rend());
    return 0;
}
 
#4

Domehobb88

Si è barare 😂, no vabbè ma stavo solo facendo solo qualche esperimento, non ricordo una mazza più, devo assolutamente riprendere con la programmazione, ho acquistato il libro di Bjarne Stroustrup, C++. Ho letto che è uno dei migliori.
 
Mi Piace: BAT
#5

Domehobb88

Ragazzi scusate stavo vedendo qualche esercizio sulle funzioni, allora ho trovato l'algoritmo per verificare se un numero è primo

Vi posto il codice che ho trovato come soluzione

Nella funzione primo mi è chiaro il fatto che bisogna ricercare eventualmente i divisori di tale numero, infatti se si incontra un divisore allora banalmente il numero non è primo, non ho capito però perchè bisogna ricercare solo i divisori del numero fino alla radice quadrata di esso per risparmiare iterazioni e poi perchè nel ciclo for i viene incrementato di 2.

C++:
#include <iostream>
#include <math>

using namespace std;

int pari(int n)
{
 if (n%2 == 0) return 1; /* se il resto della divisione e' 0 ... */
 else return 0;
}
int primo(int n) {
    int max,i;
    if (n>=1 && n<=3)
         return 1;  /* 1,2,3 ? ok */

    if (pari(n))
 return 0;  /* no numeri pari */
    max = sqrt(n);
    for(i=3; i<=max; i+=2)
        if (n%i==0) return 0;
    return 1;
}
int main()
{
 int n,i;
 cout<<"Inserisci un numero: "<<endl;
 cin>>numero;
 if (primo(n))
{
    cout<<"Il numero inserito è primo"<<endl;
 }
 else
{
cout<<"Il numero inserito non è primo"<<endl;
}

  return 0;
}
 
#6

BAT

Staff Forum
Utente Èlite
Domehobb88 ha detto:
Nella funzione primo mi è chiaro il fatto che bisogna ricercare eventualmente i divisori di tale numero, infatti se si incontra un divisore allora banalmente il numero non è primo, non ho capito però perchè bisogna ricercare solo i divisori del numero fino alla radice quadrata di esso per risparmiare iterazioni e poi perchè nel ciclo for i viene incrementato di 2.
elimina la funzione PARI (è inutile) e sostituisci l'if corrispondente nella funzione primo direttamente col controllo
if (n%2 == 0) return 1;

Per quanto riguarda la domanda bisogna sapere delle cosette sui numeri primi: innazitutto sono numeri interi >1 (quindi 1 non è primo) divisibili solo per 1 e per se stessi; questo significa che il 2 è l'unico numero pari, tutti gli altri numeri primi sono dispari: 2,3,5,7,11,13...
di conseguenza una volta che sei certo che il numero da controllare non è pari (a parte il 2) deve per forza essere dispari
dato che nessun numero dispari è divisibile per 2 (avrebbe resto 1) basta controllare tutti i suoi divisori dispari a partire dal 3, quindi 3,5,7 ecc., ecco perché il divisore va incrementato di 2 ogni volta
ora pensaci un attimo: a parte se stesso, qual è il più grande divisore di qualsiasi numero? al massimo la sua metà
per esempio se prendi il 100, il suo massimo divisore è 50
se tu dovessi cercare i divisori di 100 (a parte 1 e 100) come faresti? inizi dal 2 e vedi che è un divisore, ma rifletti:
100:2=50 e quindi hai trovato che 2 è un divisore, perché 100=2x50, ma allora anche 50 è divisore
poi procedi, 3 non è divisore ma 4 sì
100:4=25 e quindi anche 25 è divisore di 100 infatti 100:25=4 ci siamo fino a qui?
se continui a cercare torverai 5 (e 20) e poi 10 (che è la radice quadrata di 100
adesso mettiamo i divisori in fila uno dietro l'altro:
2 - 4 - 5 -10 - 20 - 25 - 50
i divisori di un numero intero si dispongono a coppie intorno alla radice quadrata del numero che dividono (è una proprietà degli interi, si può dimostrare)
come conseguenza per trovare tutti i divisori di un certo numero basta controllare fino alla radice quadrata (perché quando ne trovi uno trovi automaticamente l'altro con cui fa coppia)
quindi per controllare se un numero è primo ti basta controllare tutti i numeri dispari minori o uguali alla radice quandrata (intera) del numero
 
#7

Domehobb88

Grazie Bat, forse ho capito, cioè il fatto della ricerca dei divisori fino alla radice del numero significa che la ricerca è ridondante sopra i divisori maggiori della radice? I divisori sono comunque trovati ho capito, però perchè non vengono considerati quelli maggiori della radice e perchè non vengono stampati nel programma.
 
#8

BAT

Staff Forum
Utente Èlite
Domehobb88 ha detto:
il fatto della ricerca dei divisori fino alla radice del numero significa che la ricerca è ridondante sopra i divisori maggiori della radice?

Domehobb88 ha detto:
però perchè non vengono considerati quelli maggiori della radice
perché sono disposti a coppie intorno alla radice quadrata: se non trovi divisori minori della radice quadrata, non puoi trovarne di maggiori; in altri termini un intero non può avere nessun divisore maggiore della radice quadrata se non ne ha di minori

prendi il 100, la radice è 10 le coppie di divisori intorno alla radice quadrata te le avevo colorate apposta
2 - 4 - 5 -10 - 20 - 25 - 50
2 fa coppia con 50, 4 con 25, 5 con 20

adesso prendi il numero 101 (è primo), la radice quadrata intera è 10
--> per verificare che sia primo col metodo precedente, devi controllare so 3,5,7,9 ma non 11 che è > della radice

a proposito vedo ora che nel tuo programma c'è un errore: 1 non è un numero primo quindi
if (n>=1 && n<=3) return 1; // ERRATO
deve essere
if (n>1 && n<=3) return 1; // OK

un po' meglio bisognerebbe fare
if(n<5) return (n==2 || n==3);
perché resttuisce 0 per tutti i numeri negativi (corretto: i numeri primi sono SOLO positivi, -2 e -1 per esempio NON sono primi) mentre ritorna 1 per n=2 e n=3
 
Mi Piace: Domehobb88
#9

bigendian

serve il C++ per una cosa del genere ?
Codice:
  GNU nano 7.2                                             main.c
#include <stdio.h>

int main()
{
        long unsigned int n;

        printf("inserisci :");
        scanf("%lu", &n);

        while (n) {
                printf("%d", n % 10);
                n /= 10;
        }
        printf("\n");

        return 0;
}

inserisci :123456789
987654321
 
#10

BAT

Staff Forum
Utente Èlite
bigendian ha detto:
serve il C++ per una cosa del genere ?
è a lui che serve per ristudiarselo 😅
comunque è passato al test di primalità
 
#11

bigendian

mah si :) era per giocare, bene test sia passato, ma ricordare che spesso il c++ e' cargo cult.
 
#12