c# - 数组排序效率...初学者需要指点

标签 c# arrays algorithm

首先我会说我是一个非常初级的程序员,这基本上是我在使用学习 Material 之外的第一个真正的项目。我一直在使用 C# 和 XNA 制作“Simon Says”风格的游戏(重复计算机生成的模式的游戏),实际游戏已经完成并且运行良好,但在创建它时,我还想创建一个 '前 10 名记分牌。记分牌会记录玩家姓名、等级(他们完成了多少“回合”)和连击(他们按了多少按钮是正确的),然后记分牌将按连击得分排序。这让我想到了 XML,这是我第一次使用它,最终我得到了一个记录前 10 名分数的 XML 文件。 XML 文件在记分板类中进行管理,该类还负责添加新分数和对分数进行排序。这让我明白了......我想要一些关于我对得分列表进行排序的方式以及我如何做得更好的反馈,我没有其他方法可以获得反馈=(。我知道。 NET 功能 Array.Sort() 但我不太确定如何使用它,因为它不仅仅是需要排序的单个数组。当需要将新分数输入记分板时,玩家姓名和级别也会必须添加。这些存储在“数组数组”中(10 = 用于“前 10 名”分数)

scoreboardComboData = new int[10]; // Combo

scoreboardTextData = new string[2][];
scoreboardTextData[0] = new string[10]; // Name
scoreboardTextData[1] = new string[10]; // Level as string

计分板类的工作原理如下:

- 检查'scoreboard.xml'是否存在,如果不存在则创建它
- 初始化以上数组并添加来自 scoreboard.xml 的任何玩家数据,来自上一次运行
- 当调用 AddScore(name, level, combo) 时排序开始
- 也可以调用另一种方法,用上述数组数据填充 XML 文件

排序检查新分数(组合)是否小于或等于 scoreboardComboData 数组中的任何记录分数(如果它大于分数,则移至下一个元素)。如果是这样,它会将低于或等于分数的所有分数向下移动一个元素,实质上删除最后一个分数,然后将新分数放在低于或等于分数的元素内。如果分数大于所有记录的分数,它将所有分数向下移动一个并将新分数插入第一个元素中。如果它是唯一的分数,它只是将它添加到第一个元素。添加新分数时,名称和级别数据也会以相同的方式添加到它们的相关数组中。真是绕口令。下面是 AddScore 方法,我已经添加了评论,希望它能让事情更清楚 O_o。您可以获得实际的源文件HERE .该方法下方是添加分数以使用调试器跟进的最快方法的示例。

    public static void AddScore(string name, string level, int combo)
    {
        // If the scoreboard has not yet been filled, this adds another 'active'
        // array element each time a new score is added. The actual array size is
        // defined within PopulateScoreBoard() (set to 10 - for 'top 10'
        if (totalScores < scoreboardComboData.Length)
            totalScores++;

        // Does the scoreboard even need sorting?
        if (totalScores > 1)
        {
            for (int i = totalScores - 1; i > - 1; i--)
            {
                // Check to see if score (combo) is greater than score stored in 
                // array
                if (combo > scoreboardComboData[i] && i != 0)
                {
                    // If so continue to next element
                    continue;
                }

                // Check to see if score (combo) is less or equal to element 'i'
                // score && that the element is not the last in the
                // array, if so the score does not need to be added to the scoreboard
                else if (combo <= scoreboardComboData[i] && i != scoreboardComboData.Length - 1)
                {
                    // If the score is lower than element 'i' and greater than the last
                    // element within the array, it needs to be added to the scoreboard. This is achieved
                    // by moving each element under element 'i' down an element. The new score is then inserted
                    // into the array under element 'i'
                    for (int j = totalScores - 1; j > i; j--)
                    {
                        // Name and level data are moved down in their relevant arrays
                        scoreboardTextData[0][j] = scoreboardTextData[0][j - 1];
                        scoreboardTextData[1][j] = scoreboardTextData[1][j - 1];
                        // Score (combo) data is moved down in relevant array
                        scoreboardComboData[j] = scoreboardComboData[j - 1];
                    }

                    // The new Name, level and score (combo) data is inserted into the relevant array under element 'i'
                    scoreboardTextData[0][i + 1] = name;
                    scoreboardTextData[1][i + 1] = level;
                    scoreboardComboData[i + 1] = combo;
                    break;
                }

                // If the method gets the this point, it means that the score is greater than all scores within
                // the array and therefore cannot be added in the above way. As it is not less than any score within
                // the array.
                else if (i == 0)
                {
                    // All Names, levels and scores are moved down within their relevant arrays
                    for (int j = totalScores - 1; j != 0; j--)
                    {
                        scoreboardTextData[0][j] = scoreboardTextData[0][j - 1];
                        scoreboardTextData[1][j] = scoreboardTextData[1][j - 1];
                        scoreboardComboData[j] = scoreboardComboData[j - 1];
                    }

                    // The new number 1 top name, level and score, are added into the first element
                    // within each of their relevant arrays.
                    scoreboardTextData[0][0] = name;
                    scoreboardTextData[1][0] = level;
                    scoreboardComboData[0] = combo;

                    break;
                }

                // If the methods get to this point, the combo score is not high enough
                // to be on the top10 score list and therefore needs to break
                break;
            }
        }

        // As totalScores < 1, the current score is the first to be added. Therefore no checks need to be made
        // and the Name, Level and combo data can be entered directly into the first element of their relevant
        // array.
        else
        {
            scoreboardTextData[0][0] = name;
            scoreboardTextData[1][0] = level;
            scoreboardComboData[0] = combo;
        }


    }
}

添加分数的示例:

    private static void Initialize()
    {
        scoreboardDoc = new XmlDocument();
        if (!File.Exists("Scoreboard.xml"))
            GenerateXML("Scoreboard.xml");

        PopulateScoreBoard("Scoreboard.xml");

        // ADD TEST SCORES HERE!
        AddScore("EXAMPLE", "10", 100);
        AddScore("EXAMPLE2", "24", 999);

        PopulateXML("Scoreboard.xml");
    }

在当前状态下,源文件仅用于测试,在 main 中调用初始化,PopulateScoreBoard 处理大部分其他初始化,因此除了添加测试分数外不需要其他任何东西。

感谢您的宝贵时间!

最佳答案

作为编程技巧,您应该将 3 个不同的数组替换为单个分数对象数组,这些对象中的每一个都将具有您提到的所有 3 个属性(名称、级别和分数)。然后,您可以为其创建一个类似比较器的函数(基于 score 属性),该函数可用于通过 Arrays.Sort() 方法对其进行排序。

如果您想保持当前的 3 个数组,那么您可以在此处查找排序算法:http://en.wikipedia.org/wiki/Sorting_algorithm#Comparison_of_algorithms并且只需这样做,以便同时对 3 个数组进行任何更改,而不是一个一个地进行(因为您通过索引使它们中的数据保持同步)。

关于c# - 数组排序效率...初学者需要指点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5035914/

相关文章:

c++ - 为什么这不起作用 : `int arr[size]` but this does `int* arr = new int[size]` ?

C - 通过网络发送后字符数组更长

algorithm - 比较指数函数的增长率?

java - 如何找到指定月份的星期几的索引?

c# - ListView OwnerDraw 的默认实现

c# - 系统.InvalidOperationException : 'A method was called at an unexpected time when calling LaunchUriAsync inside ToastNotification UWP

c# - 从立即窗口执行方法

php - "Notice: Undefined variable"、 "Notice: Undefined index"、 "Warning: Undefined array key"和 "Notice: Undefined offset"使用 PHP

algorithm - 8 元素二叉堆需要多少次比较?

c# - 在C#中丢弃的优点是什么