Siemka!
Mam pewien problem nad ktorym siedze juz kilka godzin. Mianowicie potrzebuje stworzyc funkcje w C++ ktora wylosuje mi 15 liczb (beda to indeksy tablic) z 15 liczb (po prostu wszystkie liczby) ,ale bez powtorzenia. Stworzylem taki kod :
Ale nie chce on dzialac :( moze ktos pomoc ?
PS. sory za brak polskich znakow..
Nie wiem po co ta tablica zmiennych logicznych czy_wystapilo.
W warunku while odwołujesz się do niej jak do funkcji (logicznie, bo składniowo jak do tablicy), a nigdzie nie wpisujesz do tej tablicy wartości logicznych. Zresztą to nie miałoby prawa działać w ten sposób.
Sądzę, że gdzieś coś widziałeś z czy_wystapilo, ale tam było to funkcją sprawdzającą, czy w tablicy liczb już nowa wystąpiła, a źle zapamiętałeś. Proponuję iść tym tokiem rozumowania. :)
Nie wystarczy pobierać obecny czas (milisekundach od jakieś daty; jest chyba w C++ taka funkcja), a następnie sprawdzać resztę z dzielenia uzyskanej w ten sposób liczby, najpierw przez 15 (jak reszta 0 - pierwsza liczba z pietnastu, reszta 1 - druga liczba, reszta 2 - trzecia itd.), odłożyć wylosowaną liczbę w innej tablicy, przepisać tablicę z której losujesz wrzucając wylosowaną liczbę na koniec, a w następnej sekwencji pętli zmniejszać dzielnik o jeden i zwiększać wskaźnik czy indeks tablicy do której będzie zapis o 1?
Zaznaczam, że nie patrzyłem na Twój kod.
A dobra, albo pominąłem nawias o indeksach tablic, albo go na początku nie było.
Musisz jeszcze po pętli do..while dać ustawianie czy_wystapilo[liczby] na true i powinno śmigać, chyba że dalej nie zrozumiałem istoty problemu. :)
Zacznijmy od tego, że popełniłeś błąd w trakcie inicjowania generatora liczb losowych - ziarno może być tylko liczbą całkowitą co oznacza, że musi posiadać typ int, trzeba wykonać rzutowanie z time_t na int:
srand(static_cast<unsigned>(time(NULL)));
Poza tym po co Ci tablica flag? Bardziej logicznie byłoby wyrzucić inkrementacje licznika z pętli for i wewnątrz samej pętli uzależnić przejście dalej od tego czy liczba powtarza się czy nie. Sprawdzenie możesz wykonać zagnieżdżonym forem który działa od zerowego indeksu do tego który aktualnie przetwarzasz. Jeśli liczba się powtórzy to po prostu pętla jeszcze raz przeleci po tym samym indeksie. To dosyć prosty kod.
Zamiast tablicy int liczby[15] uzyj kontenera std::set, w petli losuj liczbe i dodawaj ja poprzez metode insert std::set, petle kontynuuj dopoki rozmiar konetnera nie osiagnie 15 elementow.
Tak, jeśli koleś ma problem z podstawowymi rzeczami to na sto procent kontenery mu pomogą i dodatkowo uproszczą zrozumienie całości.
Nie jestem pewien czy rozumiem co chcesz zrobić w tej linijce:
while (czy_wystapilo[liczby]);
Jeżeli dobrze rozumiem to powtarzasz pętle do momentu, gdy w i-tym miejscu tablicy boolianów będzie prawda. Nie aktualizujesz jednak wartości tej tablicy.
Strasznie skomplikowane to co piszecie i do tego każdy ma swoją teorię. Chciał bym to zrobić jak najprostszym sposobem nie wykorzystując nie wiadomo jakich rzeczy. Czyli z tego kodu nie zrobię już nic tak ? nie da się go zaktualizować aby działał ?
Edit:
Może napiszę jaki program chcę wykonać może bedzie łatwiej mi pomóc a więc:
Mam tablicę stringów i w indeksach od 0-14 mam zapisane pytania. Chcę teraz zrobić funkcję która wylosuje pewne pytanie z tych 15 i będziemy musieli podać na nie odpowiedź i tak 15 pytań ,aby się wylosowało tylko bez powtórzeń. Jak najprościej to wykonać ?
Chciał bym to zrobić jak najprostszym sposobem nie wykorzystując nie wiadomo jakich rzeczy.
... to zmień język ;D
Przede wszystkim - sranda daj przed funkcje na samym początku programu! Bardzo prawdopodobne (o ile dobrze kojarzę), że za każdym razem będzie ci się "losowało" to samo umieszczając sranda w tym miejscu gdzie go umieściłeś.
We whilu masz coś takiego - liczby=rand()%15+1; a więc używając tej liczby jako indeks musisz odjąć od niej 1 (bo może mieć wartość od 1 do 15)!
Pod drugie - musisz w pętli for, pod whilem umieścić aktualizację stanu tablicy: czy_wystapilo[liczby - 1] = true;
To kilka takich szybkich obserwacji, nie gwarantuję że to jedyne błędy w twoim kodzie.
Zrób sobie to tak: (pseudokod bo składni C++ nie pamiętam):
Twoja tablica z 15 stringami - tab1
Tworzysz tablice 15 pustych stringów - tab2
for od i=0 do 14
[
...losujesz liczbę 0-14 - n
...while(tab2[n] nie jest puste)
...[
......n++
......jeżeli n>14 to n=0
...]
...tab2[n]=tab1
]
W tab2 masz 15 pytań w kolejności losowej.
Albo jakoś tak.
Masz tablicę wyzerowaną na wyniki (tab_wyniki). Masz zmienną przechowującą reszty (reszta). Masz zmienną czas. Masz i ustawione na 1.
Pętla (while i<=15): 1. Pobierz czas w milisekundach od któregoś tam roku (jest funkcja taka w C++) i zapisz w zmiennej czas. 2. Wyciągnij resztę z dzielenia czasu przez 15 (masz takie działanie, albo funkcję w C++; dzielenie przez 15 daje reszty od 0-14) i zapisz w zmiennej reszta. 3. Sprawdź czy tab_wyniki[reszta] wynosi 0. Jeśli tak wykonaj polecenie tab_wyniki[reszta]=i i podnieś wartość i o jeden. Jeśli nie: nie rób nic (pętla się powtórzy).
Jeśli gdzieś się nie machnąłem, będziesz miał w wyniku tablicę (tab_wyniki) z liczbami od 1 do 15 w losowym porządku. Jak będziesz chciał później wyświetlić swoje stringi w tej kolejności, to po prostu dajesz rosnącą pętlę po tablicy ze stringami string_tab[(tab_wyniki [.i] -1)]
BTW. TO będzie bardzo niewydajne podejście, bo będzie Ci się, jak już wypełnisz większość tabelki, losować i losować i losować, aż trafi na wolne miejsce. Tak się nie powinno tego pisać, ale ogólnie powinno działać.
"for od i=0 do 14
[
...losujesz liczbę 0-14 - n
...while(tab2[n] nie jest puste)
...[
......n++
......jeżeli n>14 to n=0
...]
...tab2[n]=tab1
]"
Wydaje się być dobre niestety nie wiem do końca jak to zapisać :(
Dobra, mniej więcej sobie przypomniałem jak to w C++ wyglądało. Tylko trzeba by sprawdzić jakie nagłówki trzeba dodać.
srand(time(NULL))
powiedzmy, że to Ci uruchamia generator liczb pseudolosowych (dla takich zastosowań, to ja bym się nie przejmował i po prostu od razu resztę z czasu w mikrosekundach brał, ale od Ciebie raczej będą wymagać, żeby jak najbardziej te liczny ulosowić); robisz to raz na początku. Jak już to przygotujesz, to możesz używać funkcji rand.
rand() - losuje Ci liczbę pseudolosową
jak chcesz mieć liczbę z określonego zakresu, to robisz tak
rand() % n - wyrażenie to oznacza: wyciągnij resztę z dzielenia rand() przez n (taka reszta będzie się mieścić w zakresie od 0 do n-1; co jest oczywiste: reszty z dzielenia zawsze się tak zachowują)
W przykładzie jaki sprawdzałem, gość miał dodane nagłówki:
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <time.h>
alpha_omega niestesty sposób który podałeś jest dla mnie za trudny do zrozumienia niestety nie korzystaliśmy jeszcze z takich nagłówków :(
Ja chyba taki kod ci napiszę i go przeanalizujesz. Ale jutro bo dziś czas mnie nagli.
Było by naprawdę super :) Nie chce gotowców ale akurat tą część kodu piszę już parę godzin i mam już jej dość :(
Gersiak --
Po prostu je wklej na górze (nagłówki) i powinno wszystko działać. Nagłówki dodają tylko biblioteki. Ja Ci nie opisuję jak napisać całość, tylko jak losować liczby.
W main, na samym początku, wpisujesz
srand(time(NULL));
Nie ważne co to dokładnie robi, ważne czym możesz się później dzięki temu posługiwać.
A możesz dzięki temu używać sobie następnie funkcji losującej rand(). rand() zwraca Ci po prostu liczbę pseudolosową z zakresu 0 - 32767. Liczbę całkowitą. Losuje jakąś liczbę z tego przedziału i zwraca. Najczęściej jednak nie potrzebujesz liczby z takiego zakresu, tylko z określonego. Więc co możesz zrobić?
Jak dzielisz dwie liczby całkowite przez siebie, np. a przez b , to albo b dzieli a, i wtedy reszta wynosi 0, albo b nie dzieli dokładnie a i wtedy reszta może wynosić 1,2,3,4,5.... b-1. Inaczej rzecz ujmując reszta z dzielenia a przez b, mieści się zawsze w zakresie od 0 do b-1.
Więc teraz masz tę swoją liczbę pseudolosową zwróconą przez rand(). Nie wiadomo co to za liczba, jest losowa, a więc losowe jest też to jak dzieli się przez b (jaką z takiego dzielenia daje resztę). Więc ta reszta też jest losowa. Ale zarazem jest w zakresie od 0 do (b-1).
Więc jak chcesz mieć liczbę losową z przedziału np. 0-14, to robisz tak:
rand() % 15 (operator % oznacza właśnie wyciągnięcie reszty z dzielenia wyrażenia po lewej stronie, przez wyrażenie po prawej stronie)
Możesz więc sobie zapisać np.
zmienna = rand() % 15
i będziesz miał w zmiennej 'zmienna' losową liczbę z przedziału 0-14.
O tym ja wiem tylko chcę wylosować 15 takich liczb (0-14) na raz ,ale nie powtarzających się i zapisać je do drugiej tablicy.
Kurde, ja nigdy nie pisałem inaczej niż hobbystycznie i niemal niczego już nie pamiętam. Będzie więc pewnie bardzo nadmiernie w stosunku do tego, jak to najprościej zrobić. I nie będzie o stringach, tylko o wylosowaniu 15 losowych liczb do tablicy.
temp - zmienna
tab_1 - tablica z której losujemy wypełniona po kolei liczbami od 0-14 (musisz ją wypełnić)
tab_2 - tablica wyników (tej samej wielkości)
srand(time(NULL)); //uruchamia generator liczb losowych
for (i=15; i>0; i--)
;;;;;;;;;
...... losowa = rand() % i; .................//losuje liczbę z przedziału 0 do i-1 (czyli na początku 0-14) i zapisuje ją w zmiennej losowa
...... tab_2[15-i] = tab_1[losowa]; ..............//z tablicy liczb od 0-14 bierze losową komórkę i zapisuje w wynikach w pierwszej komórce
...... temp = tab_1[i-1] ................//wpisuje ostatnią liczbę z tablicy liczb do tymczasowej zmiennej
...... tab_1[i-1] = tab_1[losowa]; .................//wykorzystaną liczbę z tablicy liczb, wpisuje w ostatnią komórkę tej tablicy
...... tab_1[losowa] = temp; ..................//liczbę, która wcześniej była na końcu i wpisaliśmy ją w temp, wpisuje w miejsce tej wylosowanej
;;;;;;;
W kolejnym przebiegu pętli 'i' się zmniejsza o jeden. Więc nie możemy już wylosować komórki jaka była ostatnia w poprzednim przebiegu pętli. A to właśnie tam przenieśliśmy wylosowaną (a więc już użytą liczbę), którą najpierw wpisaliśmy do wyników, a potem zamieniliśmy (za pośrednictwem zmiennej temp) miejscami z ostatnią liczbą w tabeli liczb.
Jak chcesz to uogólnić, to wszędzie gdzie masz 15 zmień to w n. Żeby to zamknąć w funkcję, to już musisz sam pokombinować, na pewno jako parametr powinieneś jej przekazywać wartość n, wewnątrz funkcji w pętli wypełnić tablicę liczb (skoro n byłoby zmienne, to trzeba to zrobić dynamicznie), natomiast nie bardzo pamiętam jak się w C++ zwracało z funkcji tablice, czy przypadkiem nie tworzyło się wtedy tablicy inaczej i nie zwracało jedynie wskaźnika.
@up Posłużyłeś się srandem. On ma sam taką funkcję stworzyć. Dokładnie ma stworzyć funkcję, która z 15 liczb generuje je wszystkie bez powtórzenia. Jutro będę w domu to mu na spokojnie kod napiszę albo podam sam algorytm. Bo tu problem nie tkwi w języku programowania tylko w sposobie znalezienia odpowiedniego algorytmu.
No chyba, ze ma w tej funkcji zastosować ten srand()??? Ale to wtedy byłoby banalne...
Co za różnica. Przecież nie o to chodzi w zadaniu, ażeby użyć funkcji, która zwróci gotowy ciąg. Tak mi się przynajmniej wydaje. Tylko właśnie o to, żeby manipulować zmiennymi.
Nie wiem zresztą czy mój pomysł działa, bo jak mówię - od lat się w to nie bawiłem, nie mam jak sprawdzić.
EDIT:
Myślisz? Że ma stworzyć funkcję generującą? W takim razie źle zrozumiałem problem. Mi się wydawało, że chce po prostu uzyskać losowy ciąg liczb bez powtórzeń z pewnego zakresu. Jasne, że to jest banalne - jak się już załapało bakcyla.
@up Teraz to i ja się pogubiłem???
Twórco wątku tłumacz o co ci konkretnie chodzi???
EDIT:@alpha_lyr Kurde jemu chodzi o srand(). Właśnie przeczytałem jego kod który wkleił. Jutro będę miał dostęp do kompilatora to napiszę kod, przetestuję i może podam gotowca. Chociaż masz go powyżej w postaci prawie gotowca.
Autorze wątku na przyszłość takie tematy wrzucaj na: http://forum.pclab.pl/forum/22-Programowanie/
Tam taką odpowiedź dostaniesz parę razy krotnie szybciej!!!
@ [11] - ale to nie była głupia odpowiedź. W normalnym języku (chociażby w Javie) zrobiłbyś sobie obiekt Pytanie oraz listę tych obiektów, losowałbyś numer pytania i jeśli znajdowałby się dalej na liście, to byś go z niej zdjął.
Serio, jeśli chcesz prostych sposobów, to nie C++ ;D
@ cube0 --> było by super tak więc czekam ;)
@Toshi_ --> kategoria to szkoła można więc domyślić się ,że nie robię tego dla siebie tylko robię to do szkoły i musi być to C++ ..
@Gersiak ale co mam ci pisać jak masz gotowca od alpha_omega. Po prostu scal to z twoim kodem i ci wyjdzie.
Zrobiłem ci wszystko to co napisałem w poście [12] i działa. Wystarczyło tylko lekko przerobić twój kod. Z tym srandem miałem rację - przy wywołaniu funkcji 2 razy ze srandem w środku w ciągu sekundy losowanie zwraca taki sam wynik. Dodałem jeszcze tylko prostą pętlę zerującą najpierw tablicę czy_wystapilo.
http://wklej.to/W7iW9
@Wooler -- super działa o to mi chodziło :) mam niestety teraz jeszcze jeden problem chcę przerobić kod zeby liczby zapisały się do tablicy zamiast do zmiennej ,aby można było wypisać np. cout << tab2[1]; (i pokazuje mi jedna liczbe). Uzywajac twojego kodu i przerabiając na tablice po użyciu np. cout << tab2[7] wypisuje mi tą samą liczbę 15 razy :( czy wiesz co na to poradzić ?
PS.
Chcę zrobić coś takiego :
http://wklej.org/id/1129579/
w pierwszej tablicy mam zapisane pytania od 0-14. Teraz chce dzięki drugiej tablicy wywoływać pytanie z pierwszej aby było losowe. Mam nadzieje ,ze wiesz o co mi chodzi ;)
Chyba jednak będę musiał napisać gotowca. Ale to wieczorem.
Mówiłeś coś o losowaniu pytania z puli 15, to spróbowałem to zrobić, tylko trochę inaczej:
http://wklej.org/id/1129708/
Tylko nie wiem czy znasz już podstawowo programowanie obiektowe.
Ok, mam chwilę czasu i mogę pomóc - możesz tylko napisać DOKŁADNIE co trzeba zrobić? Już się parę różnych opcji w tym wątku przewinęło (włącznie z napisaniem własnego generatora liczb pseudolosowych ^^)...
Jeśli dobrze rozumiem to ogólnie rzecz biorąc, masz tablicę 15 pytań jako stringi, chcesz z niej wylosować 15 pytań w losowej kolejności i bez powtórzeń i po każdym pytaniu zapisać odpowiedź (jaki typ zmiennej?) w drugiej tablicy, tak?
EDIT: [32]-->Na cholerę pre-kompilowany header?! Raz, że jeśli używa IDE, które nie generuje automatycznie tego pliku to nawet mu się nie odpali, a dwa, że przy wrzucaniu tylko podstawowych bibliotek to i tak praktycznie nic nie daje...
Wydaje mi się, że można to zrobić trochę łatwiej i wygodniej: http://wklej.org/id/1129888/
Nie trzeba cały czas latać po całej tablicy wylosowanych liczb jak u ksipsa :P
@ksips,Dengar* --> zarówno jedno jak i drugie działa dzięki , o to mi chodziło ;) jednak jak już służycie pomocą to dwa pytanka jeśli można.
1 - Jak najłatwiej będzie mi sprawdzać czy dana odpowiedź z tablicy jest poprawna ? stworzyć trzecią tablicę o nazwie odpowiedzi poprawne i jakoś to porównywać ? jeżeli tak ,to jak to zrobić skoro odpowiedzi do tablicy moje_odpowiedzi są dodawane losowo.
2 - Dlaczego przy wpisywaniu odpowiedzi do tablicy moje_odpowiedzi przy dodaniu spacji np : moja odpowiedz program się wali i wysypuje potem dwa pytania ? i jak temu zapobiedz jeżeli się da ?
1 -> Jeśli bierzemy pod uwagę ten kod, który ci wysłałem to możemy założyć, że miejsce w tablicy danego pytania jest jego identyfikatorem, czyli pytania maja ID od 0 do 14 włącznie. Kolejność odpowiadania w programie będzie losowa, ale miejsce w tablicy answers zawsze będzie odpowiednie dla pytania - answers dla questions itd.
Wystarczy więc zrobić trzecią tablice, gdzie wrzucisz poprawne odpowiedzi, tak żeby odpowiadały pytaniom i tyle. Wtedy możesz porównać czy answers jest takie same jak valid_answers za pomocą tej funkcji: http://www.cplusplus.com/reference/string/string/compare/
2-> cin przerywa wczytywanie gdy natrafią na spację. Musisz użyć std::getline(cin,test) gdzie test to nazwa stringa, do którego chcesz wrzucić odpowiedź.
Mozesz wytlumaczyc jak dziala po polsku to string::compare ? niestety nie bralismy jeszcze tego :(
Edit:
dodalem cos takiego :
std::getline(cin,tab2[help]);
nistety nei dziala :(
Ciekawe, używasz w swoim kodzie using namespace std;? Jeśli nie to oczywiście przed zamiast cin musisz napisać std::cin, jeśli jednak używasz - jesteś pewny, że ładujesz dane do stringa? Za to co do porównywania, masz tutaj przykładowy kod jak to działa: http://wklej.org/id/1130237/
Najprostsze porównywanie sprawdza po prostu czy string, którego chcesz porównać jest taki sam jak ten podany w argumencie funkcji. Jeśli jest taki sam to funkcja zwraca 0, jeśli inny to coś innego.
Degnar: std posiada operator porownania stringow ==, dlatego zamiast std::compare lepiej jego uzyc. Kod bedzie dzieki temu znacznie wyrazniejszy.
Gersiak: jak nie wiesz do czego sluzy dana funkcja, to korzystasz z dokumentacji.
cin domyslnie przerywa wczytywanie gdy natrafi spacje\newline, ale mozna to wylaczyc wstawiajac jako pierwszy argument dla cin nazwe noskipws, np.: cin>>noskipws>>answers[help];
Hmm... Nie wiem czemu mam zakodowane w pamięci, żeby nie używać operatora porównania, tylko właśnie funkcji compare. Muszę o tym trochę poczytać.
Moim zdaniem dopoki nie zaczniesz uzywac wyjatkow, to nie ma sensu uzywac compare. operator == rozni sie tylko tym od compare, ze nie zawsze rzuca wyjatki w przypadku wystapienia krytycznego bledu.
Na mnie nie czekaj - nie jestem specjalistą, ciągle raczej amatorem :P
@cruiser ---> możesz więc napisać jakiś przykładowy kod sprawdzający tablice stringów ? było by dużo prościej. Z góry dzięki
Kurde, Gersiak, przestań grać głupiego, ściągnij sobie jakiś podręcznik, albo wejdź na jakiś tutorial w necie, i spróbuj coś samemu zrozumieć, a nie czekasz aż ktoś za Ciebie napisze gotowce. W ten sposób absolutnie niczego się nie nauczysz.
Nawet nie próbujesz się zastanowić, co robi kod który ktoś Ci napisał. Tylko: działa, nie działa.
****
Króciutki kawałek kodu jaki dawałem dawno temu ([22]), gdybyś się zastanowił jak funkcjonuje, możesz później wykorzystać do kolejnych zastosowań. Bo np. kod ksipsa, dokonuje tego samego nadużycia, co jeden z moich wcześniejszych: losuje, a dopiero potem sprawdza, czy przypadkiem już tej liczby nie wylosował. Jest to całkowicie zbędne.
Gresiak --> Mój kod przecież działa, prawda? Owszem, jak służnie cruiser zauważył, użycie '==' zamiast compare() jest bardziej czytelne i łatwiejsze do przeczytania, ale to w gruncie rzeczy drobnostka, która niewiele zmienia.
@alpha_omega jezeli kod nie jest pisany przez Ciebie w calosci ciezko go potem modyfikwoac zrozum.. wtedy lepiej po prostu przeanalizowac gotowy kod i nauczyc sie konstrukcji aby nastepnym razem umiec zrobic dane zadanie. Ktos chce pomoc i chwala im za to jezeli ty nie wyrazasz takiej checi to nikt nie karze ci czytac i pisac...
@Dengar* ---> dziala aczkolwiek cos nie moge sobie poradzic zeby zamienic tego stringa example na dzialajaca tablice. Najlepiej chyba jak dam kod abys powiedzial co jest zle.
I jeszcze raz wielkie piwko za pomoc :))
Nie gadaj bzdur. Pomysł na stworzenie permutacji danego zbioru liczb został podany kilkadziesiąt postów temu. Wszystkie Twoje następne pytania - ich rozwiązania - zawierają ten sam koncept, który po prostu trzeba było zrozumieć i zacząć używać. Dodatkowa praca jest minimalna. Nawet nie próbowałeś jej wykonać.
Skąd ci się bierze i w linii 135 i 136? Czytałeś jakie błędy wyskakują przy kompilacji (bo to się nie ma prawa nawet skompilować)?
Degnar --
Tak właśnie jest jak się przepisuje i skleja gotowce bez własnego namysłu.
Gersiak --
Jest chyba oczywiste, że jak masz tablicę pytań (tab_pytania), poprawnych odpowiedzi (tab_poprawne), oraz wygenerowałeś sobie permutację ze zbioru 0 do [n-1] (gdzie n to wielkość tych tablic) i masz ją w tablicy tab_permutacja, to możesz sobie bez problemu wygenerować pytania w kolejności tej permutacji:
Po prostu tworzysz pętlę (od zera do n-1), w której wyświetlasz coś takiego.
tab_pytania[tab_permutacja[n]]
Jak chcesz, to możesz już tutaj, od razu, pobierać sobie odpowiedź (pobrać ją cin) i zapisywać po kolei w tablicy tab_udzielone. Czyli w tab_udzielone[n].
Jak później chcesz sprawdzić, czy udzielone odpowiedzi są odpowiedziami prawidłowymi, to porównujesz dwie tablice (tab_udzielone i tab_poprawne) w kolejnej pętli od 0 do n-1. Albo i w tej samej jak sobie będziesz chciał.
Np. w takiej pętli:
cout<<"Zadałeś pytanie: "<<endl;
cout<<tab_pytania[tab_permutacja[n]]<<endl;
if(tab_udzielone[n] == tab_poprawne[tab_permutacja[n]]) ; cout<<"Odpowiedź poprawna"<endl; ; else cout<<"odpowiedź błedna"<<endl; cout<<"Prawidłowa odpowiedź: "<<endl; cout<<tab_poprawne[tab_permutacja[n]]<<endl; ;
Jeśli nie porównujesz liczb (porównujesz np. stringi; bo to one są odpowiedziami), to są specjalne funkcje do porównywania. Ale pewnie == też zadziała, bo chyba String ma przeciążony ten operator w ten sposób.
@alpha --> nie komentuje Twoich wypowiedzi
Degnar* --> bez wyskakuje błąd z compare z którym nie miałem jeszcze do czynienia i się go uczę dlatego postanowiłem dać i które też nie działa ;/
Gersiak --
Sobie nie komentuj. Odpowiedzi masz już gotowe. Jak nie chcesz z nich skorzystać, to zostawiam pole dla jeleni (bez obrazy chłopaki, ale gość leci z Wami w kulki).
@ksips po dodaniu odp_pop[help] niestety niestety wgl nie wyświetla pytań :( już powoli gubię się w tym kodzie jeszcze będę próbował to edytować.
Spróbuj zamiast
if(odpowiedzi[help].compare(odp_pop)==0)
dać
if(odpowiedzi[help]==odp_pop[help])
Heh... Serio, alpha_omega ma rację... Powiedz proszę, do czego wrzucasz pytania? Do tabeli odpowiedzi[] czy do tabeli pytania[]?
Przy okazji sam się czegoś nauczyłem - używanie cin.getline to faktycznie niekoniecznie był dobry pomysł, ponieważ po cin>>znak pierwszy getline przechwytuje znak końca linii. Głupia pomyłka z mojej strony, ale do łatwej naprawy przez wklejenie cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
Czyli co trzeba zrobić, żeby to zadziałało:
1)Wkleić powyższą linię kodu po cin>>znak
2)Wpisać pytania faktycznie do pytań
3)Wywalić i zmienić na [help]
4)Dodać funkcję test, którą zadeklarowałeś i nawet użyłeś, ale nie zdefiniowałeś.
Wszystko działa ,dorobiłem jeszcze punkciki i inne duperele. Zostały jeszcze najlepsze wyniki i takie duperele ale to zrobie samemu i potem :) Mam jeszcze OSTATNIE pytanie a w zasadzie problem wszystko działa aczkolwiek po skończeniu gry i powrocie do menu gdy wybiorę znów "1" aby grać niestety wtedy już nie działa. Wypisuje się tekst przed grą "powodzenia" aczkolwiek pytanka już nie ruszają. Co może być problemem ?
Tabela odpowiedzi jest zapełniona, musisz ją wyczyścić, wystarczy zwykła pętla for i w niej odpowiedzi.clear() Możesz to robić przed rozpoczęciem każdej gry, albo po zakończeniu każdej gry.
Nie mam sil do tego caly czas kompilator sie sypie nawet nie wywalajac komunikatu co jest zle ;/
:
for (int i=0;N-1;i++)
odpowiedzi.clear();
http://cpp0x.pl/kursy/Kurs-C++/Poziom-2/Petla-for/294
No i czyścisz każdego stringa po kolei, czyli odpowiedzi.clear[ i ]()
EDIT: Ano tak, GOL przecież zżera i w kwadratowych nawiasach ^^
Jeśli jeszcze to czytasz, to przyjrzyj się temu (sprawdź czy Ci zadziała):
Nie ma chyba prostszego sposobu (bez użycia bardziej złożonych konstrukcji języka), niż sobie generować taką tablicę z permutacją, a potem jej używać. W kodzie jest przykład wyświetlenia pytań w losowej kolejności przy posłużeniu się taką tablicą.
Równie łatwo można dopisać po każdym losowym zapytaniu cina, który przyjmie odpowiedź i zapisze ją do tablicy odpowiedzi (pierwszą w odpowiedzi[0], następną w odpowiedzi[1] itd. - czyli bez żadnego motania).
Potem, żeby to porównać z odpowiedzią prawidłową, robisz po prostu dla n-tego zadanego pytania z kolei (czyli też dla n-tej odpowiedzi), takie porównanie:
odpowiedzi[n] == prawidłowe[permutacja[n]];
Czyli z 'prawidłowe' robisz dokładnie to samo, co wcześniej - i co jest zrobione w załączonym kodzie - z 'pytania'. Sens tego jest jasny: jak wcześniej za pomocą permutacji zmienialiśmy kolejność wyświetlania pytań (a odpowiedzi od razu zapisaliśmy w tej zmienionej kolejności - w kolejności wyświetlania pytań a nie tego jak siedzą w tablicy pytań), tak teraz w tak samo zmienionej kolejności musimy pobierać prawidłowe odpowiedzi, żeby pasowały do danych pytań.
Robisz to w zwykłej pętli i reagujesz sobie jak chcesz na to, czy jest prawidłowa, czy nie jest.
Degnar* --> dzięki działa wszystko już ;)
alpha --> na pewno poczytam coś na ten temat fajna sprawa i dużo bardziej ułatwia życie gdy się to umie :)
W tym kodzie nie ma nic zaawansowanego. To są podstawy, które możesz poznać całkiem szybko. Zagadnienia tam użyte, to:
- tworzenie funkcji
- wskaźniki
- tworzenie dynamiczne tablic (tj. tworzenie tablic innym sposobem, który pozwala na to, żeby wielkość tablicy była ustalana w czasie wykonywania programu, a nie wiadoma z góry).
- skrótowa inicjacja tablic
Ta funkcja której deklarację masz przed main nie robi nic poza tym, że tworzy zwykłą tablicę liczb, które są ustawione w losowej kolejności bez powtórzeń i ją zwraca. Więc otrzymujesz taką właśnie tablicę.
Innymi słowy masz np. (jeśli akurat tak ci wylosowało) permutacja[0] (pierwsza komórka tablicy 'permutacja') wynosi 3; permutacja[1] wynosi 0; permutacja[2] wynosi 1; permutacja[3] wnosi 2.
Więc teraz, jak masz swoją tablicę stringów z pytaniami (czterema), to jakbyś ją wyświetlał w pętli
for (i=0; i<4; i++) ;;;;;;; cout<<pytania[.i]; ;;;;;;; (te kropki przed i w rejestrze tablicy, to tylko z winy GOLa).
to w oczywisty sposób wyświetliłoby Ci te pytania po kolei, tak jak je umieściłeś w tablicy. Ale jak masz tą tablicę, którą nazwaliśmy 'permutacja' i zrobisz tak:
for (i=0; i<4; i++) ;;;;;;; cout<<pytania[permutacja[.i]]; ;;;;;;;
to pierwszy przebieg pętli będzie wyglądał tak:
cout<<pytania[permutacja[0]];
A jak wiemy permutacja[0] ma wartość (tak nam wylosowało) 3, więc w istocie przebieg pierwszy pętli, to będzie
cout<<pytania[3];
Na tym bazuje cały pomysł z posiadaniem takiej tablicy, żeby to tak sobie podstawiać i zmieniać. To zwykłe wstawienie jednej tablicy w indeks drugiej. Funkcja createPermutation, która tworzy taką tablicę liczb w losowej kolejności, to też nic skomplikowanego.