【问题标题】:C# Sorting through a big list of numbersC# 对一大串数字进行排序
【发布时间】:2017-05-20 18:02:01
【问题描述】:

我有一个庞大的级别列表,以及该级别需要多少经验值(通过游戏中的级别进行)

名单:

1级 - 0 xp 2级 - 83 xp 3级 - 174 xp 4级 - 276 xp 5级 - 388 xp 6 级 - 512 经验值 7 级 - 650 经验值 8 级 - 801 经验值 9 级 - 969 经验值 10 级 - 1154 经验值 11 级 - 1358 经验值 12 级 - 1584 经验值 13 级 - 1833 经验值 14 级 - 2107 经验值 15 级 - 2411 经验值 16 级 - 2746 经验值 17 级 - 3115 经验值 18 级 - 3523 经验值 19 级 - 3973 经验值 20 级 - 4470 经验值 21级 - 5018 xp 22 级 - 5624 经验值 23 级 - 6291 经验值 24 级 - 7028 经验值 25 级 - 7842 经验值 26 级 - 8740 经验值 27 级 - 9730 经验值 28 级 - 10824 经验值 29 级 - 12031 经验值 30 级 - 13363 经验值 31 级 - 14833 经验值 32 级 - 16456 经验值 33 级 - 18247 经验值 34级 - 20224 xp 35 级 - 22406 经验值 36 级 - 24815 经验值 37 级 - 27473 经验值 38级 - 30408 xp 39级 - 33648 xp 40级 - 37224 xp 41 级 - 41171 经验值 42级 - 45529 xp 43级 - 50339 xp 44级 - 55649 xp 45 级 - 61512 经验值 46级 - 67983 xp 47 级 - 75127 经验值 48级 - 83014 xp 49 级 - 91721 经验值 50级 - 101333 xp 51 级 - 111945 经验值 52级 - 123660 xp 53级 - 136594 xp 54 级 - 150872 经验值 55级 - 166636 xp 56 级 - 184040 经验值 57级 - 203254 xp 58 级 - 224466 经验值 59级 - 247886 xp 60 级 - 273742 经验值 61级 - 302288 xp 62级 - 333804 xp 63级 - 368599 xp 64 级 - 407015 经验值 65级 - 449428 xp 66 级 - 496254 经验值 67 级 - 547953 经验值 68 级 - 605032 经验值 69 级 - 668051 经验值 70 级 - 737627 经验值 71 级 - 814445 经验值 72级 - 899257 xp 73级 - 992895 xp 74级 - 1096278 xp 75 级 - 1210421 经验值 76 级 - 1336443 经验值 77 级 - 1475581 经验值 78 级 - 1629200 经验值 79级 - 1798808 xp 80级 - 1986068 xp 81级 - 2192818 xp 82级 - 2421087 xp 83级 - 2673114 xp 84 级 - 2951373 经验值 85级 - 3258594 xp 86 级 - 3597792 经验值 87 级 - 3972294 经验值 88 级 - 4385776 经验值 89 级 - 4842295 经验值 90级 - 5346332 xp 91 级 - 5902831 经验值 92级 - 6517253 xp 93 级 - 7195629 经验值 94级 - 7944614 xp 95级 - 8771558 xp 96级 - 9684577 xp 97级 - 10692629 xp 98级 - 11805606 xp 99级 - 13034431 xp 100 级 - 14391160 经验值 101级 - 15889109 xp 102 级 - 17542976 经验值 103级 - 19368992 xp 104 级 - 21385073 经验值 105 级 - 23611006 经验值 106级 - 26068632 xp 107 级 - 28782069 经验值 108 级 - 31777943 经验值 109 级 - 35085654 经验值 110 级 - 38737661 经验值 111 级 - 42769801 经验值 112 级 - 47221641 经验值 113 级 - 52136869 经验值 114 级 - 57563718 经验值 115 级 - 63555443 经验值 116 级 - 70170840 经验值 117级 - 77474828 xp 118 级 - 85539082 经验值 119 级 - 94442737 经验值 120 级 - 104273167 经验值 121级 - 115126838 xp 122 级 - 127110260 经验值 123级 - 140341028 xp 124 级 - 154948977 经验值 125 级 - 171077457 经验值 126级 - 188884740 xp

而且我希望能够从基于 xp 的列表中返回一个级别。

因此,例如,如果我有 200 xp,它将返回我是 3 级。
如果我有 4,787,746 xp,它将返回我是 88 级
(4,787,746 xp 介于 88 级和 89 级之间,所以这就是为什么我会达到 88 级。只有当您至少拥有该级别所需的最低 xp 数量时,您才能达到新的级别)

所以我希望能够在没有大量条件语句的情况下实现上述目标。一定有比这样做更好的方法。

这是获得一个级别所需经验的公式(如果有帮助的话):

(L是你计算的等级)

【问题讨论】:

  • 谷歌二分搜索,应该可以帮到你。
  • 既然你有基于等级的xp公式,你也许可以解出等级并得到相反的公式。
  • 126 是最高级别吗?...或者这只是列表停止的地方?
  • 126 是最高级别,是的
  • @LasseV.Karlsen 我试图解决 L 的公式没有任何运气:/

标签: c# numbers


【解决方案1】:

简单:

var levels =
    Enumerable
        .Range(1, 126)
        .Select(L => (int)Math.Floor(
                Enumerable
                    .Range(1, L - 1)
                    .Select(x => Math.Floor(x + 300 * System.Math.Pow(2.0, x / 7.0)))
                    .Sum() / 4.0))
        .ToArray();

Func<int, int> getLevel = xp => levels.Where(x => x <= xp).Count();

然后这个:

Console.WriteLine(getLevel(200));
Console.WriteLine(getLevel(4787746));

给出这个:

3 88

你甚至可以这样做:

Func<int, int> getLevel = xp =>
    Enumerable
        .Range(1, 126)
        .Select(L => (int)Math.Floor(
            Enumerable
                .Range(1, L - 1)
                .Select(x => Math.Floor(x + 300 * System.Math.Pow(2.0, x / 7.0)))
                .Sum() / 4.0))
        .Where(x => x <= xp)
        .Count();

我的计时测试表明,这可以在 1 毫秒内计算出一个值,因此它不应该是性能问题。

【讨论】:

  • 不错。比我的干净。我不经常使用 LINQ,所以我的方法有点老派。
【解决方案2】:

给你...

private void button1_Click(object sender, EventArgs e)
{
    Console.WriteLine(Level(0).ToString());
    Console.WriteLine(Level(83).ToString());
    Console.WriteLine(Level(4787746).ToString());
    Console.WriteLine(Level(188884739).ToString());
    Console.WriteLine(Level(188884740).ToString());
    Console.WriteLine(Level(999999999).ToString());
}

private List<int> MinimumExperience = null;

private int Level(int experience)
{
    if (MinimumExperience == null)
    {
        MinimumExperience = new List<int>();
        List<int> numerators = Enumerable.Range(1, 125).Select(x => (int)Math.Floor((double)x + 300D * Math.Pow(2, (double)x / 7D))).ToList();
        for (int L = 1; L <= 126; L++)
        {
            int sum = 0;
            for (int x = 1; x < L; x++)
            {
                sum = sum + numerators[x - 1];
            }
            MinimumExperience.Add((int)Math.Floor((double)sum / 4D));
        }
    }

    for(int i = 0; i < MinimumExperience.Count; i++)
    {
        if (experience < MinimumExperience[i])
        {
            return i;
        }
    }
    return MinimumExperience.Count;
}

【讨论】:

    【解决方案3】:

    我希望这可以帮助:

        static void Main(string[] args)
        {
            //*****init for test
            List<Game> g = new List<Game>();
    
            Game g1 = new Game();
            g1.level = 1;
            g1.xp = 0;
            g.Add(g1);
            g1.level = 2;
            g1.xp = 83;
            g.Add(g1);
            g1.level = 3;
            g1.xp = 174;
            g.Add(g1);
            g1.level = 7;
            g1.xp = 276;
            g.Add(g1);
            //**********
    
            //setting your xp in order to find your level
            int your_level = 180;
            bool exact_sp = g.Exists(x => x.xp == your_level);
    
            if (!exact_sp)
            {
                g1.level = -1; //because you do not know
                g1.xp = your_level;
                g.Add(g1);
    
    
    
                List<Game> new_list = g.OrderBy(x => x.xp).ToList();
    
                for (int i = 0; i < new_list.Count; i++)
                {
                    if (new_list[i].xp == your_level)
                    {
                        Console.WriteLine("Your level is: " + new_list[i - 1].level);
                    }
                }
            }
            else
            {
                for (int i = 0; i < g.Count; i++)
                {
                    if (g[i].xp == your_level)
                    {
                        Console.WriteLine("Your level is: " + g[i].level);
                    }
                }
            }
    
    
        }
    struct Game
        {
            public int level { get; set; }
            public int xp { get; set; }
        }
    

    【讨论】:

    • 如果 xp 是关卡所需的确切数字,这将不起作用。 (在这种情况下它给出了上一个级别)
    • 已修复,谢谢!我也乐于看到可以实现我最初要求的其他方式:)
    • 谢谢,大脑。我编辑了答案。如果有任何错误,请告诉我。
    猜你喜欢
    • 2012-08-31
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 2011-10-07
    • 2011-08-14
    • 2021-09-17
    • 1970-01-01
    • 2012-11-14
    相关资源
    最近更新 更多