Jekon Temat założony przez niniejszego użytkownika |
[C++] Program wyszukujący niepowtarzające się liczby z danego zbioru » 2016-12-29 19:58:39 Witam. Niedawno napisałem program, którego zadaniem miało być wypisanie niepowtarzających się liczb ze zbioru 10 podanych przez użytkownika. Po pomyślnym skompilowaniu, program po zatwierdzeniu ostatniej (10.) zmiennej zawiesza się - komunikat Windowsa "Program x.exe przestał działać". Nie wiem co jest tego przyczyną. Uprzejmie proszę o pomoc w zlikwidowaniu tego błędu oraz o ocenę mojego kodu źródłowego - błąd nie pozwala mi sprawdzić czy program wykonuje swoje zadanie poprawnie. Dodam, że dopiero zaczynam swoją przygodę z C++. Z góry dziękuję! :) #include <iostream> #include <windows.h>
using namespace std; int main() { system( "chcp 1250" ); system( "cls" ); int x[ 9 ] = { 0 }; bool z[ 9 ] = { 0 }; cout << "Podaj dowolne wartości: " << endl << endl; for( int i = 0; i < 10; i++ ) { cout << i + 1 << ". = "; cin >> x[ i ]; } system( "cls" ); cout << "Oto liczby które wystąpiły tylko raz: " << endl << endl; for( int i = 0; i < 9; i++ ) { for( int j = i + 1; i < 9 && z[ i ] == 0; j++ ) { if( x[ i ] == x[ j ] ) { z[ i ] = 1; z[ j ] = 1; } } if( z[ i ] == 0 ) { cout << x[ i ] << endl; } } cin.get(); cin.get(); return 0; }
|
|
carlosmay |
» 2016-12-29 20:18:09 for( int i = 0; i < 10; i++ ) { cout << i + 1 << ". = "; cin >> x[ i ]; } |
Wyjście poza zakres tablicy. |
|
Jekon Temat założony przez niniejszego użytkownika |
Tablica » 2016-12-30 14:18:20 Nie rozumiem. Jest to tablica 10-elementowa kończąca się "9". A 9 spełnia warunek "<10". Dopiero 10 kończy pętle i nie wczytuje "10." nieistniejącej tablicy. |
|
latajacaryba |
» 2016-12-30 14:26:45 for( int i = 0; i < 10; i++ ) { cout << i + 1 << ". = "; cin >> x[ i ]; }
petla powtarza sie 10 razy! dla i równego: 0 1 2 3 4 5 6 7 8 9 Co daje nam 10 powtórzeń zrób tablicę int tab[ 10 ] Edit: Nie rozumiem. Jest to tablica 10-elementowa kończąca się "9". A 9 spełnia warunek "<10". Dopiero 10 kończy pętle i nie wczytuje "10." nieistniejącej tablicy. |
Nie. w nawiasach kwadratowych [] określasz wielkość tablicy, jej rozmiar, a nie ostatni element. To znaczy, że jeśli napiszesz int tab[3] to jest to tablica int o trzech elementach - tab[0], tab[1] i tab[2] |
|
Jekon Temat założony przez niniejszego użytkownika |
Brak efektu » 2016-12-30 16:17:20 latajacaryba wielkie dzięki za wytłumaczenie! Teraz już rozumiem :P Jednak mimo poprawy, program nadal po zatwierdzeniu ostatniej zmiennej zacina się - "Program x.exe przestał działać". W czym w takim razie leży problem? Domyślam się że gdzieś w pętli, porównującej te liczby, ale gdzie konkretnie? Postanowiłem też lekko zmodyfikować kod, aby program nie musiał sprawdzać czy dana liczba się powtarza, jeżeli powtórzyła się już wcześniej - dodałem opcję warunkową, która sprawdza przed wewnętrzną pętlą czy wartość logiczna odpowiednika danej zmiennej jest prawdziwa czy też nie. #include <iostream> #include <windows.h>
using namespace std; int main() { system( "chcp 1250" ); system( "cls" ); int x[ 10 ] = { 0 }; bool z[ 10 ] = { 0 }; cout << "Podaj dowolne wartości: " << endl << endl; for( int i = 0; i < 10; i++ ) { cout << i + 1 << ". = "; cin >> x[ i ]; } system( "cls" ); cout << "Oto liczby które wystąpiły tylko raz: " << endl << endl; for( int i = 0; i < 10; i++ ) { if( z[ i ] == 0 ) { for( int j = i + 1; i < 10 && z[ i ] == 0; j++ ) { if( x[ i ] == x[ j ] ) { z[ i ] = 1; z[ j ] = 1; } } } if( z[ i ] == 0 ) { cout << x[ i ] << endl; } } cin.get(); cin.get(); return 0; }
Jednak i to nie przyniosło żadnego efektu... Może jest inny, mniej skomplikowany sposób na rozwiązanie tego problemu w C++? |
|
michal11 |
» 2016-12-30 16:36:26 Najprościej będzie skorzystać ze zbioru http://www.cplusplus.com/reference/set/set/?kw=set. Program napisany na szybko: #include <iostream> #include <algorithm> #include <set> #include <iterator>
int main() { int n; std::cin >> n; std::set < int > IntSet; std::copy_n( std::istream_iterator < int >( std::cin ), n, std::inserter( IntSet, IntSet.end() ) ); std::copy( IntSet.begin(), IntSet.end(), std::ostream_iterator < int >( std::cout, ", " ) ); return 0; }
jeżeli jeszcze nie znasz stlowych algorytmów to można tak zapisać powyższy program int n; std::cin >> n;
std::set < int > IntSet; int num; for( int i = 0; i < n; ++i ) { std::cin >> num; IntSet.insert( num ); }
for( const int & el: IntSet ) { std::cout << el << ", "; }
|
|
carlosmay |
» 2016-12-30 16:39:11 #include <iostream> #include <array> #include <algorithm>
template < class C > const bool is_single_num( const C & coll, int checked ) { return { std::count( coll.cbegin(), coll.cend(), checked ) == 1 ? true : false }; }
int main() { std::array < int, 10 > nums { 1, 2, 3, 5, 4, 4, 2, 8, 6, 1 }; for( std::size_t i { }; i < nums.size(); ++i ) { if( is_single_num( nums, nums[ i ] ) ) { std::cout << "Liczba " << nums[ i ] << " pajawia sie w tablicy tylko raz\n"; } } } |
|
latajacaryba |
» 2016-12-30 17:34:32 Na wstępie zaznaczę, że kończyłem pisanie kiedy przez prypadek kliknąłem klawisz powrotu na poprzednią stronę przy klawiszach strzałek. Co za... je tam umieścił ;-; Oraz zauwazylem dopiero teraz. Tam gdzie masz samo x lub z bez nawiasow kwadratowych - tam ma byc zmienna 'i' w nawiasach kwadratowych tylko cos dziwnie mi tekst formatuje i nie widac tego :/ czyli x czytaj jako x[.i] Ok, tu jest program bez funkcji bibliotecznych: #include <iostream> #include <windows.h>
using namespace std; int main() { system( "chcp 1250" ); system( "cls" ); int x[ 10 ] = { 0 }; bool z[ 10 ] = { 0 }; cout << "Podaj dowolne wartości: " << endl << endl; for( int i = 0; i < 10; i++ ) { cout << i + 1 << ". = "; cin >> x[ i ]; } system( "cls" ); cout << "Oto liczby ktore wystapily tylko raz: " << endl << endl; for( int i = 0; i < 10; i++ ) { for( int l = 0; l < 10; l++ ) { if( l != i && x[ i ] == x[ l ] ) { z[ i ] = true; break; } } if( z[ i ] == false ) cout << "bez powtorzenia: " << x[ i ] << endl; } cin.get(); cin.get(); return 0; }
1. pierwszy warunek if'a to i ma być nie równe l. dlaczego? spójrz, jak wykonuje się pętla: i = 0, l = 0. i = 0, l = 1 i = 0, l = 2 (...) i = 0, l = 9 i = 1, l = 0 i = 1, l = 1 Czyli zawsze w końcu l będzie równe i. Co to znaczy dla nas? Spójrz: Drugim warunkiem jest: jeśli x == x[l] Czyli jeśli liczba w elemencie x jest równa liczbie w indeksie x[l]. Chwila! ale l zawsze w końcu będzie równe i. No właśnie. Po to jest pierwszy warunek. Jeśli l jest równe i to nie, instrukcje w ifie się nie wykonają! Bo skoro i = l, to x = x[l], czyli porównujemy liczby w tym samym indeksie! To tak jakbysmy napisali x == x. Zawsze więc, prędzej czy później tak by się stało. Tak więc warunek l != i chroni nas przed takim porównaniem. przykład: użytkownik podał liczby: 1,2,3,4,5,6,7,8,9,0. If sprawdza: i = 0, l = 0 czy x == x[l]? tak, więc wykonuje ciało if'a, 1 równa się 1. A dziNa wstępie zaznaczę, że kończyłem pisanie kiedy przez prypadek kliknąłem klawisz powrotu na poprzednią stronę przy klawiszach strzałek. Co za... je tam umieścił ;-; Ok, tu jest program bez funkcji bibliotecznych:
#include <iostream> #include <windows.h>
using namespace std; int main() { system( "chcp 1250" ); system( "cls" ); int x[ 10 ] = { 0 }; bool z[ 10 ] = { 0 }; cout << "Podaj dowolne wartości: " << endl << endl; for( int i = 0; i < 10; i++ ) { cout << i + 1 << ". = "; cin >> x[ i ]; } system( "cls" ); cout << "Oto liczby ktore wystapily tylko raz: " << endl << endl; for( int i = 0; i < 10; i++ ) { for( int l = 0; l < 10; l++ ) { if( l != i && x[ i ] == x[ l ] ) { z[ i ] = true; break; } } if( z[ i ] == false ) cout << "bez powtorzenia: " << x[ i ] << endl; } cin.get(); cin.get(); return 0; }
1. pierwszy warunek if'a to i ma być nie równe l. dlaczego? spójrz, jak wykonuje się pętla: i = 0, l = 0. i = 0, l = 1 i = 0, l = 2 (...) i = 0, l = 9 i = 1, l = 0 i = 1, l = 1 Czyli zawsze w końcu l będzie równe i. Co to znaczy dla nas? Spójrz: Drugim warunkiem jest: jeśli x == x[l] Czyli jeśli liczba w elemencie x jest równa liczbie w indeksie x[l]. Chwila! ale l zawsze w końcu będzie równe i. No właśnie. Po to jest pierwszy warunek. Jeśli l jest równe i to nie, instrukcje w ifie się nie wykonają! Bo skoro i = l, to x = x[l], to tak jakbyśmy napisali x == x. przykład - użytkownik podał liczby: 1,2,3,4,5,6,7,8,9,0 program jest w pętlach, i = 0, l = 0 i teraz ma tego naszego if'a. Czy x == x[l]? No tak! 1 równa się 1 (bo liczba 1 jest pod x[0] ) Przed tym chroni nas właśnie nasz pierwszy warunek. tak działa z naszym zabezpieczniem: i = 0, l = 0, to zobaczmy, x jest równe x[l], ale jest warunek, że i nie może równać się l. W takim razie nie wykonujemy! pętla się powtarza, i teraz i = 0, l = 1, i teraz takie porównanie ma sens. porównujemy liczbę x do x[l], czyli liczbę 1 do 2.
2 i 3. Jesli warunki były prawdziwe, to z = true; Czyli odpowiadający indeksowi x indeks z przybiera wartość true. następnie przerywamy pętle dzięki break; 4. Jeśli z == false - czyli było nie ruszane przez naszego if'a, to wyswietl liczbe x.
Czegoś nie zrozumiałeś? - pisz :) |
|
« 1 » 2 3 |