C# 如何将一个数字分成多个部分,使结果和等于输入值?

C# 如何将一个数字分成多个部分,使结果和等于输入值?,c#,C#,我试图将一个数字分成多个部分,这样部分的总和就等于输入的数字 如果我有3.99,如果我需要分成两部分,预期输出是2和1.99(2+1.99=3.99) 如果我需要将3.99分为3部分,预期输出是1.3、1.3和1.39(1.3+1.3+1.39=3.99) 对于第一个示例,我能够输出2.99和1,对于第二个示例,我能够得到1.99、1和1。然而,在这两种情况下,结果与预期产出相差甚远 我需要把邮费分成不同的项目。结果可以等分或不等分,同时确保不同部分的总和等于输入数 以下是一些其他示例: 3.9

我试图将一个数字分成多个部分,这样部分的总和就等于输入的数字

如果我有3.99,如果我需要分成两部分,预期输出是2和1.99(2+1.99=3.99)

如果我需要将3.99分为3部分,预期输出是1.3、1.3和1.39(1.3+1.3+1.39=3.99)

对于第一个示例,我能够输出2.99和1,对于第二个示例,我能够得到1.99、1和1。然而,在这两种情况下,结果与预期产出相差甚远

我需要把邮费分成不同的项目。结果可以等分或不等分,同时确保不同部分的总和等于输入数

以下是一些其他示例:

3.99 divided in 3 parts: 1.33, 1.33, 1.33
3.98 divided in 3 parts: 1.33, 1.33, 1.32
3.97 divided in 3 parts: 1.32, 1.32, 1.33
3.96 divided in 3 parts: 1.32, 1.32, 1.32
3.95 divided in 3 parts: 1.32, 1.32, 1.31

我使用您提供的值进行了测试。可能需要一些调整:

static IEnumerable<decimal> SplitValue2(decimal value, int count)
{
    if (count <= 0) throw new ArgumentException("count must be greater than zero.", "count");
    var result = new decimal[count];

    decimal runningTotal = 0M;
    for (int i = 0; i < count; i++)
    {
        var remainder = value - runningTotal;
        var share = remainder > 0M ? Math.Max(Math.Round(remainder / ((decimal)(count - i)), 2), .01M) : 0M;
        result[i] = share;
        runningTotal += share;
    }

    if (runningTotal < value) result[count - 1] += value - runningTotal;

    return result;
}
静态IEnumerable SplitValue2(十进制值,整数计数)
{
如果(计数0M?数学最大值(数学四舍五入(余数/(十进制)(计数-i)),2),.01M):0M;
结果[i]=股份;
runningTotal+=股份;
}
如果(runningTotal<值)结果[计数-1]+=值-runningTotal;
返回结果;
}

这假设您传入一个精度为2位小数的值。如果传入3.999,您将无法得到正确的结果。

如果有人打算使用扩展方法拆分成四舍五入的数字,可以通过执行以下操作来完成。例如,将25拆分为4将得到类似于6,6,6,7的结果。谢谢@Jon B

 public static IEnumerable<int> PartitionMeInto(this int value, int count)
    {
        if (count <= 0) throw new ArgumentException("count must be greater than zero.", "count");
        var result = new int[count];

        int runningTotal = 0;
        for (int i = 0; i < count; i++)
        {
            var remainder = value - runningTotal;
            var share = remainder > 0 ? remainder / (count - i) : 0;
            result[i] = share;
            runningTotal += share;
        }

        if (runningTotal < value) result[count - 1] += value - runningTotal;

        return result;
    }

我有一个要求,其中ex:29的数字被划分为一个常量数组,余数必须追加到最后

29=9,9,9,3。对于这个,我的代码是

       List<int> split(int num,int splitBy)
           {

               List<int> r = new List<int>();
               int v = Convert.ToInt32(num / splitBy);
               r.AddRange(Enumerable.Repeat(splitBy, v).ToArray());
               var remaining = num % splitBy;
               if (remaining != 0)
                   r.Add(remaining);
               return r;

           }
列表拆分(int num,int splitBy)
{
列表r=新列表();
int v=转换为32(num/splitBy);
r、 AddRange(可枚举的.Repeat(splitBy,v.ToArray());
剩余var=数量%splitBy;
如果(剩余!=0)
r、 增加(剩余);
返回r;
}

快乐编码!!!

为什么3.99分成3部分不改为1.33、1.33、1.33?“但在这两种情况下,结果都与预期的输出相差甚远”--变化如何?你尝试了什么?预期的结果是什么?@Naresh为什么不
1.32,1.32,1.33
?我认为这是一个非常好的问题,只是没有表达得非常清楚。我认为Naresh想做的类似于在餐厅分摊账单。你想平均分摊价值,但不能收取低于一个0.01——因此在某些情况下,一个人的收费比其他人高/低0.01。@纳雷什你的例子现在清楚多了,但是你的
3.95
3.98
例子不一致——一个你有
x,x,x+0.02
,另一个你有
x,x+0.01,x+0.01
。有什么理由对它们区别对待吗例如,您更喜欢“偶数”数字?如果您愿意,可以使用
(decimal.GetBits(value)[3]>>16)%256
获取输入小数点中指定的小数位数。这对
计数
>3不起作用;例如
0.03
5
之间拆分会得到
.01.01.01-.01
而不是
.01.01.01 0
@Rawling好的结果。这有点边缘问题,但我可以解决。快做吧,因为我在发帖g如果重新打开,我自己的版本:p可能负数部分是一个糟糕的例子;这仍然保存了最后一个数字的所有“差异”,例如
(1.03M,5)
给出
.21.21.21.19
,而不是
.21.21.20
       List<int> split(int num,int splitBy)
           {

               List<int> r = new List<int>();
               int v = Convert.ToInt32(num / splitBy);
               r.AddRange(Enumerable.Repeat(splitBy, v).ToArray());
               var remaining = num % splitBy;
               if (remaining != 0)
                   r.Add(remaining);
               return r;

           }