我有一个整数数组,需要在最大数字的数组中找到最小值的位置。我有它工作但它似乎不是一个非常好的方法来做到这一点。任何人都可以建议一个更好的方法来实现我的目标吗?
这是我的代码:
int[] usageHours = { 3, 3, 5, 4, 0, 0, 2, 2, 4, 25, 158, 320, 212, 356, 401, 460, 480, 403, 298, 213, 102, 87, 34, 45 };
double myAverage = usageHours.Average();
int runningTotal = 0;
int runningMaxPosition = 0;
for (int i = 0; i < usageHours.Length; i++)
{
if (usageHours[i] > runningTotal)
{
runningMaxPosition = i;
runningTotal = usageHours[i];
}
}
txtmax.Text = Convert.ToString(runningMaxPosition)+" With: "+Convert.ToString(runningTotal)+" Users";
txtAv.Text = Convert.ToString(myAverage);
答案 0 :(得分:7)
那段代码很好。我建议稍微更改变量名称,但这就是全部。您可以在同一循环中计算出最小值。我已经非常轻微地改变了“if”条件,以保证它们总是挑出至少一个元素(即使所有值都是,例如int.MinValue
)。还有其他方法可以解决这个问题,但这只是一个例子。如果你有一个空数组,你最终会得到max = min = 0,并且两个索引都是-1。
int currentMax = 0;
int currentMaxIndex = -1;
int currentMin = 0;
int currentMinIndex = -1;
for (int i = 0; i < usageHours.Length; i++)
{
if (currentMaxIndex == -1 || usageHours[i] > currentMax)
{
currentMaxIndex = i;
currentMax = usageHours[i];
}
if (currentMinIndex == -1 || usageHours[i] < currentMin)
{
currentMinIndex = i;
currentMin = usageHours[i];
}
}
以下是使用可空值类型来表示“没有值”答案的替代方案:
int currentMax? = null;
int currentMaxIndex? = null;
int currentMin? = null;
int currentMinIndex? = null;
for (int i = 0; i < usageHours.Length; i++)
{
if (currentMax == null || usageHours[i] > currentMax.Value)
{
currentMax = i;
currentMax = usageHours[i];
}
if (currentMin == null || usageHours[i] < currentMin.Value)
{
currentMinIndex = i;
currentMin = usageHours[i];
}
}
如果您还没有遇到可以为空的值类型,请不要担心......
答案 1 :(得分:2)
代码看起来可以找到最大值。如果您使用的是C#3或更高版本,则可以使用LINQ扩展方法(Min
,Max
和Average
方法,List
上还有FindIndex
1}}方法,其中包括),但我得到的印象是你正在学习编程,然后有时候实现可以构建到框架中的东西是个好主意,只是为了学习价值。
答案 2 :(得分:1)
我只是想为问题提供单线解决方案(完整性)。 在OP的原始问题中,他只询问最大值的索引和最小值的索引。
让我们坚持这个问题。这是最有趣的问题,因为要找到最大值,我们可以简单地使用Enumerable.Max LINQ方法。 Min和Average也是如此。
我们只提供max的索引,min的索引可以用类似的代码检索。
int indexOfMax = Enumerable.Range(0, usageHours.Length).Aggregate(
(indexOfMax, i) => (usageHours[i] > usageHours[indexOfMax] ? i : indexOfMax)
);
对于每个数组索引,都会执行Aggregate括号内的委托。它获取参数“迄今为止找到的最大值索引”和当前索引。它返回“到目前为止找到的最大值索引”。显然,在每次迭代中,“当前找到的最大值索引”将仅在数组的对应元素大于先前最大值时才变为当前索引。
答案 3 :(得分:0)
抓住linq代码,它没有按你想要的方式工作
你可以让你的代码更简洁
for (int i = 0; i < usageHours.Length; i++)
{
if (usageHours[i] > usageHours[runningMaxPosition])
runningMaxPosition = i;
}
所有不同的方法是抛出临时的runningTotal变量。
答案 4 :(得分:0)
这个怎么样:
double average = usageHours.Average();
int maxPosition = Enumerable.Range(0, usageHours.Length).Max(i => usageHours[i]);
int minPosition = Enumerable.Range(0, usageHours.Length).Min(i => usageHours[i]);
答案 5 :(得分:0)
您的代码并不错,但如果所有值都小于零,它将无效。
试试这个:
int getArrayMaxPosition (double[] theArray)
{
double maxVal = theArray[0];
int ret = 0;
int currentIndex = 0;
foreach (double aValue in theArray)
{
if (aValue > maxVal)
{
ret = currentIndex;
maxVal = avalue;
}
currentIndex++;
}
return ret;
}
答案 6 :(得分:0)
正如评论中提到Jon的回答,Jon的解决方案确实是最好,最直接,最快捷的解决方案。
但是,如果您确实想要使用Igor的解决方案,那么其余部分(获取实际位置以及值):
int maxValue = Enumerable.Range(0, usageHours.Length).Max(i => usageHours[i]);
int maxPosition = Array.FindIndex(usageHours, i => i == maxValue);
int minValue = Enumerable.Range(0, usageHours.Length).Min(i => usageHours[i]);
int minPosition = Array.FindIndex(usageHours, i => i == minValue);