3

我有一个整数数组,需要在数组中找到最大数和最小值的位置。我让它工作,但它似乎不是一个很好的方法。任何人都可以提出更好的方法来实现我所拥有的吗?

这是我的代码:

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);
4

7 回答 7

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];
    }
}

如果您还没有遇到可空值类型,请不要担心......

于 2009-10-08T19:28:29.473 回答
2

该代码看起来可以找到最大值。如果您使用的是 C# 3 或更高版本,则可以使用 LINQ 扩展方法(有Min,MaxAverage方法,List还有一种FindIndex方法等),但我的印象是您正在学习编程,然后有时实现可能内置到框架中的东西是一个好主意,只是为了学习价值。

于 2009-10-08T19:24:06.113 回答
1

我只是想为这个问题提供一个单一的解决方案(为了完整性)。在 OP 的原始问题中,他只要求提供最大值索引和最小值索引。

让我们坚持这个问题。这是最有趣的问题,因为要找到最大值,我们可以简单地使用 Enumerable.Max LINQ 方法。最小值和平均值也是如此。

我们只提供最大值的索引,最小值的索引可以用类似的代码检索。

int indexOfMax = Enumerable.Range(0, usageHours.Length).Aggregate(
    (indexOfMax, i) => (usageHours[i] > usageHours[indexOfMax] ? i : indexOfMax)
);

对数组的每个索引执行聚合括号内的委托。它作为参数“迄今为止找到的最大值索引”和当前索引。它返回“迄今为止找到的最大值索引”。显然,在每次迭代中,“迄今为止找到的最大值的索引”只有在数组的相应元素大于先前的最大值时才会更改为当前索引。

于 2010-07-14T14:41:38.767 回答
0

刮擦linq代码,它没有按照您想要的方式工作

你可以让你的代码更简洁一点

for (int i = 0; i < usageHours.Length; i++)
{
    if (usageHours[i] > usageHours[runningMaxPosition])
        runningMaxPosition = i;
}

它所做的只是忽略了临时的 runningTotal 变量。

于 2009-10-08T19:23:01.793 回答
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]);
于 2009-10-08T19:25:06.063 回答
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;
 }
于 2009-10-08T19:33:47.920 回答
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);
于 2009-10-08T19:46:57.267 回答