Newsgroup: it.comp.lang.c++
Titolo: problema con l'output

Allora, innanzitutto un saluto al ng...poi, avrei una domandina.
Vorrei controllare che un dato numero inserito da console sia o meno un
"numero primo".
In giro vi sono già delle funzioni disponibili dalle quali copiare ma vorrei
tanto arrivarci seguendo dei ragionamenti e non copiando qui e la.
In pratica il ragionamento che faccio io è il seguente:
1-prendo un numero NUM
2-lo divido per due tenendo solo la parte intera e ottengo META
3-faccio la divisione in modulo di NUM%X ove X è inizialmente META-1 e
poi in loop fino ad arrivare a 2 ovvero for(x=meta-1;x>2;x--)
4-controllo nel loop che la div in modulo sia diversa da zero.In tal caso 
NUM è primo.
La funzione che ho scritto funziona se non fosse che in output se il numero 
è primo
mi scrive 2 volte "il numero è un numero primo" e se non lo è scrive prima 
che lo è
e poi che non lo è.
vi riporto il codice.
void scoprinumero()
{
     unsigned long int num, meta, x;
     cout<<"inserisci un numero per controllare che sia PRIMO\n";
     cin>>num;
     system("cls");
     meta = num/2;
     x = meta-1;
    for(x = meta-1;x>2;x--)
     {
                          if((num%x)!=0)
                          {
                          cout<<"Il numero "<<num<<" e\' un numero 
primo\n\n";
                          }
                          else cout<<"Il numero "<<num<<"  e\' un numero 
primo\n\n";
     }
}
Dove sbaglio? Mille grazie e scusate la lunghezza.
-- 
franz 

 NUM è primo.
a parte qualche stranezza,
e' il controllo del for che e' sballato (ad esempio 9 me lo da come numero primo)
se trova un numero per cui e' divisibile, deve uscire dal ciclo altrimenti controlla tutti i numeri e ti riporta per ciascuno se e' o meno divisibile
corretto sarebbe:
#include <iostream>
using namespace std;
int main()
{
     unsigned long int num, meta, x;
     cout<<"inserisci un numero per controllare che sia PRIMO\n";
     cin>>num;
    for(x = num/2; x>2 ;x--)
     {
                          if((num%x)==0)
                          {
                          cout<<"Il numero "<<num<<" non e\' un numero primo\n\n";
			  return false;
                          }
     }
    cout<<"Il numero "<<num<<"  e\' un numero primo\n\n";
    return true;
}
comunque l'idea del modulo mi e' piaciuta, mi ci sono intrippato un po' e ti posto il risultato
/*
la logica si basa su come si fa a mano,
ovvero si controlla con 2, se e' divisibile lo si divide per 2
e si ricomincia col risultato
esempio
60/2= 30/2= 15/2= no
15/3= 5/3= no
5/5= 1
fine
ps controlla anche per i numeri non primi, ovvero 4 6 8 9 ecc
*/
#include <iostream>
using namespace std;
int main () {
  unsigned long int num, x, last;
  cout << "Inserisci un numero per controllare che sia PRIMO\n";
  cin >> num;
  //  system("cls");
 
  bool primo = true; // ipotizziamo
  last=	num;
  // iniziando da 2 perche' ogni numero e' divisibile per 1
  x=	2;
 
  // continua finche' il numero da controllare
  // e' maggiore del numero con cui lo controllo
  while (last >= x && x!=num) {
    // se il numero non da' resto e' divisibile, percio' non e' primo ...*1
    if ( (last % x) == 0) {
      if (primo) { // se e' il primo numero divisibile che trovo ...*2
	primo = false;
	cout << "Il numero " << num << " non e\' un numero PRIMO\n";
	cout << "e' divisibile per: " << x; // lascio la riga continuabile
      } else { // *2... altrimenti continuo a scrivere sulla stessa riga
	cout << ", " << x;
      }
      // visto che e' divisibile lo si divide e si continua col risultato
      last= last/x;
      x=2; // e ricominciando a controllare da 2
      // *1... altrimenti provo col prossimo numero
    } else {
      x++;
    }
  }
  if (primo) {
    cout << "Il numero " << num << " e\' un numero PRIMO\n\n";
  } else {
    cout << ";\n\n";
  }
 
  return 0;
}
E' stato un piacere ;)
t1t0

 2-lo divido per due tenendo solo la parte intera e ottengo META
Estraendo la radice quadrata di NUM ottieni un algoritmo di gran lunga 
più veloce.
Assumi di avere un numero di 20 cifre e che occorra un nanosecondo per 
controllare un divisore.
Cercando fino a NUM/2 impieghi ~1585 anni, mentre cercando fino a 
sqrt(NUM) impieghi 10 secondi.
Fai un po' te :-)
Kiuhnm

Grazie mille per la dritta sul ciclo.
Se il giochino di scoprire se un numero è primo o no ti ha intrippato,
allora ti piacerà anche questo...la ricerca di un numero primo tra
N numeri, ove N è stato dato da tastiera.
Non è molto diverso dal precedente algoritmo però utilizza la radice
quadrata di cui parlava Kiuhnm.
void primi()
{
     long int dividendo,n;
       long int divisore;
       long int radice;
       char grado = 167;
       int fermati;     /* segnala la fine del ciclo */
       int conto = 3;   /* contatore */
       cout <<"tra quanti numeri vuoi cercare quelli che sono PRIMI?";
       cin>>n;
       /* 2 e' un numero primo, stampa 2 */
       cout<<"\n1"<<grado<<"\t\t2";
       /* 3 e' un numero primo, stampa 3 */
       cout<<"\n2"<<grado<<"\t\t3";
       //dividendo = 3;
     for(dividendo = 3;dividendo<n;dividendo += 2)
     {
               divisore = 3;
               radice   = sqrt(dividendo );
               fermati  = 0;
               do
               {
                       /* se il resto (modulo) di dividendo/divisore non è 
zero */
                       if((dividendo % divisore) != 0)
                       {
                               /* e il divisore è maggiore della radice del 
dividendo  */
                               if (divisore > radice)
                               {
                                       /* allora il dividendo è primo, e lo 
stampa */
                                       cout<<"\n"<<conto<<""<<grado<<"\t\t"<<dividendo;
                                       ++conto;
                                       fermati = 1;
                               }
                       }
                       else {
                               fermati = 1;
                       }
                       divisore += 2; /* passa al numero dispari successivo 
*/
               }
               while (fermati == 0);
       }
}
------
franz 

 N numeri, ove N è stato dato da tastiera.
Per enumerare i numeri primi a me piace questo. E' sostanzialmente una
diagonalizzazione del crivello di Eratostene che, se si utilizzano
interi di dimensione arbitraria invece dei long long che ho usato io,
e' adatto a ricercare primi di dimensione arbitraria. (e' direttamente
derivato da un algoritmo postato su questo newsgroup da Alex Martelli
qualche anno fa e non ne conosco la paternita'):
#include <cmath>
#include <iostream>
#include <limits>
#include <ostream>
#include <utility>
#include <vector>
typedef long long number;
// first e' il numero primo, second e' il suo multiplo corrente
typedef std::pair<number, number> prime;
// i primi individuati
typedef std::vector<prime> prime_vector;
int main() {
    prime_vector primes;
    for ( number current = 2;
            current < std::numeric_limits<number>::max() ; ++current )
    {
// Ogni numero viene confrontato con il multiplo corrente di ciascun
primo individuato;
// se e' superiore il multiplo viene incrementato, se e' uguale si
interrompe il ciclo
        prime_vector::iterator i = primes.begin();
        for ( ; i != primes.end(); ++i )
        {
            while ( current > i->second )
                i->second += i->first;
            if ( current == i->second )
                break;
        }
// Se si e' completato un ciclo si e' individuato un nuovo primo
        if ( i == primes.end() )
        {
            std::cout << current << '\n';
            primes.push_back(prime(current, current));
        }
    }
}
Si puo' probabilmente migliorare usando un array statico, o perlomeno
una struttura dati che non si ricopi ogni volta che cresce.
Ciao,
Nicola

 Per enumerare i numeri primi a me piace questo.
Qui c'e' un altro crivello di Eratostene; e' carino perche' usa
esclusivamente la SL.
#include <iostream>
#include <ostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
using namespace std;
const vector<int>::size_type maxNum(99);
int main()
{ 
  vector<int> vi(maxNum, 1);
  const vector<int>::iterator first  = vi.begin();
  const vector<int>::iterator second = first+1;
        vector<int>::iterator last   = vi.end();
  partial_sum(first, last, first);
  for (vector<int>::iterator it = second;   it != last;   it++) {
    last = remove_if(it+1, last, not1(bind2nd(modulus<int>(), *it)));
  }
  copy(first, last, ostream_iterator<int>(cout, " "));
  cout << endl;
}
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy              ROT13: 
ybe...@cq.vasa.vg