K1cek Temat założony przez niniejszego użytkownika |
Jak zwrócić tablicę struktur / C++ ? » 2019-04-30 12:56:18 Witam, piszę program na zajęcia z C++, chciałbym aby funkcja usunPunkty zwróciła mi tablicę struktur ale nie do końca wiem jak się za to zabrać, proszę o pomoc. #include <iostream> #include <string> #include <conio.h> #include <ctime> #include <cstdlib>
using namespace std;
struct PUNKTY { int x; int y; };
PUNKTY usunPowt( PUNKTY Plaszczyzna[] ) { int elem = 1000; int tablica1[ elem ]; int tablica2[ elem ]; for( int i = 0; i < elem; i++ ) { tablica1[ i ] = Plaszczyzna[ i ].x; tablica2[ i ] = Plaszczyzna[ i ].y; } int licznik = 0; for( int i = 0; i < elem; i++ ) { for( int j = i + 1; j < elem; j++ ) { if( tablica1[ i ] == tablica1[ j ] ) { if( tablica2[ i ] == tablica2[ j ] ) { tablica1[ i ] = - 1; tablica2[ i ] = - 1; licznik++; } } } } cout << "Liczba punktów, które się powtórzyły: " << licznik << endl; PUNKTY PlaszczyznaBezPowt[ elem - licznik ]; int licznik2 = 0; for( int x = 0; x <( elem ); x++ ) { if( tablica1[ x ] > - 1 ) { PlaszczyznaBezPowt[ licznik2 ].x = tablica1[ x ]; PlaszczyznaBezPowt[ licznik2 ].y = tablica2[ x ]; licznik2++; } else { } return PlaszczyznaBezPowt[ licznik2 ]; } } int main() { system( "chcp 1250" ); PUNKTY Plaszczyzna[ 1000 ]; srand( time( NULL ) ); for( int i = 0; i < 1000; i++ ) { Plaszczyzna[ i ].x =( rand() % 800 ) + 1; Plaszczyzna[ i ].y =( rand() % 600 ) + 1; } usunPowt( Plaszczyzna ); return 0; } |
|
pekfos |
» 2019-04-30 14:01:21 Nie da się zwrócić tablicy per se. Możesz: Twoja funkcja być może powinna wyglądać tak: int usunPowt( PUNKTY Plaszczyzna[], int rozmiar )
Powinieneś mieć przekazany rozmiar, zamiast go zgadywać w środku, a wynik możesz zapisać bezpośrednio do tablicy źródłowej. Jeśli możesz używać standardowych algorytmów, to std::sort(), potem std::unique() zrobią to, czego potrzebujesz. A jeśli nie, ale możesz używać standardowych kontenerów, to std::set<> jest wydajnym sposobem na testowanie, czy elementy się powtarzają. Oba podejścia dadzą czas O(n log n), twój aktualny algorytm ma O(n 2) - dla 1000 elementów to tak poglądowo 100 razy wolniej. |
|
K1cek Temat założony przez niniejszego użytkownika |
» 2019-04-30 15:15:40 Czy ktoś mógłby mnie naprowadzić w jaki sposób utworzyć dynamiczną tablicę struktur i pokazać jak przekazać ją do funkcji usunPowt abym mógł ją wypełnić nowymi danymi ? |
|
pekfos |
» 2019-04-30 17:47:11 Podałem 3 różne rozwiązania, nie listę kroków. |
|
nanoant20 |
» 2019-04-30 19:24:58 Czy ktoś mógłby mnie naprowadzić w jaki sposób utworzyć dynamiczną tablicę struktur i pokazać jak przekazać ją do funkcji ... |
//edit teraz moze bardziej czytelnie #include <iostream> #include <vector> #include <ctime>
using namespace std;
struct PUNKTY { int x; int y; };
void addpoint( vector < PUNKTY > & tablica ) { PUNKTY p = { 200, 300 }; PUNKTY r = { 10, 20 }; PUNKTY s = { 100, 200 }; tablica.push_back( p ); tablica.push_back( r ); tablica.push_back( s ); }
int main() { vector < PUNKTY > tablica; srand( static_cast < unsigned int >( time( NULL ) ) ); for( int i = 0; i < 10; i++ ) { int a =( rand() % 80 ) + 1; int b =( rand() % 60 ) + 1; PUNKTY p = { a, b }; tablica.push_back( p ); } std::cout << std::endl; for( auto el: tablica ) std::cout << el.x << ' ' << el.y << std::endl; std::cout << '\n'; addpoint( tablica ); for( auto el: tablica ) std::cout << el.x << ' ' << el.y << std::endl; std::cout << '\n'; std::cout << std::endl; for( int i = 0; i < tablica.size(); i++ ) { std::cout << tablica[ i ].x << " " << tablica[ i ].y << std::endl; } std::cout << std::endl; std::cin.get(); std::cin.get(); return 0; }
|
|
nanoant20 |
» 2019-05-01 21:25:31 dlaczego nie ma progress'u? #include <iostream> #include <vector> #include <ctime> #include <algorithm>
using namespace std;
struct PUNKTY { int x; int y; }; void addpoint( std::vector < PUNKTY > & tablica );
void addpoint( std::vector < PUNKTY > & tablica ) { PUNKTY p = { 21, 777 }; PUNKTY r = { 100, 200 }; PUNKTY s = { 21, 777 }; tablica.push_back( p ); tablica.push_back( r ); tablica.push_back( s ); }
bool comp( const PUNKTY & a, const PUNKTY & b ) { return(( a.x < b.x ) ||( a.y < b.y ) ); }
int main() { vector < PUNKTY > tablica; srand( static_cast < unsigned int >( time( NULL ) ) ); for( int i = 0; i < 1; i++ ) { PUNKTY a = { 20, 30 }; PUNKTY b = { 10, 20 }; PUNKTY c = { 100, 200 }; tablica.push_back( a ); tablica.push_back( b ); tablica.push_back( c ); } std::cout << "vector < PUNKTY > tablica; orginal" << std::endl; for( auto el: tablica ) std::cout << el.x << ' ' << el.y << std::endl; std::cout << '\n'; addpoint( tablica ); std::cout << "Po dodaniu" << std::endl; for( auto el: tablica ) std::cout << el.x << ' ' << el.y << std::endl; std::cout << '\n'; sort( tablica.begin(), tablica.end(), & comp ); std::cout << "po sortowaniu" << std::endl; for( int i = 0; i < tablica.size(); i++ ) { std::cout << tablica[ i ].x << " " << tablica[ i ].y << std::endl; } std::cout << std::endl; std::cout << "rm - remove duplicates" << std::endl; auto compare =[]( const PUNKTY & a, const PUNKTY & b ) { return(( a.x == b.x ) &&( a.y == b.y ) ); }; auto predykat =[]( const PUNKTY & a, const PUNKTY & b ) { return(( a.x < b.x ) &&( a.y < b.y ) ); }; std::sort( tablica.begin(), tablica.end(), predykat ); auto last = std::unique( tablica.begin(), tablica.end(), compare ); tablica.erase( last, tablica.end() ); for( int i = 0; i < tablica.size(); i++ ) { std::cout << tablica[ i ].x << " " << tablica[ i ].y << std::endl; } std::cout << std::endl; std::cin.get(); std::cin.get(); return 0; }
- uważam że program jest w miarę czytelny - nalezy doszlifować i wgryźć się w temat, - można wzbogacić funkcjonalność programu - jeżeli są jakieś UWAGI to wprowadzić korektę |
|
pekfos |
» 2019-05-01 22:05:13 uważam że program jest w miarę czytelny nalezy doszlifować i wgryźć się w temat, |
Kod nie jest zbyt czytelny, przez te "compare" i "predykat", nazwy są użyte więcej niż raz do nazwania różnych rzeczy i nawet nie w spójny sposób. I co ważniejsze - kod jest błędny, również z powodu predykatów. Polecam wgryźć się w wielką czerwoną ramkę na końcu Wprowadzenie do standardowych algorytmów, jak również w przykładowy kod, w którym jest zaprezentowane, jak poprawnie sortować elementy po więcej niż jednej wartości. return(( a.x < b.x ) &&( a.y < b.y ) );
|
Taki predykat stawia a przed b wtedy, gdy obie wartości w a są mniejsze od tych w b. A jeśli jedna z tych wartości będzie równa, to dla sortowania a i b będą nieodróżnialne i posortowana sekwencja nie będzie poprawna dla std::unique(), a przynajmniej nie dla predykatu, jaki tam podałeś. Relacja równości dla std::unique() powinna być prawdziwa tylko i dla każdej pary elementów nierozróżnialnych przy sortowaniu, inaczej nie zawsze usuniesz duplikaty. |
|
nanoant20 |
» 2019-05-01 23:26:04 nazwy są użyte więcej niż raz |
poprawiłem Taki predykat stawia a przed b wtedy, gdy obie wartości w a są mniejsze od tych w b. A jeśli jedna z tych wartości będzie równa, to dla sortowania a i b będą nieodróżnialne i posortowana sekwencja nie będzie poprawna dla std::unique(), |
zrozumiałem faktycznie jeżeli PUNKTY b = { 100, 20 }; nie zostanie posortowane, muszę przemyśleć auto predykat =[]( const PUNKTY & a, const PUNKTY & b ) { return(( a.x < b.x ) ||( a.y < b.y ) ); }; @pekfos tak zauważyłem |
|
« 1 » 2 |