12 svar
119 visningar
a.carnosa behöver inte mer hjälp
a.carnosa 36
Postad: 9 sep 2022 15:50

Slumpa int från givet set

Hej!

När man slumpar en int inom ett intervall använder jag mig av rand()% x + y.

Nu skulle vilja slumpa från ett givet mönster inom bestämt intervall. Exempelvis om jag har ett intervallet 0-100 men jag vill endast att slumptalet ska vara var femte tal. Dvs. 5, 10, 15 20 osv.

Hur ska jag tänka då?

Jag har nu fått till det på detta sätt:

srand(time(0));

int tal = rand() % (10 + 1) * 3;

while (tal == 0)
{tal = rand() % (10 + 1) * 3;}

printf("%d", tal);

Här ska alltså printas ett slumpmässigt genererat tal mellan 3 och 30 med ett hopp på +3 för varje accepterat tal. Jag har lagt till while-satsen för att undvika 0 som alternativ. Kan detta kanske fixas på annat sätt?

Väldigt tacksam för input på hur man kan tänka!

Fermatrix 7841 – Fd. Medlem
Postad: 9 sep 2022 16:32

Finns nog något finare sätt att göra det på men eftersom vi pratar småtal så behövs ingen exceptionell lösning. 

för att slumpa mellan 1-100 där alla tal är delbara med 5.

Se till att talet är sådant att talet%5 == 0. Nu behöver du bara se till att random är från 1-100. 

Kommer du vidare? 

Laguna Online 30472
Postad: 9 sep 2022 18:16

I stället för att loopa med modulo N tills man inte får 0 så kan du ta modulo N-1 och lägga till 1.

a.carnosa 36
Postad: 9 sep 2022 18:21
Dracaena skrev:

Finns nog något finare sätt att göra det på men eftersom vi pratar småtal så behövs ingen exceptionell lösning. 

för att slumpa mellan 1-100 där alla tal är delbara med 5.

Se till att talet är sådant att talet%5 == 0. Nu behöver du bara se till att random är från 1-100. 

Kommer du vidare? 

Som jag förstår det när du förklarar så har jag gjort om koden:

int tal = 0;
do {
tal = rand() % 28 + 3;
} while (tal % 3 != 0);
printf("%d", tal);

Vid mönster med konstant lika hopp lär man ju då bara kunna ändra på den fetmarkerade 3:an till vad som passar. 
För att undvika att 0 blir med i intervallet måste man väl nästan göra på det här sättet.

I lösningsförslag på den uppgiften jag har försökt lösa ovan stod endast int tal = rand() % (10 + 1) * 3; där alternativen skulle vara 3, 6, 9, 12, 15, 18, 21, 24,  27 och 30.  Då borde ju det inte riktigt stämma?

a.carnosa 36
Postad: 9 sep 2022 18:24
Laguna skrev:

I stället för att loopa med modulo N tills man inte får 0 så kan du ta modulo N-1 och lägga till 1.

Här förstår jag nog inte riktigt hur du menar. 

Laguna Online 30472
Postad: 9 sep 2022 18:27

(rand()%10 + 1)*3

a.carnosa 36
Postad: 9 sep 2022 18:47
Laguna skrev:

(rand()%10 + 1)*3

Detta är  ett annat exempel vi fick:

3, 5, 7, 9, 11, 13, 15, 17, 19
printf(”%d”, (rand()%9+1)*2+1

När jag tänker så ser jag (rand()%9+1) först. Alltså ett intervall från 1 -->9.
Hela intervallet multipliceras med 2. Dvs. 1*2 --> 9*2. som blir 2-->18. På detta adderas sedan 1 i både nedre och övre gräns. 2+1-->18+1, dvs. 3-->19.

Är det då *2 (eller *x i andra exempel) som avgör hur stora hoppen är?

Är man helt ute och cyklar eller verkar detta stämma något?

Laguna Online 30472
Postad: 9 sep 2022 18:59

Ofta går det lätt att få talen till ett intervall som funkar med rand()%nånting.

Vi har en följd av udda tal. Först vill vi få ner hoppen till 1. Om vi delar med 2 blir det inte heltal, så vi drar bort 1 först: 2,4,6,...,18

Nu kan vi dela med 2: 1,2,3,...9

rand modulo nånting börjar på 0, så vi drar bort 1 så vår följd börjar med 0: 0,1,2,...,8

Nu har vi nåt vi kan få direkt med rand():

rand()%9

Nu gör vi alla stegen i omvänd ordning: (((rand()%9)+1)*2)+1

Man kan så klart förenkla uttrycket nu om man vill.

a.carnosa 36
Postad: 9 sep 2022 19:19

Okej får se om jag fattat.

0m man nu skulle ha talen 5, 10, 15, 20, 25 30.

rand()% som start.

1. Vi ser att hoppen är på 5. Vi tar bort 5 --> 0, 5, 10, 15, 20, 25

2. Vi kan nu dividera med 5 för att få --> 0, 1, 2, 3, 4, 5

3. När man sedan får ihop detta:

rand()%(eftersom räkningen börjar på 0 adderas inget här)

(rand()%5)*5 (eftersom vi dividerat med 5)

(rand()%5)*5 + 5 (eftersom vi drog bort 5)

När jag testkör denna får jag dock inte med 30. Kan du se vad som felar?

Laguna Online 30472
Postad: 9 sep 2022 19:21

Eftersom det är sex tal får du ta rand()%6.

a.carnosa 36
Postad: 9 sep 2022 19:31

Ja nu tror jag att jag hänger med! 

4, 8, 12, 16, 20, 24, 28

Skulle alltså ge: 

-4 --> 0 4 8 12 16 20 24
/4 --> 0 1 2 3 4 5 6

(rand()%7)* 4 + 4

Laguna Online 30472
Postad: 9 sep 2022 19:34

Just det.

a.carnosa 36
Postad: 9 sep 2022 19:39
Laguna skrev:

Just det.

Tusen tack!!

Svara
Close