Erlang随机数生成技术咨询:实现每次不同值及交替0/1输出
Hey there! Let's break down your three Erlang questions with practical, straightforward solutions:
1. Can we implement a random number generator that produces different values on each iteration in Erlang?
Absolutely! Erlang has you covered with the rand module (the recommended replacement for the older random module). By default, each Erlang process automatically initializes a unique random seed the first time you call a rand function, so subsequent calls will generate distinct values as long as you don't manually reset the seed to the same value.
Here's a quick example of a loop that generates unique random numbers each iteration:
generate_unique_rands(0) -> ok; generate_unique_rands(N) -> % Generate a random number between 1 and 100 io:format("Random value: ~p~n", [rand:uniform(100)]), generate_unique_rands(N - 1).
When you run generate_unique_rands(5), you'll get 5 different random numbers (there's an extremely tiny chance of collision, but that's inherent to randomness, not Erlang's implementation).
2. How to generate 0 or 1, since rand:uniform(2) outputs 1 or 2?
This is a simple tweak! Just subtract 1 from the result of rand:uniform(2). Since rand:uniform(2) returns either 1 or 2, subtracting 1 gives you exactly 0 or 1.
Here's a reusable function for this:
zero_or_one() -> rand:uniform(2) - 1.
Test it out—calling zero_or_one() repeatedly will return random 0s and 1s, perfectly matching your need.
3. Can we implement a generator that alternates between 0 and 1 (no consecutive 0s or 1s)?
Yes, but this requires keeping track of the last value we output—since we need to ensure the next value is the opposite. In Erlang, the most idiomatic way to maintain state like this is using a process to hold the current state.
Here's a simple implementation using a dedicated process:
% Start the alternator process (initializes with last value 0, so first output is 1) start_alternator() -> spawn(fun() -> alternator_loop(0) end). % Internal loop that maintains the last output value alternator_loop(LastValue) -> receive {get_value, CallerPid} -> NextValue = 1 - LastValue, % Flip the value CallerPid ! {alternator_result, NextValue}, alternator_loop(NextValue) end. % Function to get the next alternating value get_alternating_value(AlternatorPid) -> AlternatorPid ! {get_value, self()}, receive {alternator_result, Val} -> Val end.
How to use it:
- Start the process:
Pid = start_alternator(). - Get values repeatedly:
get_alternating_value(Pid). % Returns 1 get_alternating_value(Pid). % Returns 0 get_alternating_value(Pid). % Returns 1
This guarantees no consecutive duplicates—each call will always return the opposite of the previous one.
内容的提问来源于stack exchange,提问作者Kiros

