当前位置:  开发笔记 > 编程语言 > 正文

生成一系列随机数,在c#中加起来为N

如何解决《生成一系列随机数,在c#中加起来为N》经验,为你挑选了2个好方法。

如何在1-9之间生成30个随机数,在C#中总共加起来200(或任意N)?

我正在尝试生成一串可以加起来为N的数字.



1> Spencer Rupo..:

我不确定这方面的统计数据,但是,这里的问题是你不想随意选择一个数字,这使得无法通过过冲或下冲来将N与M个条目相加.我是这样做的:

static void Main()
{
    int count = 30;
    int[] numbers = getNumbers(count, 155);
    for (int index = 0; index < count; index++)
    {
        Console.Write(numbers[index]);
        if ((index + 1) % 10 == 0)
            Console.WriteLine("");
        else if (index != count - 1)
            Console.Write(",");
    }
    Console.ReadKey();
}
static int[] getNumbers(int count, int total)
{
    const int LOWERBOUND = 1;
    const int UPPERBOUND = 9;

    int[] result = new int[count];
    int currentsum = 0;
    int low, high, calc;

    if((UPPERBOUND * count) < total ||
        (LOWERBOUND * count) > total ||
        UPPERBOUND < LOWERBOUND)
        throw new Exception("Not possible.");

    Random rnd = new Random();

    for (int index = 0; index < count; index++)
    {
        calc = (total - currentsum) - (UPPERBOUND * (count - 1 - index));
        low = calc < LOWERBOUND ? LOWERBOUND : calc;
        calc = (total - currentsum) - (LOWERBOUND * (count - 1 - index));
        high = calc > UPPERBOUND ? UPPERBOUND : calc;

        result[index] = rnd.Next(low, high + 1);

        currentsum += result[index];
    }

    // The tail numbers will tend to drift higher or lower so we should shuffle to compensate somewhat.

    int shuffleCount = rnd.Next(count * 5, count * 10);
    while (shuffleCount-- > 0)
        swap(ref result[rnd.Next(0, count)], ref result[rnd.Next(0, count)]);

    return result;
}
public static void swap(ref int item1, ref int item2)
{
    int temp = item1;
    item1 = item2;
    item2 = temp;
}

我没有太多时间来测试这个如此道歉,如果我的逻辑中有一个缺陷.

编辑:

我做了一些测试,一切看起来都很稳固.如果你想要一个漂亮的漂亮的传播,看起来你想要的东西沿着这条线Total = Count * ((UPPER + LOWER) / 2).虽然我相当肯定,是身份的区别UPPER,并LOWER增加了更灵活的这种变.



2> lc...:

问题是我们希望所有数字都限制在1-9 加起来为N.所以我们必须逐个生成每个数字并确定下一个数字的实际边界.

这当然会在列表末尾产生统计偏差,因此我建议在生成后将数组洗牌一次.

要确定下一个数字的边界,请执行以下操作:上限=取剩余的总和减去(剩余的元素数量*min).下限=取剩余的总和减去(剩余的元素数量*max).

像(未经测试)的东西:

public static List RandomList(int digitMin, int digitMax, 
                                   int targetSum, int numDigits)
{
    List ret = new List(numDigits);

    Random random = new Random();
    int localMin, localMax, nextDigit;
    int remainingSum = targetSum;

    for(int i=1; i<=numDigits; i++)
    {
          localMax = remainingSum - ((numDigits - i) * min);
          if(localMax > max)
              localMax = max;

          localMin = remainingSum - ((length - i) * max);
          if(localMin > min)
              localMin = min;

          nextDigit = random.Next(localMin, localMax);
          ret.Add(nextDigit);
          remainingSum -= nextDigit;
    }

    return ret;
}

这里的想法是在生成数字时,剩余数字的可能值范围变得更小,就像限制函数归零目标总和一样.有点.

编辑:我必须将for循环更改为从1开始,因为我们希望生成此元素后剩余的元素数量.

EDIT2:把它放在一个方法的完整性和改变lengthnumDigits为了便于阅读.

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有