[英]Calculating maximum and minimum values in an array
我有一個整數數組,需要在最大數字的數組中找到最小值的位置。 我有它工作但它似乎不是一個非常好的方法來做到這一點。 任何人都可以建議一個更好的方法來實現我的目標嗎?
這是我的代碼:
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);
那段代碼很好。 我建議稍微更改變量名稱,但這就是全部。 您可以在同一循環中計算出最小值。 我已經非常輕微地改變了“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];
}
}
如果您還沒有遇到可以為空的值類型,請不要擔心...
代碼看起來可以找到最大值。 如果你使用的是C#3或更高版本,你可以使用LINQ擴展方法(有Min
, Max
和Average
方法,在List
上也有FindIndex
方法,等等),但我得到你正在學習編程的印象,然后有時候一個好主意是實現可以構建到框架中的東西,只是為了學習價值。
我只是想為問題提供單線解決方案(完整性)。 在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括號內的委托。 它獲取參數“迄今為止找到的最大值索引”和當前索引。 它返回“到目前為止找到的最大值索引”。 顯然,在每次迭代中,“當前找到的最大值索引”將僅在數組的對應元素大於先前最大值時才變為當前索引。
抓住linq代碼,它沒有按你想要的方式工作
你可以讓你的代碼更簡潔一些
for (int i = 0; i < usageHours.Length; i++)
{
if (usageHours[i] > usageHours[runningMaxPosition])
runningMaxPosition = i;
}
所有它做的不同就是拋出臨時的runningTotal變量。
這個怎么樣:
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]);
您的代碼並不錯,但如果所有值都小於零,它將無法運行。
嘗試這個:
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;
}
正如評論中提到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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.