关于c#:带有随机数的平面轮盘:获取随机所属的间隔

Flat Roulette with random number: get interval where random belongs to

例如,我有一个包含这些元素的数组:

1
0 21 29 0 0 50

让我们"平"这个数字:

enter image description here

假设我的随机数是54,所以我的数字属于索引为6(50)的数组中的最后一个元素。

我不明白,怎么把它演算法化…用C

我尝试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  Random random = new Random();
            int randomNumber = random.Next(1, 100);
            int temp, temp_ind;
            float a_, b_;
            for (j = 0; j < n-1; j++)
            {
                if (roulette[j] != 0)
                {
                    temp_ind = j+1;
                    a_ = roulette[j];
                    while ((roulette[temp_ind] == 0.0) && (temp_ind < n-1))
                    {
                        temp_ind++;
                    }
                    b_ = roulette[temp_ind];
                    if ((a_ <= randomNumber) && (b_ >= randomNumber))
                    {
                        start = j;
                        break;
                    }
                }
            }

但这不管用,也许有什么能帮助我?


下面是一个将数组转换为累积数组的解决方案(使用Eric Lippert提供的此答案的扩展方法),然后找到该数组中第一个匹配项的索引,该索引高于随机数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Program
{
    static void Main(string[] args)
    {
        var random = new Random();
        int[] roulette = { 0, 21, 29, 0, 50 };

        var cumulated = roulette.CumulativeSum().Select((i, index) => new { i, index });
        var randomNumber = random.Next(0, 100);
        var matchIndex = cumulated.First(j => j.i > randomNumber).index;

        Console.WriteLine(roulette[matchIndex]);
    }
}

public static class SumExtensions
{
    public static IEnumerable<int> CumulativeSum(this IEnumerable<int> sequence)
    {
        int sum = 0;
        foreach (var item in sequence)
        {
            sum += item;
            yield return sum;
        }
    }
}


你的变量太多了,太复杂了。除了计数器和数字之外,您只需要一个额外的变量来跟踪最近的较小数字。

下面是我写的一些代码,它基本上有相同的想法,只是看起来有点简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int[] roulette = {0, 21, 29, 0, 0, 50};
int closest = -1;
int number = 54;
for (int j = 0; j < roulette.Length; j++)
   // if the values isn't 0 and it's smaller
   // and we haven't found a smaller one yet, or this one's closer
   if (roulette[j] != 0 && roulette[j] < number &&
       (closest == -1 || roulette[j] > roulette[closest]))
   {
      closest = j;
   }

if (closest == -1) // no smaller number found
   Console.WriteLine(0);
else
   Console.WriteLine(roulette[closest]);

现场演示。

对于重复的查询,最好对数字进行排序,然后进行二进制搜索以找到正确的位置。