这是一位面试官提出的问题。我无法回答。
问题是,假设您想从给定数组中选择一个随机数。
条件是您不应该按顺序选择任何东西,也不应该使用内置的 Random 函数。
我不知道。想知道这个 Math.Random 对我们有什么作用?
我用谷歌搜索并没有找到其背后的实现/逻辑。
有谁知道吗?
到目前为止,三个人已经告诉你使用最后一位数字。这行不通。尝试在一个紧密的循环中这样做,您很快就会明白为什么这是一个坏主意。
这个问题不是很好提出的。我喜欢在面试中提出模棱两可的问题,因为你可以了解候选人如何处理模棱两可的情况。在这种情况下,我会立即反击并找出面试官所说的“随机”是什么意思。伪随机性是否足够好?是否有可用的高质量熵源?
一旦你有一个明确的问题,它应该更容易回答。
问题归结为管理熵。如果你有一个非常弱的熵源——比如 Ticks 的值(不是最后一个数字,它毫无价值,而是整个值),那么你可以使用它来播种伪随机数生成器。如果您有高质量的熵源,那么您可以直接使用它来生成随机位。
保证随机。(舌头紧贴脸颊):
void Main()
{
Enumerable.Range(0, 10).Select(x => ComeOnItsKindaRandom(0, 10)).Dump();
}
public int ComeOnItsKindaRandom(int minValue, int maxValue)
{
var query = "http://www.random.org/integers/?num=1&min={0}&max={1}&col=1&base=10&format=plain&rnd=new";
var request = WebRequest.Create(string.Format(query, minValue, maxValue));
var response = request.GetResponse();
using(var sr = new StreamReader(response.GetResponseStream()))
{
var body = sr.ReadToEnd().Trim();
return int.Parse(body);
}
}
如果您只想从数组中获取一项Random
,而不使用类,则可以使用modulo
具有未知值的函数,例如DateTime.Now.Ticks
:
string[] items = new[] { "1", "2", "3", "4", "5" };
// Modulo items.Lenth returns a value from 0 to Length - 1
int index = (int)(DateTime.Now.Ticks % items.Length);
Console.WriteLine(items[index]);
我会用
DateTime.Now.Tick
然后为 Math.Random(10) 取足够的数字,我只取最后两个数字。
或者你可以像下面这样取这个刻度的模数:
public static class MyMath
{
private static int counter = 1;
public static int Random(int max)
{
counter++;
long ticks = DateTime.Now.Ticks;
int result = Math.Abs((int) (ticks/counter)%max);
return result;
}
}
请参阅以下测试:
[Test]
public void test()
{
List<int> test = new List<int>();
for (int i = 0; i < 10; i++)
{
test.Add(MyMath.Random(100));
}
Console.WriteLine("result:");
foreach (int i in test)
{
Console.WriteLine();
}
}
这是 C 中随机数的实现。您可以尝试用 C# 重写它。
C 的随机数:终于结束了? http://www.cse.yorku.ca/~oz/marsaglia-rng.html
它似乎质量非常高。
但是在面试中编写这段代码并不容易,但你绝对可以告诉他使用的想法。
只是一个想法,您可以使用最后一位数字DateTime.Now.Ticks
来获得选择索引的基础。或者也许是同一件事上的一些哈希函数。或者使用可以为您提供从辐射测量的随机数的网络服务。Math.Random
只是从预定义的表中挑选(是的,它确实不是随机的)。
首先,它被称为伪随机而不仅仅是随机,因为随机序列不可能以计算形式生成,
大多数伪随机数生成器 PRNG 都采用这种形式:
在时间 0:R(0) = 随机(种子)
在时间 i:R(i) = Random(R(i-1));
其次,随机并不意味着您不知道第 i 个结果会是什么,而是该系列是稳健的,并且很难猜测给定结果链的公式或种子
希望这可以帮助
我想他们只是想看看你是否了解LCG(线性同余生成器)算法。
然而,他们背后的数学有点棘手,所以我怀疑他们是否能指望你能在脑海中写下一个。
但是如果做不到这一点,你就不能像这样作弊来生成一个随机索引吗?
int index = Guid.NewGuid().GetHashCode() % array.Length;