-
Daniel Fukuda
Mam takie zadanko... i nie rozumiem na czym ma polegac ta "magiczna" liczba, ktora ma uzytkownik wpisywac.
Z tego co ja wiem to w totolotku uzytkownik wybiera sobie 6 liczb z 49 a potem patrzy ile liczb dobrze trafi, kolejnosc liczb jest dowolna (chyba). Wiem, ze to grono Java a zadanie ma byc napisane w REXX'ie, ale skladnie javy tez znam i moze mi ktos podac przyklad w javie to zrozumiem, ale chodzi mi bardziej o wyjasnienie samego polecenia zadania :P
Ja bym napisal ten program w ten sposob (tak jak w totolotku), ze uzytkownik wpisuje najpierw 6 liczb, ktore sie nie powtarzaja a potem program losuje liczby od 1 do 49, wypisuje je a "mowi" nam ile liczb trafilismy ^^
A i czy ktos moze mi wyjasnic na czym polega to "ziarno"? Po co mi to:
"random(1, 49, mnum) - zwróci liczbę losową z przedziału 1 ... 49"
jak moge po prostu napisac random(1, 49). co mi daje to ziarno? w tym przypadku mnum.
A oto tresc calego zadania:
Napisać program, który na podstawie podanej przez użytkownika "magicznej" liczby podaje 6 liczb do "zakreślenia" w totolotku.
Wyprowadzić liczby w postaci (podano przykład):
Twoje liczby:
1 7 9 23 43 12
Pomoc:
Liczby w totolotku: 6 z 49
Liczby mają być losowe (jak to w totolotku). Użyć generatora liczb pseudolosowych.
W REXXie możemy zastosować wbudowaną funkcję random(...).
Wywołanie
random( od , do, seed)
inicjuje generator liczb pseudolosowych ziarnem seed (liczbą - tu podajemy wprowadzaoną przez użytkownika liczbę "magiczną") i zwraca liczbę pseudolosową z przedziału [od , do]
Kolejne wywołania tej funkcji z argumentami od, do:
random( od, do)
zwracają kolejne liczby pseudolosowe w ciągu zainicjowanym przez pierwsze wywołanie generatora
Przykład:
Niech mnum wprowadzona liczba magiczna:
random(1, 49, mnum) - zwróci liczbę losową z przedziału 1 ... 49
kolejne wywołania
random(1, 49) - zwracają kolejne liczby ciągu pseudolosowego.
Uwaga, uwaga. Generator zwraca liczby losowo - zatem mogą się one powtarzać!!!
Oczywiście my chcemy pokazać tylko 6 niepowtarzających się liczb. -
Brut[all]
Za bardzo się przejmujesz :)
Te całe "ziarna", "seedy", czy "liczby magiczne" (:D) istnieją tylko dlatego, że komputer nie jest w stanie wytworzyć prawdziwej liczby losowej, może tylko korzystać z jakichś pokomplikowanych algorytmów opartych o ilości cykli wykonywania, aktualny czas, czy... parametr seed...
Ten seed ma po prostu zmniejszyć szansę, że liczby losowane z dwóch losowań będą takie same lub zbliżone do siebie. Bardzo często dla zwiększenia losowości sam seed jest losowany z wcześniejszego randoma.
I chyba nieuważnie przeczytałeś zadanie.
Tu nie o to chodzi, żeby komputer nam zasymulował działanie totka - my podajemy numerki, a on mówi, ile trafiliśmy.
Chyba dostatecznie wyraźnie jest napisane:
"Napisać program, który (...) podaje 6 liczb do "zakreślenia" w totolotku."
Ty tutaj nie masz wprowadzać żadnych "skreśleń", program nie ma Ci wcale mówić, czy trafiłeś, czy nie - program ma się Ciebie zapytać o przypadkową liczbę (seed), a potem, korzystając z tego ma wylosować 6 numerków, które możesz obstawić w następnym losowaniu prawdziwego totka.
Poprawne zrozumienie zadania to połowa sukcesu, więc lepiej poświęć na to zawsze te parę minutek :)
Pozdrawiam -
Daniel Fukuda
eee myslalem, ze to zadanko jest bardziej ciekawe... a tutaj taki banal mam zrobic :[
anyway... Wielkie dzieki bo chyba dzis bym tego nie rozkminil :DD -
owczi
...a porządne systemy przy zamykaniu zapisują sobie podstawę generatora; ] -
-
Daniel Fukuda
omfg... napisalem ze proste zadanko a tak nie jest :P
wie ktos moge jak zrobic zeby te liczby wywolywane funkcja random(1, 49) nie powtarzaly sie?:X -
Brut[all]
1. Nie wywalać ich na ekran zaraz po wylosowaniu, a umieszczać w tablicy. Przy losowaniu następnej sprawdzamy, czy liczba nie leży już przypadkiem w tablicy i jeśli tak, losujemy drugi raz.
2. Rozwiązanie trochę bardziej skomplikowane, za to lepsze od strony logiki (w niektórych sytuacjach wręcz konieczne).
Tak samo umieszczamy każdą z liczb w tablicy, ale robimy taki mały numer - przy każdej kolejnej liczbie zmniejszamy górny margines losowania o jeden. Potem inkrementujemy wylosowaną liczbę dla każdej liczby z tablicy, która była równa lub mniejsza tej nowej.
To sprawia, że nie jest możliwe "zacięcie" się programu w przypadku felernych losowań, choć akurat w takim programie nie powinno to być problemem. -
Daniel Fukuda
-
bartkiller
a mógłbyś wyjaśnić zdanie "Potem inkrementujemy wylosowaną liczbę dla każdej liczby z tablicy, która była równa lub mniejsza tej nowej. " ?
(ew. przedstawić ten algorytm inaczej, bo nie zrozumiałem) -
Brut[all]
Tak, wiem, nie napisałem tamtego zrozumiale, bo i się śpieszyłem, a stwierdziłem, że pierwsza metoda w tym przypadku i tak jest lepsza.
Chodziło mi o takie jakby zasymulowanie losowania liczby z "dziurawego" przedziału liczb, czyli np. 1-49 z wyjątkiem 5 i 18.
Gdyby przyrównać to do rzeczywistej sytuacji - zbiornika z numerowanymi kulami - dość logiczne jest, że maszyna losująca wybierałaby już jedną kulę z 47, więc i my tak roibimy - losujemy 1-47.
Teraz oczywiście pozostaje problem tych dziur, a to... ehh.. ciężko mi to wytłumaczyć... dobra, konkretny przykład, bardzo uproszczony.
Mamy tylko 6 kul, przeprowadzamy pierwsze losowanie i wypadła 2.
Teraz zostało już tylko 5 kul, więc z tylu losujemy, ale wyloswany numer niekoniecznie oznacza numer kuli, tzn:
Numer kuli (wylosowana liczba):
1 1
2 X
3 2
4 3
5 4
6 5
Losujemy i wypadła nam liczba 3, czyli kula nr. 4.
W następnym loisowaniu mamy już tylko 4 kule, więc losujemy 1-4, gdzie:
1 1
2 X
3 2
4 X
5 3
6 4
i tak dalej.
Zaletą takiej metody jest to, że nie losujemy w kółko z nadzieją, że kiedyś się wreszcie uda - każde losowanie wybiera nam element z rzeczywistej puli możliwości, a prawidłowy wynik jest obliczany.
A właśnie! Obliczany.
Jak to obliczyć?
Wystarczy wylosowaną wartość zwiększyć o tyle, ile było łącznie wylosowanych już liczb mniejszych od naszej. Jeśli w tym ostatnim przykładzie wypadłaby 3, widać, że ponad nią były 2 X'y, więc jej rzeczywistą wartością jest 3 + 2 = 5.
Patrząc na to od strony gotowego algorytmu, możemy sprawę rozwiązać na dwa sposoby:
1. Jeśli w tablicy będziemy zapisywali rzeczywiste wylosowane liczby, pojawi się mały problem - algorytm zadziała tylko i wyłącznie wtedy, jeśli nasza nowa liczba będzie porównywana z tymi z tablicy koniecznie w kolejności od najmniejszej z nich.
To oznacza przymus sortowania w czasie rzeczywistym wyników - trochę nieciekawie.
2. Możemy też w tablicy zapisywać nie rzeczywiste liczby, a wyniki losowań. Te rzeczywiste będą albo od razu wyrzucane gdzieś na ekran, albo umieszczane w drugiej tablicy.
Rozwiązanie będzie o tyle prostsze, że sortowanie nie będzie konieczne. Musimy porównać nową liczbę ze wszystkimi z tablicy w dowolnej kolejności, ale w tym przypadku liczbę należy zwiększyć dopiero na samym końcu, po wszystkich porównaniach.
Wada oczywista - zazwyczaj zajmie nam to więcej pamięci.
A tak ogólnie co do takiego podejścia do tematu - spróbujcie napisać algorytm, który Wam ustawi w losowej kolejności liczby od 1 do 1000, to zrozumiecie, czemu nie zawsze można stosować metody "losujemy, aż się uda". -
Anonim
-
Kupiś
Zaproponował bym inną metodę - prostszą chyba.
Dla 49 liczb tworzymy tablicę 49-elemntową i każdemu elementowi przypisujemy wartość równą jego indeksowi.
Teraz sam proces losowania - losujemy numer indeksu tablicy (a nie konkretną wylosowaną liczbę) i po każdym losowaniu zmniejszamy górny zakres liczb o 1. Kopiujemy przy tym wartość indeksu opowiadającemu górnemu zakresowi losowań do elementu o indeksie właśnie wybranym.
Dosyć proste i oczywiste to się wydaje i często w literaturze stosowane.
Pozdrawiam.
-
Brut[all]
-
Kupiś
-
Brut[all]
Myślę, że w większości przypadków nie ma sensu wypełniać tych wszystkich pól, gdy możemy np, potrzebować losowania 10 elementów z milionoelementowego zbioru. Hmm.. tablica o milione indeksów... ciężko, ciężko...
Nie musimy nic wypełniać, ale zasada pozostanie dokładnie ta sama - w momencie wylosowania liczby, na jej miejsce wstawiamy ostatni element. Losujemy znów i sprawdzamy, czy wylosowany element leży w tablicy, a jeśli nie, to przyjmujemy taką wartość, jaką liczbę wylosowaliśmy - wstawiamy ostatni element i kontynuujemy.
Różnica jest delikatna, ale znacząca w wydajności:
Jeśli mamy zbiór 100 elementów, to nie robimy nic na początku, od razu losujemy liczbę.
Wylosowaliśmy 56, więc przeszukujemy tablicę, która jest narazie pusta, więc wyrzucamy wynik: 56. Wstawiamy do tablicy pierwszą wartość: 100 pod indeks 56.
Teraz losujemy i 72 - przeszukujemy tablicę, w której takiego indeksu nie znajdujemy, więc wyrzucamy jako wynik 72, wstawiamy do tablicy 99 pod adres 72 i dalej.
Tym razem znów 56, przeszukujemy tablicę, zauważamy, że taki indeks istnieje, więc wyrzucamy 100, a w tablicy podmieniamy wartość na 98.
Jak już pisałem - zasada jest dokładnie ta sama, ale nie wypełniamy zbędnie tablicę wartościami typu:
tabl[34] = 34;
tab[73] = 73;
Wstawiamy tylko to, co zostało już wzięte.
Aha.
Wszystko powyższe straciłoby sens, gdybym czegoś nie dodał - nie mam na myśli tej najprostszej tablicy-tablicy, jaką znamy choćby z C++.
Nie znam Javy, nie wiem jak tam wyglądają tablice, ale spodziewałbym się raczej zbiorników asocjacyjnych - kojarzenia ze sobą kluczy i wartości, a nie fizycznie zadeklarowanego ciągu 50 bajtów w pamięci, także i tych pustych i obliczanie po indeksie konkretnego offsetu.
Jeśli się mylę, od razu zwracam uwagę - tak należy rozumieć te moje tablice, a nawet jeśli te standardowe Javy są tym, co w C++, na pewno istnieją jakieś zbiorniki asocjacyjne w bibliotekach standardowych, więc to nie jest problem. -
Kupiś
(Nie wiem czy do końca ten tok myślenia zrozumiałem) ... Ma to sens, ale zauważ, że chcesz przeszukiwać tablicę za każdym razem. Kwestia teraz kłócić się co ma większe znaczenie - obciążenie pamięci czy procesora, a wydaje mi się, że w chwili obecnej bardzo ciężko ten spór rozstrzygnąć .. a przypadek losowania 10 elementów z miliona też nie jest wart takiego zachodu, tylko zwykłego random, aż się nie uda :D ... podejżewam, że nawet 1000 liczb z miliona pod random spokojnie można podciągnąć, a program będzie się "sypał" raz na 10 lat, choć niekoniecznie.
"Nie znam Javy" - ten kawałek mi się szczególnie podoba :PPP
Są klasy pojemników jak chociaż ArrayList o teoretycznie nieograniczonym rozmiarze i zwiększanym dynamicznie. Zawsze też można pobawić się w jakieś abstrakcyjne stuktury danych :)
Tyle, że takie rozważania raczej już daleko wykraczają poza temat postu =) -
Brut[all]
>Tyle, że takie rozważania raczej już daleko
>wykraczają poza temat postu =)
Przepraszam, lubię teoretyzować :)
Zresztą... naprawdę chciałem skończyć na tamtym pierwszym rozwiązaniu, bo w tym przypadku wydawało się lepsze, tamto drugiego dodałem raczej jako ciekawostkę :) -
Dzemus
>Kupiś napisał
>Są klasy pojemników jak chociaż ArrayList
Ale Brutalowi chodziło o zbiorniki asocjacyjne jak w PHP lub C#... W Javie to jest HashMap.
-
spec
>Kwestia teraz kłócić się co ma
>większe znaczenie - obciążenie pamięci
>czy procesora, a wydaje mi się, że w chwili
wlasnie o to chodzilo. przy hashtable'ach jako ze to jest tablica _haszujaca_ (jak nazwa wskazuje) narzut pamieciowy bedzie zawsze wiekszy (czasem duzo) niz arraylisty, ale odwolujesz sie do tablicy kluczem(co wewnatrz zamieniane jest na hash i indeks do elementu) wiec nie trzeba przeszukiwac calej tablicy
-
spec
- Przeglądaj grona w kategorii Internet i Komputery
- Przeglądaj grona w okolicy Warszawa
- Załóż własne grono tematyczne
- Zostań moderatorem
Podobne Tematy
|
|
Wszystko co związane z programowaniem w Java (J2EE, JSP, JDBC, itd) test
Miejsca grona (1)
-
Kino Luna ul. Marszałkowska, Warszawa
www.kinoluna.pl kino.luna@maxfilm.com.pl 22 621 78 28
- Dodaj miejsce

