排序大小的功能问题

时间:2019-06-26 15:56:26

标签: c#

因此,我正在编写一个小型c#控制台应用程序,该应用程序应模仿各种购物系统。 所有产品均以包装出售(不是单独出售),包装尺寸为4件,10件或15件。

鉴于数量为28,它应该返回类似以下内容的结果: 2 x 10包+ 2 x 4包。 或给定的Qty大小为25,则应返回类似以下内容的结果: 1 x 15包+1 x 10包 而且该功能必须高效,因此它返回的包装数量最少。 (显然,请忽略Scenerio的数量可能是3的数量-因为没有那么小的包装尺寸)

这是我目前的代码:
数量= 28,LargePack = 15,MediumPack = 10,SmallPack = 4

            double total = 0.00;
            int tmpQty = qty;

            while (tmpQty != 0)
            {
                if ((tmpQty >= LargePack) && ((tmpQty % LargePack) % 1) == 0)
                {
                    tmpQty -= LargePack;
                    lg += 1;
                    total =+ (lg * LargePrice);
                }
                else if ((tmpQty >= MediumPack)) 
                {
                    tmpQty -= MediumPack;
                    md += 1;
                    total =+ (md * MediumPrice);
                }
                else if ((SmallPack !=0) && (tmpQty >= SmallPack) && (tmpQty < MediumPack))
                {
                    tmpQty -= SmallPack;
                    sm += 1;
                    total =+ (sm * SmallPrice);
                }
            }

我的想法是-因为数量大约为28,我需要它跳过第一个IF语句,所以我想检查一下tmpQty(28)/ LargePack(15)是否为整数-它不应该,那么它将转到第二个IF语句。但是由于某种原因,公式:

(tmpQty % LargePack) %1 == 0

始终等于0-因此当它为假时为True。

或者,如果有人有更好的方法来计算包装尺寸,我欢迎您提出建议。 注意-此处未定义包装尺寸,因为各种不同的产品使用相同的分类过程。

4 个答案:

答案 0 :(得分:1)

您最大的问题是您不知道%做什么。它不返回小数。它的工作方式类似于小学部的“剩余部分”。 7%5将返回2。如果要保持相同的逻辑(期望一个百分比),则需要除法,但变量必须是double或float。如果不是,则C#将结果转换为没有小数的整数。希望对您有所帮助。

答案 1 :(得分:0)

(任何%1)始终返回0。这就是为什么您的条件不起作用的原因。

尝试一下

(tmpQty % LargePack) >= 0 

答案 2 :(得分:0)

使用:

if ((tmpQty >= LargePack) && ((tmpQty % LargePack) == 0))

这仅对于完全被LargePack整除的值返回true,因此在这种情况下28将失败并继续。

答案 3 :(得分:0)

这是一种蛮力方法。首先,我们需要一种方法来生成序列数组的所有组合。它称为CartesianProduct,实现如下所示:

public static IEnumerable<T[]> CartesianProduct<T>(IEnumerable<T>[] sequences)
{
    IEnumerable<IEnumerable<T>> seed = new[] { new T[0] };
    return sequences.Aggregate(
        seed,
        (accumulator, sequence) => accumulator
            .SelectMany(_ => sequence, (product, i) => product.Append(i))
    ).Select(product => product.ToArray());
}

我们将需要此方法,因为我们需要包装尺寸和数量的所有可能组合。例如,对于包装大小[5、8]和数量21的包装,我们要生产的组合如下:

0*5 + 0*8 = 0
0*5 + 1*8 = 8
0*5 + 2*8 = 16
1*5 + 0*8 = 5
1*5 + 1*8 = 13
1*5 + 2*8 = 21
2*5 + 0*8 = 10
2*5 + 1*8 = 18
2*5 + 2*8 = 26
3*5 + 0*8 = 15
3*5 + 1*8 = 23
3*5 + 2*8 = 31
4*5 + 0*8 = 20
4*5 + 1*8 = 28
4*5 + 2*8 = 36

最后一步是选择最佳组合。这是使所有这些事情发生的方法:

private static (int PackSize, int Quantity)[] GetBestCombination(
    int[] packSizes, int quantity)
{
    var sequences = packSizes
        .Select(p => Enumerable.Range(0, (quantity / p) + 1)
            .Select(q => p * q))
        .ToArray();
    var cartesianProduct = CartesianProduct(sequences);
    int[] selected = null;
    int maxValue = Int32.MinValue;
    foreach (var combination in cartesianProduct)
    {
        int sum = combination.Sum();
        if (sum > quantity) continue;
        if (sum > maxValue)
        {
            maxValue = sum;
            selected = combination;
        }
    }
    if (selected == null) return null;
    return selected.Zip(packSizes, (sum, p) => (p, sum / p)).ToArray();
}

让我们测试一下:

var bestCombo = GetBestCombination(new[] { 5, 8 }, 21);
foreach (var pair in bestCombo)
{
    Console.WriteLine($"{pair.Quantity} x {pair.PackSize}");
}

输出:

  

1 x 5
  2 x 8