Trodde att jag var bra men det blir inte som jag tänkt: Du har en implicit cast från double till integer, vilket innebär en avrundning. Tack... Tänk igenom: hur ska "rnd()" veta att du inte vill ha samma tal? När jag jobbade så hade vi en loop, om det var samma nummer som tidigare Inte speciellt fult. Ett enkelt Lotto slump du kan studera. Hej Sven-Åke Nja. "X"? <b>Nja. "X"? Sen skulle det vara intressant att läsa om på vilket sätt Jag orkar inte läsa exakt vad du klagar på med mina förslag, men det ser inte ut som att du förstår hur jag menar. Jag kan ju beskriva dem lite tydligare: Som vanligt ! Kvalificerat djä.. trams ! <b>ag orkar inte läsa exakt vad du klagar på med mina förslag</b> "Skriv många programrader så får du mer betalt" Kvalificerat djä... trams detta funkar klart inte utan en massa mer programrader. Roade mig med att Slumpa ut 10000 Postnummer utan dubbletter. Tråkigt att du inte kan ta konstruktiv kritik. <b>Prova gärna att ta ut 89999 personnummer istället.</b> Ajdå, miss, 89999 postnummer menade jag förstås. Alltså, exakt samma förutsättningar som du skrev ovan, men du vill ha ut lite fler, alla unika. Hur lång tid tar det nu att köra det? Nyfiken som jag är så testade jag naturligtvis. I mitt gamla tips [Slumpa och sortera (ett snabbare sätt)] har jag en funktion för att returnera en array med slumptal gjord så att arrayen bara behöver loopas igenom en gång. Se funktionen GetRandomArray och hur den anropas från main(). Intressant att läsa. Alltså, du måste kolla på algoritmisk komplexitet. Öka från 1 till max och kolla hur tiden ändras. Det kommer gå kvadratiskt istället för linjärt.slumpgenerator "VB 6"
Skriver jag in ex 35 kan tal 36 komma upp
sen verkar det bli dubblett ibland
Tanken är att inget nummer över det man skriver in och inga dubbletter.
"har nog solen i ögat :-)"
Private Sub CmdNr_Click()
Dim MyNumber As Integer
Randomize
MyNumber = (Text2.Text * Rnd) + 1 'I Text2 skriver jag in den siffra som inte ska överstigas
Label2.Caption = ("Vinstnummer ") & MyNumber ' I Label2 visas resultat
End SubSv: slumpgenerator "VB 6"
Ändra till en explicit cast så här:
MyNumber = Int(Text2.Text * Rnd) + 1
Vad menar du med dubletter?
Sv:slumpgenerator "VB 6"
Ex: Det kan komma upp nr 3 sen andra nummer sen kan 3 komma tillbaka igen
Inga nummer ska komma tillbaka som har varit uppe.
Tror jag förklarat förståligt!
SJSv: slumpgenerator "VB 6"
(det ska och kan den inte)
Alltså måste du göra det själv.Sv: slumpgenerator "VB 6"
så fick den gå igenom Random en gång till, en ful lösning men som funkade. :-) ;-)Sv:slumpgenerator "VB 6"
Jag lägger upp en ArrayNr(36)
Kör en loop tills jag fått det antal unika random jag önskar.
För varje nr 1-35 som kommer upp sätter jag ett kryss i ArrayNr(rnd())
Kollar med en If-sats om ArrayNr(nr) är X:at om inte godtar, annars kör ett nytt varv i loopen.
för att markera att detta nr är upptaget.
Ungefär så.
Rensa Arrayen och börja om på nytt.Sv: slumpgenerator "VB 6"
<code>
Option Explicit
Private Sub Command1_Click()
Randomize
Label1.Caption = ""
Dim ArrayNr(36) As String 'ArrayNr(0) används inte
Dim i As Long, newNr As Long
i = 1
Do Until i > 7 'Lottorad
newNr = Int(Rnd * 35) + 1 ' slumpar från 1-35
If ArrayNr(newNr) <> "X" Then
Label1.Caption = Label1.Caption & newNr & " "
ArrayNr(newNr) = "X"
i = i + 1
End If
Loop
'Erase ArrayNr() ' Töm Arrayen ifall du kör i Global miljö
End Sub
</code>Sv:slumpgenerator "VB 6"
Det var en intressant kod du snickrade ihop.
Den tar jag och modifierar lite, den verkar mer hållbar.
Tack för iden.
SJSv:slumpgenerator "VB 6"
Bool-array, bool-hashtabell eller lista med redan använda, är väl lite lämpligare. (vilken beror på situation).
En annan trevligare och tydligare variant är att istället slumpa en full lista.Sv: slumpgenerator "VB 6"
Bool-array, bool-hashtabell eller lista med redan använda, är väl lite lämpligare.</b>
LOL Can´t win them all :-)
Alltid lika roligt att läsa vad de sk. proffstyckarna har för åsikter.
<b>lista med redan använda</b>
Ja just det, ArrayNr är en sådan lista.
Ok han skriver att han skall modifiera då kan han ju "modda" "X" till Boolean .No big deal :-)
När jag snodde ihop detta lilla exempel tyckte jag att
det fanns en pedagogisk knorr i att använda "X" för att markera upptaget.
<b>En annan trevligare och tydligare variant är att istället slumpa en full lista.</b>
Vad är det för "bullshit" varför visa något på en lista(dubbletter) som ändå inte skall användas !???Sv:slumpgenerator "VB 6"
Niklas förslag skulle optimera Slumpgeneratorn när den skall presentera
ett givet antal Nr ur ett givet antal möjligheter tex 1-70 (Keno) utan att visa dubbletter.
Sen kan man snygga till dom dragna talen ytterliggare genom att lägga dom i en Array
och sortera dom med den gamla algoritmen QuickSort innan man visar dom för användaren.Sv: slumpgenerator "VB 6"
1. Bool-array. Lika lång som maximala mängden värden, indexera in i tabellen för att säga om den är använd sen innan, i praktiken den du använder. Dåligt om man har väldigt stor range, tar mycket minne, meck i kombination med virtuellt minne. Bra om man bara ska ta ut några få värden.
2. Hashtabell. Samma princip som bool-array, men man beräknar hash istället. Löser problemet med att den tar mycket minne.
3. Lista med redan använda (detta är alltså inte samma som en bool-array, nej). Lägg till ett nytt tal till en lista, och jämför mot den. Typ:
until list.count>5
val = getrandom()
if not list.contains(val)
list.add(val)
end if
loop
elegant, lämplig vid relativt få val. En variant av detta är att använda ett set:
until set.count>5
set.add(getrandom())
loop
Mycket elegant.
4. "Full lista". Skapa upp alla tillgängliga värden, ta så många man vill ha:
list = GetAllValues()
rlist = randomizeList(list)
values = rlist.Get(5)
Också elegant, definitivt att föredra om man har några stycken och ska ha en stor andel av dem.Sv:slumpgenerator "VB 6"
En djä... massa "bullshit"
"Skriv många programrader så får du mer betalt" Phuuuuuuuuuuuuuuuuuuuuu.
"Spela mer marig och kunnig. Kvalificerat "Bull"
<b>"Mycket skrik för lite ull sa kärringen när hon klippte grisen"</b>
Funkar mitt exempel eller funkar det inte ???
Och !? sista frågan Löste Vi problemmet ????????????????????
Jag löste det med yxa och hyvel och det kommer alltid att funka.Sv: slumpgenerator "VB 6"
Så typiskt för Er yngre. Ni orkar inte läsa "plain" svenska.
Ok skall förtydliga mig. Det mesta du anförde var kvalificerat "bull"Sv: slumpgenerator "VB 6"
Operativ kod:
<code>
until set.count>5
set.add(getrandom())
loop
</code>
<code>
Do Until i > 7 'Lottorad
newNr = Int(Rnd * 35) + 1 ' slumpar från 1-35
If ArrayNr(newNr) <> "X" Then
Label1.Caption = Label1.Caption & newNr & " "
ArrayNr(newNr) = "X"
i = i + 1
End If
Loop
</code>
Vilken har flest programrader?
En gissning är att det snarare är du som inte har läst igenom (alt. förstått) mina förslag. Det jag säger är att det finns ett antal lösningar med olika egenskaper. Om vi bortser ifrån att den lösningen du har som förslag bör modulariseras och bli lite tydligare, så är den lämplig i vissa specialfall. Oftast inte. Prova att öka både 7 och 35 till 10000 och kolla vad du får för beteende på den.
Eller att behålla 7 men öka 35 till några miljarder (långt ifrån en orimlig situation).
I de två fallen, "nej vi löste inte problemet", och det kommer inte alltid att funka.Sv:slumpgenerator "VB 6"
<code>
Private Sub Command1_Click()
until set.count>5
set.add(getrandom())
Loop
</code>Sv: slumpgenerator "VB 6"
bara för att få koll på snabbheten och effektiviteten. Snitt 100 ms
<code>
Option Explicit
' 1 Command Button
'1 Listbox
Private Sub Command1_Click()
Randomize
'List1.Sorted = True
List1.Visible = False
Dim ArrayNr(99999) As Boolean 'ArrayNr(0) används inte
Dim PnrArray(99999) As Long
Dim i As Long, newNr As Long
Dim start As Single, fini As Single
start = Timer
i = 1
Do Until i > 10000
newNr = Int(Rnd * 99999) + 1 ' slumpar från 1-99999
If ArrayNr(newNr) = False And newNr > 10000 Then
List1.AddItem newNr
' PnrArray(newNr) = newNr 'Lagra 10000 postNr utan dubbletter
ArrayNr(newNr) = True
i = i + 1
End If
Loop
fini = Timer
MsgBox fini - start
List1.Visible = True
'Erase ArrayNr() ' Töm Arrayen ifall du kör i Global miljö
'Skriv ut PnrArray på lämpligt sätt 10000 nr sorterade
End Sub
</code>Sv:slumpgenerator "VB 6"
Prova gärna att ta ut 89999 personnummer istället.
Angående antal programrader. Nej, jag tog ju bort alla initieringar, precis som jag gjorde med din för att jämförelsen skulle bli rättvis...
Men visst, du kan få fullständiga koden istället:
set<int> GetRandomNumbers(int count, int min, int max){
set<int> s;
while(s.count<count)
s.insert(rand()*1.0/RAND_MAX*(max-min) + min);
return s;
}Sv: slumpgenerator "VB 6"
Det är ju ett helt annat concept.
Där måste man ju slumpa år mån dag var för sig och tillsammans tillåta dubbletter.
Sen måste man slumpa de 4 sista och kontrollera att kontrollsiffran stämmer.
Om behov finnes kan jag klart skruva ihop ett sådant program.
Med samma teknik som jag användt tidigare.
Kan inte provköra din kod eftersom det inte är VB6 kod.
Om du inte har koll så kan jag upplysa om att detta är ett VB 6 forum.Sv:slumpgenerator "VB 6"
Sv: slumpgenerator "VB 6"
89999 Unika Postnr. Om jag lagrar i en PnrArray(99999) så tog det 300 ms
I en ListBox Sorterad och Visible = False - Visible = True tog det 8 sek.
Helt godkänt tycker jag.Sv:slumpgenerator "VB 6"
Sv: slumpgenerator "VB 6"
Många programrader blir det.
Jag gör det lätt för mig och sorterar med en ListBox.Visible = False
Kör loopen och sedan ListBox.Visible = True 89999 nr tog då 8 sek
Det kan jag stå ut med.
Skall med intresse kör din kod.
Den kan man ha mycket nytta av i andra sammanhangSv:slumpgenerator "VB 6"