Przekształć poniższy kod aby zwracał liczby (i wypisał ich czynniki ) takie, które mają trzy różne czynniki nieparzyste. np. 1157625: 3, 3, 3, 5, 5, 5, 7, 7, 7 TAK; 105: 3, 5, 7 TAK; 1287: 3, 3, 11, 13 TAK; 3465: 3, 3, 5, 7, 11 NIE

Bardzo proszę o dobre odpowiedzi, odpowiedzi tylko dla punktów będą zgłaszane.
Jest to trudne zadanie, dlatego daje każdemu, kto dobrze zrobi 30 punktów.
Z góry dziekuję.


Przekształć Poniższy Kod Aby Zwracał Liczby I Wypisał Ich Czynniki Takie Które Mają Trzy Różne Czynniki Nieparzyste Np 1157625 3 3 3 5 5 5 7 7 7 TAK 105 3 5 7 T class=

Odpowiedź :

Odpowiedź

Program, który napisałam znajdziesz w pierwszych dwóch załącznikach.

Trzeci załącznik zawiera plik tekstowy z przykładowego uruchomienia dla liczb z zakresu od 105, do 999999.

Wyjaśnienie

Niestety właściwie nie było co przekształcać z tego co wrzuciłeś. Zostawiłam z oryginału tylko oznaczenie  n  dla zmiennej będącej końcem zakresu i użycie  cin  oraz  cout.  (Jak może zauważyłeś preferuję  printf,  ale akurat w tym przypadku nawet przejrzyściej jest użyć  cout.  :)  Zwykle nie jest... )

Mam sporo komentarzy do swojego programu i dużo uwag do Twojego...

Zacznę od Twojego. Zrób sobie i tym, którzy będą czytali Twoje programy tę przyjemność, że nazwy zmiennych będą opisowe, a jednoliterowe zostawisz w miejscach, gdzie ma to sens (np. czasami pętle). Funkcja sprawdzająca powinna zwracać True / False, wtedy od razu warunek jest oczywisty, tutaj  if  w wierszu 35.

Problem, nawet gdy jest bardzo łatwy, warto (a czasem należy) rozłożyć na elementy. W przypadku tego zadania minimalny podział na moduły uznałam, że jest następujący:

  • wyznaczenie górnego zakresu obliczeń + pętla przechodząca przez cały zakres od początku (oczywiście nie od 2, tylko od 105) do końca (n czytane z konsoli);
  • sprawdzenie czy liczba ma dokładnie trzy różne czynniki i wydrukowanie czynników jeśli spełnia ten warunek;
  • funkcja pomocnicza sprawdzająca czy czynnikiem x jest y – tak, doskonale wiem, że ( x % y == 0 ) – ale moim zdaniem takie wyodrębnienie polepsza czytelność kodu, a i sprawdzenie dzielenia przez 0 nie jest przypadkowe (choć akurat w tym programie rzeczywiście bezużyteczne, możesz pominąć);
  • funkcja pomocnicza sprawdzająca, czy liczba jest pierwsza.

Podejrzewam, że nie na darmo poprzednie zadanie dotyczyło wyznaczenia tablicy liczb pierwszych! Użycie takiej tablicy istotnie przyspieszyłoby działanie tego programu. Czyli powinna być funkcja tworząca tablicę liczb pierwszych aż do  n,  a funkcja   czyLiczbaPierwsza()  tylko by sprawdzała w tej tablicy i już nic nie wyliczała.

Zapewne należałoby też wydzielić z funkcji  czynniki3()  wypisywanie wyniku. Jednak popatrzyłam na Twoje programy i zdecydowałam, że zbyt dużo modułów mogłoby Tobie dać wrażenie skomplikowanego programu. I tak płynnie przeszłam do komentowania swojego programu. :)

Pisanie zaczęłam od zdecydowania w jakiej strukturze będę przechowywała informację o tym, które trzy czynniki oraz ile razy każdy z nich. Można by użyć tablicy 3x2. Ale byłoby to dosyć skomplikowane ponieważ nie tylko trzeba by sprawdzać czy coś zostało już zapisane, ale i też nieźle nagimnastykować się z tym gdzie co zapisać. A jest to po prostu typowe zadanie dla tablicy asocjacyjnej, mapy (C++), słownika (w wielu innych językach programowania). Dalej już było łatwo.

Na samym początku sprawdzam czy badana liczba nie jest przypadkiem liczbą pierwszą. Sprawdzenie tego właśnie na samym początku uprościło mi logikę dalszego kodu.

O... właśnie zauważyłam błąd... Pętla powinna sprawdzać od 3, co 2, a nie co 1 – ale to już sobie sam poprawisz.

Tak więc  czynniki3()  zawiera pętlę, która po kolei sprawdza liczby pierwsze mniejsze od połowy szukanej liczby czy są czynnikami. Jeśli któraś liczba pierwsza jest czynnikiem, to w pętli sprawdzane jest ile razy. W tym momencie nie jest sprawdzane czy liczba miała tylko jeden czynnik, czy dwa, a może trzy. Ale przy (tzn. po) dodaniu kolejnego czynnika jest sprawdzane czy przypadkiem nie jest to już czwarty czynnik. Jeżeli jest, to wtedy zakres pętli jest zmieniany na  0  i pętla już dalej nie będzie wykonywana. (Tak, można zmieniać parametry pętli.)

Natomiast drukowane będą czynniki tylko wtedy gdy są dokładnie trzy czynniki.

Ponieważ zadanie wymaga oddzielenia czynników przecinkami i spacjami, bezpośrednio po każdym czynniku dodaję przecinek i spację. Miałabym więc po ostatnim czynniku zbędne przecinek i spację... Zamieniam je na znak nowej linii. Właśnie tak. Na pewno nie należy użyć  endl.

Nie wiem jak szybki masz komputer, ale nie próbowałabym początkowo zakresu szerszego niż od 105, do około 50000 (50 tysięcy).

Zobacz obrazek 0AB
Zobacz obrazek 0AB
Zobacz obrazek 0AB