我有一个函数(f)获取多个项目(n)和多个列(c)并返回最佳布局作为每列的项目数组。我将最佳定义为尽可能正方形。因此f(4,4)将返回[4,4,4,4],f(17,4)将返回[5,4,4,4],而f(1,4)将返回[1,0,4] ,0,0]。我的功能在我的所有测试中都能正常工作,但我希望改变它。我这样做的愿望不是因为我期待提高性能。我只想这样做,因为我正在尝试并希望学习不同的技术。
以下是代码:
public static int[] f(int n, int c){
int[] a = new int[c];
if(c>0 && n>=0){
int opt = (n-(n%c))/c;
n = n - (opt*c);
for(int i = 0;i<a.Length;i++){
a[i] = opt;
if(n>0){
a[i]++;
n--;
}
}
}
return a;
}
该功能首先确定每个col的最佳项目数:
int opt = (n-(n%c))/c;
因此f(17,4)将产生4,f(19,4)也将产生4,而f(3,4)将产生0.然后计算提醒:
n = n - (opt*c);
然后我循环遍历数组(长度为c)并指定[i]等于最佳值。最后,如果提醒大于0,我将1添加到[i]。这同样在整个阵列中分发提醒。这是我想改变的部分。
而不是检查是否(n> 0)并向数组添加1是否存在我可以使用的公式:
a[i] = opt + n*?????;
所以n * ???如果n大于0,则总是等于1;如果n是0或更小,则总是等于0
答案 0 :(得分:3)
您的问题的简单答案是使用带条件运算符的表达式:
a[i] = opt + (n > 0 ? 1 : 0);
如果(n > 0 ? 1 : 0)
大于1
,则{p> n
为0
,否则为0
。
<小时/> 在这方面,有一种更清晰,更简洁的方法来实现您的算法。
average
)。它的值为n / c
(使用整数除法)。remainder
)。其值为n % c
。average + 1
放在第一个remainder
位置,然后将average
放在其余位置。这方面的实施将是:
public static int[] Distribute(int total, int buckets)
{
if (total < 0) { throw new ArgumentException("cannot be less than 0", "total"); }
if (buckets < 1) { throw new ArgumentException("cannot be less than 1", "buckets"); }
var average = total / buckets;
var remainder = total % buckets;
var array = new int[buckets];
for (var i = 0; i < buckets; i++)
{
array[i] = average + (i < remainder ? 1 : 0);
}
return array;
}
强制性的Linq版本:
public static int[] DistributeLinq(int total, int buckets)
{
if (total < 0) { throw new ArgumentException("cannot be less than 0", "total"); }
if (buckets < 1) { throw new ArgumentException("cannot be less than 1", "buckets"); }
var average = total / buckets;
var remainder = total % buckets;
return Enumerable.Range(1, buckets)
.Select(v => average + (v <= remainder ? 1 : 0))
.ToArray();
}
答案 1 :(得分:2)
在int
表达式上输出bool
的简单函数怎么样?
int IsPositive(int number)
{
//if number is > 0 return integer one (1), else return integer zero (0)
return number > 0 ? 1 : 0;
}
然后您可以在代码中使用它:
a[i] = opt + IsPositive(n);
//opt + 1 if n > 0, opt + 0 if n <= 0
更新:根据您的评论,您可以直接移动评估:
a[i] = opt + (n > 0 ? 1 : 0);
顺便说一句:你应该@BradleyDotNET's comment提出一个编程格言。
答案 2 :(得分:1)
如果您想使用公式:
Math.Max(n - Math.Abs(n - 1), 0)
应该做的伎俩。 您的代码应如下所示:
a[i] = opt + Math.Max(n - Math.Abs(n - 1), 0)
答案 3 :(得分:1)
公式的另一个选择是
Math.Max(Math.Sign(n), 0)
如果您正在寻找一个数学公式,我不确定您是否会找到它,因为该函数在n = 0时是不连续的。