因此,我正在编写一个小型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。
或者,如果有人有更好的方法来计算包装尺寸,我欢迎您提出建议。 注意-此处未定义包装尺寸,因为各种不同的产品使用相同的分类过程。
答案 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