从数组中获取最大值而不进行排序

时间:2011-09-29 02:43:33

标签: c# winforms arrays

我正在创建一个有点简单的游戏,我需要跟踪玩家的得分。 25人将同时玩这个游戏,这些玩家将被放入一个阵列:

public static int[] allPlayers = new int[25];

根据正确的答案,当前的玩家将获得100分,让我们说。因此,如果玩家1启动,代码将类似于以下内容:

allPlayers[0] += 100;

如果玩家3上升,正确答案的代码将是:

allPlayers[2] += 100;

在游戏结束时,我想确定哪个玩家积累了最多的积分。请注意,我不能简单地对此数组进行排序,因为我需要保持数组的顺序保持不变。如果订单保持不变,我将无法判断哪个玩家的姓名是哪个。

我很想听听你们所说的话,我期待着你的回复。

非常感谢,

埃文

8 个答案:

答案 0 :(得分:4)

无需排序,只需遍历数组,跟踪到目前为止看到的最大值以及该值的索引。

  var largest = -1;
  var player = -1;
  for (var i = 0; i < allPlayers.Length; ++i)
  {
       if (allPlayers[i] > largest)
       {
           player = i;
           largest = allPlayers[i];
       }
  }

  Console.WriteLine( "Player {0} wins, with score {1}", player, largest );

处理关系是一种练习。

答案 1 :(得分:3)

如果您希望排名可能超过一个玩家(使用保持获胜玩家的索引的简单循环对基本情况更有效),可以使用Linq作为替代方案:

var player = allPlayers.Select((x, i) => new { Score = x, Player = i })
                       .OrderByDescending(x => x.Score)
                       .First();

Console.WriteLine("Player {0} wins with a score of {1}", player.Player, player.Score);

答案 2 :(得分:3)

我想成为一名LINQ纯粹主义者,并说如果您使用的是OrderByDescending,那么您正在进行O(NlogN)排序。由于max是一个O(N)算法,我们应该能够用LINQ做得更好。这是我对LINQ的O(N)提案:

  var player=allPlayers.Select((x, i) => new {Score=x, Player=i})
    .Aggregate((self, next) => self.Score>=next.Score ? self : next);

  Console.WriteLine("Player {0} wins with a score of {1}", player.Player, player.Score);

答案 3 :(得分:1)

使用

int max = maxplayers.Max()//linq extension method of [] int

请参阅this post

答案 4 :(得分:0)

如果您无法排序或保留可以进行排序的并行数据结构或保留对最大值的引用,那么您将获得O(n)算法。

最简单的方法是保持对插入到数组中的最高值的引用。

答案 5 :(得分:0)

使用Linq:

int max = allPlayers
     .Select((x, i) = > new { Player = i, Score = x })
     .OrderByDescending(x => x.Score)
     .First();

没有Linq:

int score;
int player;

for(var i = 0; i < allPlayers.Length; i++)
{
    if(allPlayers[i] > score)
    {
        score = allPlayers[i];
        player = i;
    }
}

答案 6 :(得分:0)

你可以保持玩家在所有过程中具有最大值的跟踪,在每次增加中你可以查看新值是否大于旧值,这样你就可以知道玩家有最大值在比赛的任何时刻。

private int maxPlayer = 0;
private int value = 0;

public void setIncrement(int player, int amount)
{
    allPlayer[player] += amount; 
    if(allPlayer[player] > value) 
    { 
        maxPlayer = player; 
        value =  allPlayer[player];
    }
}

public int getMaxPlayer()
{
return maxPlayer;
}

答案 7 :(得分:-1)

正如其他人所建议的那样,只需迭代一次即可。这是不可避免的,

除非

您将玩家阵列包装成阵列并封装设置玩家得分的方式。然后,您可以在向列表中添加内容时进行比较。