Forum Gry Hobby Sprzęt Rozmawiamy Archiwum Regulamin

Forum: C ++ procedura losujaca liczby

13.09.2013 17:34
1
Gersiak
68
Konsul

C ++ procedura losujaca liczby

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 :

http://wklej.to/nYMgY

Ale nie chce on dzialac :( moze ktos pomoc ?

PS. sory za brak polskich znakow..

13.09.2013 17:46
2
odpowiedz
Madril
175
I Want To Believe

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. :)

13.09.2013 17:47
3
odpowiedz
alpha_omega
53
Legend

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.

13.09.2013 17:53
4
odpowiedz
Madril
175
I Want To Believe

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. :)

13.09.2013 17:56
5
odpowiedz
Night Prowler
63
Solid Ptake

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.

13.09.2013 18:02
6
odpowiedz
cruiser
37
Generał

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.

13.09.2013 18:03
7
odpowiedz
Night Prowler
63
Solid Ptake

Tak, jeśli koleś ma problem z podstawowymi rzeczami to na sto procent kontenery mu pomogą i dodatkowo uproszczą zrozumienie całości.

13.09.2013 18:04
8
odpowiedz
Heretyk
100
Generał

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.

13.09.2013 18:28
9
odpowiedz
Gersiak
68
Konsul

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ć ?

13.09.2013 18:30
10
odpowiedz
Toshi_
126
Got sarcasm?

Chciał bym to zrobić jak najprostszym sposobem nie wykorzystując nie wiadomo jakich rzeczy.
... to zmień język ;D

13.09.2013 18:32
11
odpowiedz
Gersiak
68
Konsul

@10 proszę bez głupich odpowiedzi..

13.09.2013 18:53
12
odpowiedz
Wooler
69
Pretorianin

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.

13.09.2013 19:02
13
odpowiedz
to nie ja
16
Generał

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.

13.09.2013 19:26
14
odpowiedz
alpha_omega
53
Legend

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ć.

13.09.2013 19:49
15
odpowiedz
Gersiak
68
Konsul

"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ć :(

13.09.2013 20:10
16
odpowiedz
alpha_omega
53
Legend

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>

13.09.2013 20:16
17
odpowiedz
Gersiak
68
Konsul

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 :(

13.09.2013 20:17
18
odpowiedz
cube0
17
Generał

Ja chyba taki kod ci napiszę i go przeanalizujesz. Ale jutro bo dziś czas mnie nagli.

13.09.2013 20:24
19
odpowiedz
Gersiak
68
Konsul

Było by naprawdę super :) Nie chce gotowców ale akurat tą część kodu piszę już parę godzin i mam już jej dość :(

13.09.2013 20:35
20
odpowiedz
alpha_omega
53
Legend

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.

13.09.2013 20:39
21
odpowiedz
Gersiak
68
Konsul

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.

13.09.2013 21:02
22
odpowiedz
alpha_omega
53
Legend

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.

13.09.2013 21:13
23
odpowiedz
cube0
17
Generał

@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...

13.09.2013 21:16
24
odpowiedz
alpha_omega
53
Legend

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.

13.09.2013 21:30
25
odpowiedz
cube0
17
Generał

@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!!!

14.09.2013 03:25
26
odpowiedz
Toshi_
126
Got sarcasm?

@ [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

14.09.2013 15:57
27
odpowiedz
Gersiak
68
Konsul

@ 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++ ..

14.09.2013 16:02
28
odpowiedz
cube0
17
Generał

@Gersiak ale co mam ci pisać jak masz gotowca od alpha_omega. Po prostu scal to z twoim kodem i ci wyjdzie.

14.09.2013 16:14
29
odpowiedz
Wooler
69
Pretorianin

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

14.09.2013 16:57
30
odpowiedz
Gersiak
68
Konsul

@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 ;)

14.09.2013 17:08
31
odpowiedz
cube0
17
Generał

Chyba jednak będę musiał napisać gotowca. Ale to wieczorem.

14.09.2013 19:56
32
odpowiedz
bananowiec2
28
Centurion

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.

14.09.2013 20:33
33
odpowiedz
Degnar*
46
Generał

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...

14.09.2013 21:01
34
odpowiedz
Gersiak
68
Konsul

Degnar --> dokładnie tak ,druga tablica również stringów :)

14.09.2013 22:18
35
odpowiedz
ksips
126
Legend
14.09.2013 23:52
36
odpowiedz
Degnar*
46
Generał

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

15.09.2013 13:05
37
odpowiedz
Gersiak
68
Konsul

@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 ?

15.09.2013 13:22
38
odpowiedz
Degnar*
46
Generał

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ź.

15.09.2013 13:42
39
odpowiedz
Gersiak
68
Konsul

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 :(

15.09.2013 16:14
40
odpowiedz
Degnar*
46
Generał

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.

15.09.2013 17:25
41
odpowiedz
cruiser
37
Generał

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];

15.09.2013 17:33
42
odpowiedz
Degnar*
46
Generał

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ć.

15.09.2013 20:48
43
odpowiedz
Gersiak
68
Konsul

Tak więc poczekam na Twoją opinie co lepiej użyć i jak ;)

15.09.2013 21:05
44
odpowiedz
cruiser
37
Generał

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.

15.09.2013 21:28
45
odpowiedz
Mercc
52
Konsul

->

15.09.2013 21:31
46
odpowiedz
Degnar*
46
Generał

Na mnie nie czekaj - nie jestem specjalistą, ciągle raczej amatorem :P

16.09.2013 08:52
47
odpowiedz
Gersiak
68
Konsul

@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

16.09.2013 09:59
48
odpowiedz
ksips
126
Legend
16.09.2013 17:43
49
odpowiedz
Gersiak
68
Konsul

@ksips dzieki za checi ale cos to nie chce dzialac :(

16.09.2013 17:49
50
odpowiedz
alpha_omega
53
Legend

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.

16.09.2013 17:51
51
odpowiedz
Degnar*
46
Generał

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.

16.09.2013 18:00
52
odpowiedz
Gersiak
68
Konsul

@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.

http://wklej.org/id/1131009/

I jeszcze raz wielkie piwko za pomoc :))

16.09.2013 18:04
53
odpowiedz
alpha_omega
53
Legend

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ć.

16.09.2013 18:09
54
odpowiedz
Degnar*
46
Generał

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ć)?

16.09.2013 18:12
55
odpowiedz
alpha_omega
53
Legend

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.

16.09.2013 18:43
56
odpowiedz
Gersiak
68
Konsul

@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 ;/

16.09.2013 18:49
57
odpowiedz
alpha_omega
53
Legend

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).

16.09.2013 18:51
58
odpowiedz
ksips
126
Legend

zamiast daj [help]

16.09.2013 18:57
59
odpowiedz
Gersiak
68
Konsul

@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ć.

16.09.2013 19:00
60
odpowiedz
ksips
126
Legend

Spróbuj zamiast

if(odpowiedzi[help].compare(odp_pop)==0)

dać

if(odpowiedzi[help]==odp_pop[help])

16.09.2013 19:12
61
odpowiedz
Gersiak
68
Konsul

Nadal to samo tu musi być jakiś inny haczyk ..

16.09.2013 19:25
62
odpowiedz
Degnar*
46
Generał

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ś.

16.09.2013 20:10
63
odpowiedz
Gersiak
68
Konsul

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 ?

16.09.2013 20:17
64
odpowiedz
Degnar*
46
Generał

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.

16.09.2013 20:40
65
odpowiedz
Gersiak
68
Konsul

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();

16.09.2013 20:42
66
odpowiedz
Degnar*
46
Generał

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 ^^

16.09.2013 20:47
67
odpowiedz
alpha_omega
53
Legend

Jeśli jeszcze to czytasz, to przyjrzyj się temu (sprawdź czy Ci zadziała):

http://wklej.org/id/1131174/

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.

16.09.2013 21:25
68
odpowiedz
Gersiak
68
Konsul

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 :)

16.09.2013 21:38
69
odpowiedz
alpha_omega
53
Legend

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.

Forum: C ++ procedura losujaca liczby