Liczba ciekawa

0

Witam mam problem z zadaniem z main (http://main.edu.pl/pl/user.phtml?op=showtask&task=cie&con=ALG). Właściwie to nie z zadaniem, bo ustalilem mniej wiecej algorytm, ale z kodem. Zwykle pracuje na fedorze, ale teraz nie mam dostepu, a windows ciagle wypluwa nieistniejace bledy, albo dzialajacy program sie zawiesza. Pozostaje kompilator internetowy. Tym razem program nie jest dzialajacy, ideone mowi o SIGFPE - czyli teoretycznie bledne dzialania arytmetyczne. Oto pierwotna wersja mojego kodu (pozniej chce zapisac wszelkie liczby ciekawe do tablicy we wlasciwym programie - preprocessing - na razie jednak mam taki malo wydajny program aby sprawdzic czy poprawnie sprawdzam czy liczba jest ciekawa).

#include <iostream>
using namespace std;
int ciekawa(int x, int n);
//sprawdza czy liczba jest ciekawa
int dlugosc(int x);
//liczy dlugosc liczby
bool pierwsza(int x);
//sprawdza czy liczba jest pierwsza przez sito Eratostenesa
int main()
{
    int x, y;
    cin >> x;
    y = dlugosc(x);
    cout << y;
    return 0;
}

int dlugosc (int x)
{
    int cyfr(0), y = x;
    while (y > 0)
    {   
        y /= 10; //skraca liczbe o jedna cyfre
        ++cyfr;
    }
    return (ciekawa(x, cyfr));
}

bool pierwsza(int x)
{
    int *liczby, *skreslona, n = x + 1;
    liczby = new int [n];
    skreslona = new int [n];
    for (int i = 2; i < n; ++i)
        liczby[i] = i;

    for (int i = 2; i < n; ++i)
        skreslona[i] = 0;

    for (int i = 2; i * i <= n; ++i)
    {
        if (!skreslona[i])
        {
            for (int j = 2 * i; j < n; j += i)
            {
                skreslona[j] = 1;
                cout << skreslona[j];
            }
        }
    }
    if (!skreslona[x])
        return true;
    else
        return false;
}

int ciekawa(int x, int n)
{
    int dziel(0), pierw(0), suma_pierwszych(0);
    for (int i = 0; i * i <= n; ++i) //i do pierwiastka z n -
    {//- po pierwiastku wystepuja juz tylko dzielniki bedace ilorazem x z dotychczasowymi i
        if(!(x % i))    //jesli x|i 
        {
            if(pierwsza(i)) //jesli dzielnik jest liczba pierwsza
            {
                ++pierw;
                suma_pierwszych += i;   //aktualizuje sume liczb pierwszych
                ++dziel;    //znajdywane sa dwa nowe dzielniki - i (liczba pierwsza) i wynik = x / i
                cout << pierw << " " << suma_pierwszych << " " << dziel << endl;
            }
            else
            {
                 dziel += 2;    //jak wyzej - x / i = liczba za pierwiastkiem - trzeba ja uwzglednic
                 cout << dziel << endl;
            }
        }
    }

    int suma = pierw + dziel;
    if(suma % 13 == 0 && suma / 13 == suma_pierwszych)
        return x;
    else if(x < 100000000)
        return (dlugosc(x+1));
    else
        return -1;
}

Duzo nad tym siedzialem szukajac bledow i nic znaczacego raczej nie znalazlem (choc jeden blad logiczny wykrylem, ale mniejsza z tym). ideone mowi o powyzszym bledzie wykonania.
PS wszelkie cout-y poza funkcja main sa tylko po to, by sledzic zmienne. niestety program nie dochodzi nawet do tego.

1

Kiedy odpalam Twój kod pod Visual Studio, debbuger zatrzymuje się na tej linijce w funkcji ciekawa (zaraz na początku w pętli)

if(!(x % i))    //jesli x|i  

z błedem "Integer division by zero". Jak spojrzysz parę linijek wyżej, to zaczynasz pętle, od i == 0, czyli szukasz wtedy w if reszty z dzielenia przez 0, i stąd pewnie błąd działania arytmetycznego.

0

dzieki ten blad rzeczywiscie lezal tutaj.
naprawilem to ale nadal jest blad, tym raczej cos z pamiecia - SIGSEGV. moze program zajmuje za duzo pamieci? zlozonosc pamieciowa rzeczywiscie ma duza, ideone moze tego nie przyjmowac...
funkcja ciekawa wyglada teraz tak:

int ciekawa(int x, int n)
{
    int dziel(2), pierw(0), suma_pierwszych(0);
    for (int i = 2; i * i <= n; ++i) //i do pierwiastka z n -
    {//- po pierwiastku wystepuja juz tylko dzielniki bedace ilorazem x z dotychczasowymi i
        if(!(x % i))    //jesli x|i
        {
            if(pierwsza(i)) //jesli dzielnik jest liczba pierwsza
            {
                ++pierw;
                suma_pierwszych += i;   //aktualizuje sume liczb pierwszych
                ++dziel;    //znajdywane sa dwa nowe dzielniki - i (liczba pierwsza) i wynik = x / i
            }
            else
            {
                 dziel += 2;    //jak wyzej - x / i = liczba za pierwiastkiem - trzeba ja uwzglednic
            }
        }
    }

    int suma = pierw + dziel;
    if(suma % 13 == 0 && suma / 13 == suma_pierwszych)
        return x;
    else if(x < 100000000)
        return (dlugosc(x+1));
    else
        return -1;
} 

reszta nie zmieniona. podejrzewam ze tak jak wczesniej, gdzies jest drobny glupi blad. widzicie tu cos?

0

znaczy wydaje mi się, że to może być problem, ale nie mam teraz możliwości przetestowania. Po prostu wywołujesz funkcje "pierwsza" dość wiele razy, a w niej za każdym razem alokujesz pamięć i nigdy jej nie zwalniasz. Kiedy opaliłem teraz Twój kod (z poprawioną funkcją "ciekawa"), to wywala Stack overflow, więc to prawdopodobnie jest problem

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