Skocz do zawartości

Temat został przeniesiony do archiwum

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

tomeq35

C++ problem z programem

Rekomendowane odpowiedzi

Witam, mam problem z moim programem co prawda znalazłem podobny problem na forum lecz nie był on rozwiązany do końca. Mój program nie działa poprawnie, proszę o pomoc i ewentualne wskazówki jak można go inaczej (lepiej) napisać.

 

Zadanie:

 

Program wczytuje dane z klawiatury do tablicy typu double, a następnie sprawdza:

 

1. czy te liczby są uporządkowane rosnąco lub malejąco,

2. czy elementy tablicy mają symetryczną zawartość (tj. pierwszy element równy ostatniemu, drugi przedostatniemu, itd.)

3. czy w tablicy występuje chociaż jedno powtórzenie wartości

 

#include <iostream>

   using namespace std; 

   int main() 
{ 
   const int rozmiar = 5; 
   double tablica [rozmiar];

   cout<<"Podaj dane do tablicy: "<<endl; 
   for(int i=0; i<rozmiar; i++) 
   { 
       cin>>tablica[i]; 
   } 
   cout<<endl; 
   for (int i =0;i<rozmiar;i++) 
   cout<<tablica[i]<<endl;

   for(int i=0; i<rozmiar; i++) 
       if(tablica[i]<tablica[i+1]) 
       { 
           cout<<"Uporzadkowane rosnaco"<<endl; 
       } 
       else if(tablica[i]>tablica[i+1]) 
           cout<<"Uporzadkowane malejaco"<<endl;

   for(int i=0; i<rozmiar; i++) 
   { 
       if(tablica[i]==tablica[rozmiar-1-i]) 
           cout<<"Jest symetryczna";

       else 
           cout<<"Jest niesymetryczna"; 
   }

// jak zrealizować sprawdzanie czy się powtórzyły ???

   return 0; 
}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Co do powtórzeń, to masz dwa sposoby:

1. bierzesz liczbę na pozycji i, a następnie sprawdzasz w pozostałej części tablicy czy element j-ty jest taki sam

jeśli tak, to dubel = true i break

2. jedziesz po całej tablicy i robisz sobie dodatkową listę na liczbę powtórzeń, po wypełnieniu listy sprawdzasz czy jest coś większe od 1

 

 

Co do uporządkowania tablicy, pokazujesz zmiany pomiędzy kolejnymi elementami, więc jak tablica ma losowy rozkład, to nic dziwnego, że raz pokazuje tak, a raz tak. Ustaw sobie x jako 1(rosnąco)/-1(malejąco) na podstawie wartości pierwszego i drugiego elementu, a następnie jedź od drugiego elementu w górę. Jeśli tablica nagle zacznie maleć/rosnąć, to robisz break i informujesz, że jest losowa. Jak dojedziesz do końca, to na podstawie x powiesz jakiego jest typu.

 

Z symetryką podobnie, tylko zliczasz liczbę elementów identycznych. Jeśli będzie połowa rozmiaru tablicy, to masz symetryczną.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ja tu widzę na dzień dobry wychodzenie poza zakres tablicy.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Witam, po całym dniu walki udało mi się coś stworzyć, jednak brakuje mi jeszcze funkcji sprawdzającej czy w tablicy są elementy powtarzające się, tutaj jednak utknąłem na dobre. Proszę o pomoc.

#include <iostream>

using namespace std;

const int r=5;
int tab[r];

bool rosnie(int *tab)
{
   for(int i=0;i<r-1;i++)
   {
       if(!(tab[i]<tab[i+1]))
       return false;
   }
   return true;
}

bool maleje(int *tab)
{
   for(int i=0;i<r-1;i++)
   {
       if(!(tab[i]>tab[i+1]))
       return false;
   }
   return true;
}

bool sym(int *tab)
{
   for(int i=0; i < r/2; i++)                         //czy tutaj moze byc i < r czy i < r/2 ???
   {
               if (!(tab[i]==tab[r-1-i]))
                   return false;
   }
   return true;

}
bool powt(int *tab)
{
 // ??????? Pomocy!!
   }

}
int main()
{
   cout << "Hello world!" << endl;
cout<<"podaj elementy: "<<endl;

   for(int i=0;i<r;i++)
       cin>>tab[i];
       cout<<endl;

   for(int i=0;i<r;i++)
       cout<<tab[i]<<endl;
       cout<<endl;

   rosnie(tab);
   maleje(tab);
   sym(tab);
   powt(tab);


   if(rosnie(tab)==true) cout<<"rosnaca";
   else if(maleje(tab)==true) cout<<"malejaca";
   else if(sym(tab)==true) cout<<"symetryczna";
   else if(powt(tab)==true) cout<<"elementy powtarzaaja sie";
   else cout<<"Zaden z warunkow nie jest spelniony";

   return 0;
}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Fajnie się zdecydować - albo przekazuj wszystkie informacje o tablicy przez argumenty, albo przez globale (FUJ). W tym momencie używasz obu rzeczy po trochu.

Obecny podział na funkcje jest bez sensu, bo ten kod i tak nie jest reużywalny (na co komu funkcje do operowania tylko na tablicach 5 elementowych?).

 

Pominę w ogóle to, że surowych tablic (int tab[rozmiar]; ) powinno się unikać - jak zdasz ten kurs czy cokolwiek teraz robisz i dalsza nauka języka Cię interesuje, to zainteresuj się alternatywami.

 

if(rosnie(tab)==true)

Robi to samo co

if(rosnie(tab))

 

    rosnie(tab);
   maleje(tab);
   sym(tab);
   powt(tab);

Ten fragment nie ma żadnego praktycznego sensu ;)

 

Co do sprawdzania powtórzeń - januzi już się do tego odniósł.

Możesz też sobie zrobić np. funkcję pomocniczą, ile razy występuje dana liczba w tablicy.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

@ MitycznyJeż dzięki za poradę. Ten program jest tylko w celu ćwiczenia c++. Nie jest to żadne zaliczenie czy cokolwiek innego, robię to tylko dla siebie (dopiero co zacząłem nauke c++). Co do sprawdzania czy się powtarza zrobiłem cos takiego:

bool powt(int *tab)
{
   for(int i=0;i<r;i++)
   {
       for(int j=i+1;j<r;j++)
       {
           if(tab[i]==tab[j])
               return true;
       }
   }
   return false;
}

Teraz chciałbym dodać jeszcze wyświetlanie który element się powtarza i ile razy.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Czyli dodatkowa lista (albo lepiej drzewo), na której będziesz trzymać liczby i liczniki. Potem przeszukanie i pokazanie tej/tych z największą liczbą.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Teraz chciałbym dodać jeszcze wyświetlanie który element się powtarza i ile razy.

Chyba nie który, tylko które ;) Więcej niż jedna wartość może się powtarzać.

 

Do zwrócenia czegoś takiego powinno się użyć którejś z istniejących kolekcji. Na Twoim miejscu wróciłbym do tego, jak już ogarniesz podstawowe pojemniki (vector/set/map) i będziesz wiedzieć w jakiej sytuacji którego użyć. Dodatkowa zaleta skupienia się na tym wcześniej niż później: porzucisz surowe tablice.

 

Równie ważną rzeczą jak umiejętność napisania takich rzeczy samemu jest wiedza gdzie są gotowe funkcje których można użyć. Spróbuj teraz użyć algorytmów z biblioteki standardowej do osiągnięcia tego samego.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Witajcie, rozwiązałem mój problem korzystając z histogramu:

for(int i=0;i<256;i++)
       histogram[i]=0;
   for(int i=0;i<r;i++)
       histogram[(int) tab[i]]++;

   for(int i=0; i<256; i++)
   {
       if(histogram[i] != 0)
           cout<<"Liczba "<<i<<" powtorzyla sie: "<<histogram[i]<<" razy"<<endl;
   }

 

Natomiast rozwiązanie nie jest tak do końca idealne gdyż gdy w tablicy podam wartości np.: {2,3,3,4} w wyniku otrzymuje:

 

Liczba 2 powtorzyla sie: 1 razy

Liczba 3 powtorzyla sie: 2 razy

Liczba 4 powtorzyla sie: 1 razy

 

Moje pytanie, jak zrobić by liczba która występuje w tablicy tylko jeden raz nie byla traktowana jako powtórzenie?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

To już tylko od Ciebie zależy jak będziesz interpretować dane które uzyskałeś.

if(histogram[i] > 1)

?

;)

 

A teraz zrób tak, by nie ograniczać możliwych wartości w tablicy do 255 ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

To już tylko od Ciebie zależy jak będziesz interpretować dane które uzyskałeś.

if(histogram[i] > 1)

?

;)

 

A teraz zrób tak, by nie ograniczać możliwych wartości w tablicy do 255 ;)

 

Cześć, trochę poszukałem i wiem ze należało by użyć std::map<> / std::unordered_map<> aczkolwiek to chyba jak na razie dla mnie za wysokie progi, na razie muszę jeszcze parę razy przeanalizować ten kod aby to dobrze zrozumieć.

Dziękuje wszystkim za pomoc.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Tak na przyszłość, czyszczenie tablicy w pętli for jest mało efektywne. Przy typach prostych można użyć memset

 

@Mistyczny

Pominę w ogóle to, że surowych tablic (int tab[rozmiar]; ) powinno się unikać

Bo?

Każda struktura ma swoje zastosowanie, np. jeżeli wiem jakiego rozmiaru potrzebuję i w czasie pracy programu nie zmienia się, to po co bawić się w kontenery?

 

Zmienne globalne też mają swoje zastosowanie (no na pewno nie do przekazywania danych do funkcji :E ), np. mam cały nagłówek constów, a ostatnio bawię się w trzymanie parametrów (mogą się zmieniać) w zasadzie jako globalne zmienne (namespace), bo tak po prostu jest wygodniej i czytelniej, niż zabawa w przekazywanie ich do poszczególnych obiektów.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
' date='27 Sierpień 2018 - 09:45' timestamp='1535355908' post='15200554']

Każda struktura ma swoje zastosowanie, np. jeżeli wiem jakiego rozmiaru potrzebuję i w czasie pracy programu nie zmienia się, to po co bawić się w kontenery?

ólnych obiektów.

 

tylko, że std:array ma wydajność gołych tablic a do tego ma wszystkie korzyści jakie dają kontenery

skoro gościu uczy się C++ to niech uczy się już nowoczesnego stylu a nie C++98 :E

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Nie każdy ma luksus doboru kompilatora - witamy w świecie systemów wbudowanych ;)

 

Tak czy inaczej warto poznać zwykłe tablice i kontenery, zwłaszcza że te pierwsze są integralną częścią języka, a te drugie rozszerzeniem przez biblioteki ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

nie użyłbym określenia "rozszerzenie przez biblioteki" w stosunku do STL bo so same templaty, które są integralną częścią języka

 

a co to za procki programujesz z ciekawości?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

No ale to są definicje klas, z których korzystasz ;)

Tak samo czyste C to 3 instrukcje na krzyż, a resztę jedziesz z bibliotek.

 

Procki jak procki, głównie intele ale też PowerPC się trafi, w innych działach rzeźbią w fpga i chyba jakichś arm ale głowy nie dam.

 

Sęk jest w systemach operacyjnych, które są z mocno konserwatywnych linii linuksa. Niby można wrzucić nowsze ale dostawca sprzętu wtedy nie da wsparcia i dawaj na własną rękę rozwiązywać problemy z autorskimi szynami danych dostawcy. Z kolei w działających sprzętach nikt nie będzie ryzykował zmian, poza tym nikt nie zapłaci za taką zmianę, która z punktu widzenia zamawiającego nic nie zmienia.

 

Ja akurat mam taki kawałek, że bez problemu mogę robić na zwykłym komputerze i tylko potem skompilować właściwą wersją kompatybilną z docelowym systemem. No ale muszę uważać na pewne elementy języka, żeby chciały się skompilować i odpalić.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

trochę tak jak u nas - jak wychodzi "nowy" :E red hat to już jest przestarzały w stosunku do innych dystrybucji a żeby doinstalować nowsze wersje softu to jest batalia

ale finalnie i tak wrzucamy soft skompilowany najnowszymi kompilatorami bo zysk zawsze jest tego warty

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
' date='27 Sierpień 2018 - 09:45' timestamp='1535355908' post='15200554']

Tak na przyszłość, czyszczenie tablicy w pętli for jest mało efektywne. Przy typach prostych można użyć memset

Poważnie polecasz początkującemu bawienie się w mikro-optymalizacje? I to jeszcze takie "na pałę", zamiast - po bożemu - pomiaru co to faktycznie daje? :(

Było pewne powiedzenie o przedwczesnej optymalizacji...

 

Jeżeli już, to prędzej powinno się tablicę od razu zainicjalizować zerami ( int tab[256]{}; ), ale tak czy siak to tylko zbędne motanie początkującemu. Nauczy się programować, to może się zainteresować jak oszczędzać cykle. Ale uczyć oszczędzać cykle kogoś, kto jeszcze nie umie programować? Widziałem efekty czegoś takiego, i nie polecam :thumbdown:

 

' date='27 Sierpień 2018 - 09:45' timestamp='1535355908' post='15200554']

Bo?

Każda struktura ma swoje zastosowanie, np. jeżeli wiem jakiego rozmiaru potrzebuję i w czasie pracy programu nie zmienia się, to po co bawić się w kontenery?

Jak wspomniał Biskup - jest std::array, który nie jest w niczym gorszy, a w wielu rzeczach lepszy.

Turner nawet ostatnio wyraził swoją dość dosadną opinię na ich temat ->

Serio, automatyczne gnicie do wskaźnika, manualne ogarnianie rozmiaru, i ogólna niekonsekwencja w stosunku do innych typów, które grzecznie stosują się do value semantics, czyni je generatorami zamieszania i bugów. Ten kto nigdy się nie walnął przy obliczaniu rozmiaru tablicy sizeof'em niech pierwszy rzuci kamień :E

 

' date='27 Sierpień 2018 - 09:45' timestamp='1535355908' post='15200554']

Zmienne globalne też mają swoje zastosowanie (...)

Chyba mnie źle odbierasz jako maniaka object oriented propaganda i innych takich :)

Po prostu uważam że początkujący najpierw powinni skupić się na umiejętnym korzystaniu z istniejących abstrakcji i narzędzi, by nauczyć się pisać proste i jednocześnie czytelne programy (dla moich znajomych, których styczność z c++ ograniczyła się do typowo prowadzonego kursu na studiach to oksymoron).

 

' date='27 Sierpień 2018 - 13:48' timestamp='1535370530' post='15200802']

Nie każdy ma luksus doboru kompilatora - witamy w świecie systemów wbudowanych ;)

Mimo wszystko w takich tematach bym zakładał, że autor ma dostęp do cywilizowanego, aktualizowanego kompilatora ;)

Ten embed to nie jest jeden z tych, gdzie kod trafia na produkcję skompilowany pod debug? :D

 

aczkolwiek to chyba jak na razie dla mnie za wysokie progi

Słaba wymówka ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Point taken.

 

Akurat zamienność tablicy i wskaźnika jest wygodna. Może się mylić? Cóż jak każdy element języka, którego dobrze się nie zna ;)

 

Hehe nie powinien :E

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...