Yumox Temat założony przez niniejszego użytkownika |
Kombinacje bez powtórzeń » 2020-07-05 20:49:14 Czytając temat w kursie o zagnieżdżonych pętlach chciałem napisać program, który wypisuje wszystkie możliwe kombinacje liczb bez powtórzeń i żeby dla (przykładowego) zbioru {0,1,2,3} program wypisywał kombinacje: {0,1,2,3} ale też {3,2,1,0}, czyli chce aby liczby się nie powtarzały, ale żeby kolejność miała znaczenie. Wyszedł mi taki program: #include <iostream> int main() { for( int i = 0; i < 4; i++ ) { for( int j = 0; j < 4; j++ ) { if( i == j ) continue; for( int k = 0; k < 4; k++ ) { if( i == j || i == k || j == k ) continue; for( int l = 0; l < 4; l++ ) { if( i == j || i == k || j == k || i == l || j == l || k == l ) continue; std::cout << i << " " << j << " " << k << " " << l << std::endl; } } } } return 0; }
Ale zdaje sobie sprawe, że przy dodaniu jeszcze kilku liczb do tego zbioru, musiałbym dopisywać kolejne porównania w if'ie, a to trochę bezsensowne. Stąd moje pytanie, jak to zrobić łatwiej/krócej? |
|
pekfos |
» 2020-07-05 21:20:47 Rozważałeś użycie tablicy zamiast nazwanych zmiennych? |
|
Yumox Temat założony przez niniejszego użytkownika |
» 2020-07-06 22:32:07 Użyłem tablicy zamiast nazwanych zmiennych i stworzyłem funkcje, przez co program jest uniwersalny: #include <iostream> bool czyPowtorzono( int tab[], int i ) { for( int j = 0; j < i; j++ ) { if( tab[ j ] == tab[ i ] ) return true; } return false; } int main() { int tablica[ 4 ] = { 12, 4, 66, 8 }; int tab[ 4 ]; for( tab[ 0 ] = 0; tab[ 0 ] < 4; tab[ 0 ] ++ ) { for( tab[ 1 ] = 0; tab[ 1 ] < 4; tab[ 1 ] ++ ) { if( czyPowtorzono( tab, 1 ) ) continue; for( tab[ 2 ] = 0; tab[ 2 ] < 4; tab[ 2 ] ++ ) { if( czyPowtorzono( tab, 2 ) ) continue; for( tab[ 3 ] = 0; tab[ 3 ] < 4; tab[ 3 ] ++ ) { if( czyPowtorzono( tab, 3 ) ) continue; std::cout << tablica[ tab[ 0 ] ] << " " << tablica[ tab[ 1 ] ] << " " << tablica[ tab[ 2 ] ] << " " << tablica[ tab[ 3 ] ] << std::endl; } } } } return 0; }
|
|
pekfos |
» 2020-07-06 23:07:41 Jak chcesz to bardziej skrócić, to sama długość ciągu też może być określana parametrem. Zmienną ilość zagnieżdżeń można uzyskać funkcją rekurencyjną. |
|
Yumox Temat założony przez niniejszego użytkownika |
» 2020-07-07 19:43:41 Zrobiłem funkcje rekurencyjną i dodałem możliwość podawania ciągu przez użytkownika dzięki alokacji pamięci, działa dobrze tylko zastanawia mnie czy nie dałoby się zmniejszyć ilości argumentów? #include <iostream> bool czyPowtorzono( int tab[], int i ) { for( int j = 0; j < i; j++ ) { if( tab[ j ] == tab[ i ] ) return true; } return false; } void wypisz( int tablica[], int tab[], int i, int j ) { if( j == i ) { for( int k = 0; k < i; k++ ) { std::cout << tablica[ tab[ k ] ] << " "; } std::cout << std::endl; return; } for( tab[ j ] = 0; tab[ j ] < i; tab[ j ] ++ ) { if( czyPowtorzono( tab, j ) ) continue; wypisz( tablica, tab, i, j + 1 ); } } int main() { std::cout << "Wpisz liczby ktorych kombinacje chcesz otrzymac, litera konczy wczytywanie:" << std::endl; int i = 0, liczba; int * wskaznik = nullptr; while( std::cin >> liczba ) { i++; int * wsk = new int[ i ]; for( int j = 0; j < i - 1; j++ ) { wsk[ j ] = wskaznik[ j ]; } wsk[ i - 1 ] = liczba; delete[] wskaznik; wskaznik = wsk; } int * tab = new int[ i ]; wypisz( wskaznik, tab, i, 0 ); delete[] tab; return 0; }
|
|
pekfos |
» 2020-07-07 19:57:28 Z ilością argumentów się tu nic sensownego nie zrobi. Możesz najwyżej ukryć ostatni z użyciem dodatkowej funkcji, bo to szczegół implementacyjny. void wypisz( int tablica[], int tab[], int i ) { wypisz_impl( tablica, tab, i, 0 ); } |
|
Yumox Temat założony przez niniejszego użytkownika |
» 2020-07-07 21:58:12 Ok, dzięki :) |
|
« 1 » |