[C++] Sprawdź czy wprowadzone liczby się powtarzają


(Hah9319) #1

Cześć :slight_smile:

Mam dosyć spory problem. Mam napisać program w którym mam wprowadzić na przykład 5 liczb a sam program ma sprawdzić czy liczby te się powtarzają i jeśli tak to jakie i podane informacje wyświetlić na ekranie. Problem polega na tym że kompletnie nie znam się na C++. Mamy w szkole przedmiot "Pracownia systemów komputerowych" gdzie nauka danego języka wygląda tak że "masz program i omów jego działanie" gdzie nie znamy podstaw...

Bardzo bym prosił o szybką pomoc.


(kostek135) #2

http://main.edu.pl/pl/user.phtml?op=sho ... pp&c=70000

Co do samego algorytmu, zależnie od zakresu danych, dla nie wielkich można zastosować sortowanie przez zliczanie, jesli i-ta waga zostanie dodana drugi raz, to ją wypisujemy.


(Martysek3) #3

http://cpp0x.pl/kursy/Kurs-C++/1

Naprawdę świetny kurs w szkole nam też dają lekcje na programowaniu z niego. Spróbuj coś napisać jak nie wyjdzie to wrzuć kod na forum ktoś pewnie ci pomoże C++ nie jest taki trudny jak dla niektórych na samym początku się wydaje.


(Hah9319) #4
#include 


using namespace std;


int main (int argc, char *argv[])

{ 

char quit; 


quit = '\0';

while (quit != 'q')

{

//POCZATEK PROGRAMU

int a, b, c, d; //zmienne

cout<<"Wprowadz 4 dowolne liczby naturalne\n"; //Program prosi o wprowadzenie 4 liczb           

cout<<"Wprowadz pierwsza liczbe:\n";  						  

cin>>a; 

cout<<"Wprowadz druga liczbe:\n"; 

cin>>b; 

cout<<"Wprowadz trzecia liczbe:\n";

cin>>c;

cout<<"Wprowadz czwarta liczbe:\n";

cin>>d;

if( a==b && b==c && c==d ) //Program sprawdza czy wszystkie liczby sie powtarzaja

cout << "Wszystkie liczby sie powtarzaja!\n"; //jesli tak wyswietla podany komunikat

else //jesli nie program przechodzi dalej i sprawdza czy trzy z podanych liczb sie powtarzaja

if( a==b && b==c || a==b && b==d || a==c && c==d || b==c && c==d )        

cout << "Trzy liczby sie powtarzaja!\n"; //jesli trzy liczby sie powtarzaja program wyswietla podany komunikat

else //jelsi nie program przechodzi dalej

if( a==b && c==d || a==c && b==d || a==d && b==c )       

cout << "Liczby w dwoch parach sie powtarzaja!\n"; //jesli tak wyswietla podany komunikat

else //jelsi nie program przechodzi dalej i sprawdza czy jakies dwie liczby sie powtarzaja

if( a==b || a==c || a==d || b==c || b==d || c==d )

cout << "Dwie liczby sie powtarzaja!\n"; //jesli tak wyswietla podany komunikat

else

cout << "Zadna wprowadzona liczba sie nie powtarza!\n"; //jelsi nie program wyswietla komunikat iz nie znalazl zadnych powtorzen

//KONIEC PROGRAMU


cout << "Wcisnij 'q' aby zakonczyc program lub dowolny inny znak aby rozpoczac od nowa:\n " << endl; //program pyta sie czy zakonczyc swoje dzialanie czy tez kontynuowa dzialanie

cin >> quit;

}


return 0;

}

Z pomocą internetu, miliona różnych tutoriali udało mi się stworzyć coś takiego. Część kodu głównie tego dotyczącego sprawdzenia powtórzenia w parach odnalazłem w sieci. Reszta to przeróbki z jakiś instruktaży itp tak aby jako tako to działało. Jednak nie mam zielonego pojęcia w jaki sposób na samym końcu wyświetlić jaka liczba się powtarza. Męczyłem to do drugiej w nocy i poległem... Tak samo nie wiem co zrobić żeby program się nie wywalał gdy wprowadzę liczby po przecinku- 4,2 2,1 itp Obecnie gdy wpiszę jakąś liczbę po przecinku w okienku robi mi się piękny matrix :slight_smile:

Jak coś to piszę w Dev C++


(Drobok) #5

Jaka jest poziom, na którym twoja klasa jest ? (co przerobiliście)


(kostek135) #6
  1. Porównanie liczb zmiennoprzecinkowych to karkołomne zajęcie z względu na dyskretny charakter operacji komputera. Porównywanie takich liczb powinno się robić w jakimś otoczeniu będącym w graniacach błędu.

  2. To co zrobiłeś może być idealnym przykładem jak NIE pisać programów. Jeśli zakres danych jest przeliczalny i skończony (np. od 0 do 1000), użyj sortowania przez zliczanie. Jeśli zakres może być np [-2^63, 2^63 - 1], użyj jakieś sortowanie w czasie nlogn (kopiec, merge sort, quick sort) następnie iterując przez posorotwaną tablicę, sprawdzaj czy sąsiedzi są tacy sami. Jeśli tak zwiększ licznik odpowiedziany za to ile powtórzeń ma zostać wyświetlonych. Alternatywnym sposobem, może być sorotwanie przez wstawianie na liscie w teorii w czasie O(n^2). Jednak jeśli zorbisz listę + skoki co ileś elementów, możesz całkiem ładnie urwać stałą. Lista jest po to, by móc łatwo wstawić element (bez konieczności rozsuwania elementów tablicy).


(system) #7

Ale, czy sortowanie jest tutaj potrzebne, gdy ma się tylko i wyłącznie 5 danych, nawet jeżeli są to duże liczby? Z względów estetycznym być może tak. Jeżeli już koniecznie uprzeć się do sortowania to wykorzystałbym wbudowaną funkcję qsort.

http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/

Lub być może :

Jak nas wikipedia informuje :

także być może właśnie te sortowanie bąbelkowe :wink:

Pozdrawiam


(kostek135) #8

Autor napisał np. 5, a w kodzie podał 4 na jakiej podstawie sądzisz, że nie ma ich wiecej? Sądze, że autor tylko podaje jakiś przykład (wniosek z niespójności założeń danych), a trzeba napisać algorytm działajacy zawsze - inaczej programowanie mija sie z celem. Poza tym quicksort z bibilioteki jest bardzo kiepski jesli chodzi o dobór pivota.


(system) #9

A widzisz sens wprowadzania 100, 15, 20 liczb? Wprowadzenie rozumiem, jako poprzez cin i dlatego uważam, że tych liczb wiele nie ma. Z drugiej strony można to zrozumieć, jako przypisanie liczb pseudo-losowych do tablicy, co miałoby większy sens, jednak tutaj to już zostało mało sprecyzowane przez autora.


(kostek135) #10

Nie. Sens zaczyna się dopiero od 10^6 do 10^9 danych. Cin nie jest wprowadzaniem, to tylko obiekt reprezentujący strumień wejściowy, testy można wygenerować raz i automatycznie przekierowywać na plik standardowego wejścia i odczytawc własnie cinem, scanfem, getcharem i czym tam jeszcze chcesz. Cel takich testów moim zdaniem jest, ale widać w pracy zawodowej nie spotkałes się z codility. Może autor narazie jest na niskim poziomie tworzenia algorytmów, a ja trochę demonizuje. Niemniej jak ludzie dawno temu wymyślili jak sortować cos w nlogn porównaniach warto by z tego korzystać (nauczyć się, bo juz nawet dla 10^6 danych różnica jest widoczna gołym okiem).

Tak czy siak to już mój ostatni post w tym temacie, bo robi się offtopic. Jeśli autor chce mogęmu podesłać moja implementacje kopca z wykorzystaniem template której można przekazać wskaźnik do funkcji porównującej wezły (notabene można porównywać dowolne obiekty jeśli jesteśmy w stanie dla nich ustalić relację). Jedyne co samemu trzeba napisać, to zapętlenie operacji sciągania wierzchołka, aby wyciągnąc jego zawartość w sposób posortowany.


(system) #11

Chciałem zwrócić uwagę na pewien kolokwializm o, który być może otarł się autor, dlatego panują różne teorie a ja próbowałem to zrozumieć. Do jakiejkolwiek pracy mi jeszcze trochę brakuję :wink: jednak na pewno sprawdzę, co kryje się pod słowem codility.

Pozdrawiam


(Drobok) #12

Ogólnie sam fakt użycia jakiegoś optymalnego algorytmu softowania mija się z celem w wypadku pobierania liczb z klawiatury. User i tak będzie podawał liczby dłużej (i to o dużo) niż będzie się sortowało. Pewnie dostał jakieś zadanie, nie chce się przyznać do tego (bo top >> kosz). A my rozwodzimy się nad rozwiązaniami / jego sensem :slight_smile:


(Hah9319) #13

@drobok 3 technikum, przedmiot "Pracownia Systemów Komputerowych" mam pierwszy rok gdzie po trochu obijamy się o wszystko z zakresu programowania, systemów itp (a wiadomo- jak coś jest do wszystkiego to jest do niczego :wink: )

@kostek135 tak, w pierwszym poście podałem 5 liczb, w programie są 4 ale tak na prawdę jest to obojętne. Po prostu program miał sprawdzić czy kilka wprowadzonych liczb się powtarza i tyle. Zresztą przegięciem by było wprowadzanie 200 liczb z klawiatury. Komu by się chciało? :stuck_out_tongue: Program miał dodatkowo wyświetlić jaka liczba się powtarza jednak jak napisałem wcześniej nie udało mi się tego dokonać.

Tak jak napisał @drobok dostałem zadanie które miałem wykonać. Przy mojej -powiedzmy sobie szczerze- zerowej wiedzy z zakresu programowania zwróciłem się tutaj z prośbą o pomoc co i jak. W między czasie w oparciu o różne tutoriale coś tam napisałem i dostałem dzisiaj za to 3+. Waszym zdaniem program jest do bani i pewnie macie rację jednak to mój pierwszy w życiu "programik" w C++. Trochę wyrozumiałości :slight_smile:

Myślę że temat można zamknąć :slight_smile: Zadanie zaliczone i tyle. Póki co nie planuję nauki C++. Skłaniał bym się bardziej ku visual basicowi ale na to będzie czas :slight_smile:


(adao1003) #14

z krusów c++ polecam to


(kostek135) #15

Miałem nie pisać, ale napisze, bo krew zalewa. Nikt wam nie każe wprowadzać 200 czy 10^6 liczb z klawiatury. Może prosty przykładzik. Poniższy kod jak łatwo ogarnąć dla n-tej linii wypisze sumę liczb z linii od 1 do n

#include 


int main() {

	int input, total = 0;


	while(scanf("%d", &input) != EOF)

		printf("%d\n", total += input);


	return 0;

}

Następnie stwórzmy plik "in" z zawartością

1 5 6 81 92 23 23 12 123 54 23 12 98 231

Teraz (używam zdalnie do kompilacji debiana z g++ 4.3.2) wykonajmy:

g++ main.cpp -o prog

./prog < in

Przekierowaliśmy strumień pliku (jego zawartość na plik wejścia standardowego do programu). scanf, cin, inne funkcje czytajace z stdin, to odebrały i przetworzyły. Teraz wyobraźmy sobie, że jakiś program wygenerował 1000 plików w każdym po 10^9 liczb. Jeśli chcemy je posortować piszemy prosty skrypt w np. bashu i wszystko wykonuje sie bez klepania testów.

Ważne, żeby nieutożsamiać czytania z stdin jako czytania z klawiatury, czytamy z pliku.

Do autora, przydatnośc algorytmu jest względna i jeśli WP są 4 liczby to twój program nie jest beznadziejny. Ja po prostu patrze na problemy szerzej, kwestia geekostwa :stuck_out_tongue: