如何跳过数组中已访问元素?解决排行榜重复分数用户名匹配错误
问题分析与修复方案
问题根源
当前代码在匹配用户名和排序后的分数时,没有标记已完成匹配的位置。遇到重复分数时,后遍历到的用户会覆盖之前匹配成功的位置,导致所有相同分数的位置都被最后一个匹配的用户占据。
修复方案
方案1:标记已匹配的位置
新增一个布尔数组记录排序后分数数组的位置是否已被使用,匹配成功后标记为已用,后续跳过这些位置:
// 分数升序排序 int[] SortedArray = MergeSort(UnsortedScoresArray); string[] SortedUsernames = new string[SortedArray.Length]; // 新增:标记数组,记录位置是否已匹配 bool[] usedPositions = new bool[SortedArray.Length]; for (int i = 0; i < UnsortedScoresArray.Length; i++) { for (int a = 0; a < SortedArray.Length; a++) { // 匹配条件:分数相等且该位置未被使用 if (UnsortedScoresArray[i] == SortedArray[a] && !usedPositions[a]) { SortedUsernames[a] = UnsortedUsernamesArray[i]; usedPositions[a] = true; // 标记为已使用,避免重复匹配 break; // 找到匹配位置后跳出内层循环,防止当前用户覆盖其他位置 } } }
方案2:绑定用户与分数为对象(更优解)
分开处理两个数组容易出现同步错误,直接创建包含用户名和分数的类,对类数组排序能从根源上保证两者绑定:
// 定义用户分数类 public class UserScore { public string Username { get; set; } public int Score { get; set; } } // 读取文件并转换为UserScore列表 string[] UsernameAndScoresArray = System.IO.File.ReadAllLines(@"UsernamesAndScores.txt"); List<UserScore> userScores = new List<UserScore>(); foreach (string line in UsernameAndScoresArray) { int position = line.IndexOf(':'); string username = line.Substring(0, position); int score = int.Parse(line.Remove(0, position + 1)); userScores.Add(new UserScore { Username = username, Score = score }); } // 按分数升序排序(若要保留自定义归并排序,需修改MergeSort适配UserScore类型) userScores.Sort((x, y) => x.Score.CompareTo(y.Score)); // 降序展示排行榜 int place = 0; for (int i = userScores.Count - 1; i >= 0; i--) { place++; ListBoxLeaderBoardPlaceAndUser.Items.Add($"{place}: {userScores[i].Username}"); ListBoxLeaderboardScore.Items.Add(userScores[i].Score); }
效果对比
原始错误结果:
SortedUsernamesArray[] = {User5, User5, User2, User4, User1}
修复后正确结果:SortedUsernamesArray[] = {User3, User5, User2, User4, User1}
内容的提问来源于stack exchange,提问作者Sanj_05
相关产品推荐
相关产品推荐

