Zliczanie liczb pierwszych na funkcjach

0

Przygotowując się do matury, chciałem zrobić jedno zadanie.
Najpierw w main() pobierałem dane do tablicy, potem wywoływał wartosc(). Program się wykonuje, jednakże nie liczy wszystkiego dobrze. Coś tam liczy.
Wydaje mi się, że źle liczy wartość ASCII. napisy są wektorem globalnym.

int wartosc()
{
   int ilosc = 0;
   int suma;
    for(int i=0; i<napisy.size(); i++)
    {
             suma = 0;
             for(int j=0; j<napisy[i].size(); j++) suma+=napisy[i][j];
    
             ilosc+= czyPierwsza(suma);
    }
    return ilosc;
}
bool czyPierwsza(int a)
{
     if(a<2) return false;
     else if(a>2)
     {
          for(int i=3; i<=sqrt(a); i++)
          {
                  if(a%i==0) return false;
          }
          
     }
     return true;
     if(a==2) return true;
}
2

Co ten program ma liczyć?

Bezsensownie nazywasz funkcje. Czym jest wartosc? Nic to czytającemu kod nie mówi, pomijając już polskie nazewnictwo.

Nie używaj zmiennych globalnych bez powodu, zawsze staraj się nadawać minimalny możliwy zakres.

Pokaż resztę kodu.

3
napisy[i][j]

zwraca jeden znak o typie char. Przykładowo w tablicy ASCII

znak '0' ma wartość 48
znak '1' ma wartość 49

więc zamiast dodawać 0 i 1 do suma to dodajesz 48 i 49.

0
 
#include <cstdlib>
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <math.h>

using namespace std;


vector<string> napisy;

int ilosc();
bool czyPierwsza(int a);



int main()
{
    fstream plik;
    string linia;
    plik.open("Napis.txt", ios::in);
    if(!plik.good()) cout<<"Plik nie jest otwarty"<<endl;

    while(getline(plik,linia))
    {
                             napisy.push_back(linia);     
    }
    cout<<ilosc()<<endl;
    plik.close();
    system("PAUSE");
    return EXIT_SUCCESS;
}

int ilosc()
{
   int ilosc = 0;
   int suma;
    for(int i=0; i<napisy.size(); i++)
    {
             suma = 0;
             for(int j=0; j<napisy[i].size(); j++) suma+=napisy[i][j];
             cout<<suma<<endl;
             ilosc+= czyPierwsza(suma);
    }
    return ilosc;
}


bool czyPierwsza(int a)
{
     if(a<2) return false;
     else if(a>2)
     {
          for(int i=3; i<=sqrt(a); i++)
          {
                  if(a%i==0) return false;
          }
          
     }
     return true;
     if(a==2) return true;
}

Właśnie chodzi o to, aby dodawać wartości z tablicy ASCII, ale po tym co napisałeś, myślę, że jest gdzieś błąd w funkcji sprawdzającej czy liczba jest liczbą pierwszą.

3
  1. Zapoznaj się z inkrementcają bo nie wiesz co czynisz: http://4programmers.net/Forum/1101404
  2. W funkcji czyPierwsza może zacznij pętle od 2 zamiast tak cudować.
  3. W funkcji czyPierwsza oblicz pierwiastek z a tylko raz, przed pętlą, teraz robisz to na każdym kroku, owszem istnieją mądre kompilatory z optymalizacją ... ale na to samo wychodzi co punkt pierwszy

Może powiedz jak brzmi zadanie, bo z tego co widzę to sprawdzasz czy suma kodów ASCII w wierszu jest liczbą pierwszą.

0

Tak, chodzi o to, aby sprawdzić w ilu wyrazach suma ASCII jest liczbą pierwszą.

Kiedy można użyć ++i zamiast i++?

1
#include <iostream>
#include <fstream>
using namespace std;
 
bool isPrime(unsigned value) // to twoje kombinowanie z if'ami było po to aby nie sprawdzać liczb parzystych, tu również podzielne przez 3 - nie sprawdzamy
  {
   if((!(value%2))||(!(value%3))) return true;
   if(value<5) return false;
   unsigned add=2;
   for(i=5;i*i<=value;i+=add,add=6-add) if(!(value%i)) return true;
   return false;
  }
 
int main()
  {
   ifstream fin("Napis.txt");
   if(!plik) cerr<<"Plik nie jest otwarty"<<endl;
   else
     {
      unsigned count=0;
      while(unsigned sum=0;fin;)
        {
         int ch=fin.get();
         if((ch=='\n')||(ch==EOF))
           {
            count+=isPrime(sum);
            sum=0;
           }
         else sum+=(unsigned)ch;
        }
     }
   return 0; // Jeżeli potrzebujesz system("PAUSE"); - to lepiej wymień IDE na jakieś z aktualnego tysiąclecia
  }
0

Jak widać po moim kodzie, używam straasznie starego c++. Mogę mieć parę pytań?
1.(!(value%2)) - co oznacza %2? Znaczy się wiem mniej więcej o co chodzi. Jeżeli reszta z dzielenia jest różna od 0, to zwróci True tak?
2.for(i=5;ii<=value;i+=add,add=6-add) - Nie bardzo tego rozumiem. Wiem czemu i=5, wiem czemu ii, ale reszty nie.
3. Czy zawsze można użyć ++i?
4. Co to jest fin.get() i EOF?
5. Wydaje mi się, że ten program liczy ile znaków w wyrazie jest liczbami pierwszymi, czy sprawdza czy suma znaków w wyrazie jest liczbą pierwszą?
Z góry dziękuję za odpowiedź

1

Ad 1. Każdą liczba może być potraktowana jako wartość logiczna na zasadzie 0 --> false; reszta --> true
Ad 2. Możesz mieć kilka instrukcji początkowych oddzielonych przecinkiem jak również kilka instrukcji krokowych, również oddzielonych przecinkiem. Po każdym kroku raz dodaje się 2, następnym razem 4, potem znowu 2 itd
Ad 3. Tak, zawsze, ale nie zawsze to ma sens, z tym że przeważnie - ma. W zwykłym: for(i=0;i<n;++i) - zawsze ma sens
Ad 4. http://www.cplusplus.com/reference/istream/istream/get/
Ad 5. Każda wartość logiczna może być potraktowana jako liczba na zasadzie false --> 0; true --> 1; count+=false; nie zmieni count, count+=true; doda jedynkę - w ten sposób eliminujemy if'a

Te pytania nie są z powodu starego C++, wszystko to istniało jeszcze od najstarszego C.

1 użytkowników online, w tym zalogowanych: 0, gości: 1