【问题标题】:How can i get the highest integer from a list string如何从列表字符串中获取最大整数
【发布时间】:2020-12-28 00:02:12
【问题描述】:

我有一个视频剪辑,其中包含一堆元数据(主要是单行字符串),这些元数据又链接到特定帧。我设法将速度数据与元数据的每一行分开并将其存储在另一个列表中lc4_highest_speed_2

     for (int h = 0; h < lc4_file_calculations.Count; h++)
                    {
     string hold_variable = lc4_file_calculations[h].Replace("-", ",");
     var mySplitResult2 = hold_variable.Split(',');
                            var speed = mySplitResult2[mySplitResult2.Length - 45];
                             lc4_highest_speed.Add(speed + ":" + h);
    }

for (int f = 0; f < lc4_highest_speed.Count; f++)
                {
 string hoe3 = lc4_highest_speed[f];
                    var mySplitResult3 = hoe3.Split(':');
                    var speed2 = mySplitResult3[mySplitResult3.Length - 2];
                    var speed3 = mySplitResult3[mySplitResult3.Length - 1];
                    string speed_test = speed2.ToString();
                        lc4_highest_speed_2.Add(speed2 + " - " + speed3);
}

新列表包含类似012 - 82 的数据,- 之前的第一部分是速度,另一部分是与另一个字符串中的值相关的索引号。我尝试过 concat 之类的方法,但没有奏效。什么是让 - 之前的元素获得最高速度的最佳方法,同时保持索引号与 - 之后的数字的关系。

谢谢

【问题讨论】:

  • 您认为该列表中的哪个条目是“最高速度”?
  • 你的意思是排序顺序是“按速度然后按索引”吗?所以在你的例子中,最高的是“013 - 106”?
  • 为什么要创建一个对象,例如,具有属性 id 和最大速度的类汽车? var car= lc4_highest_speed_2.OrderByDescending(item => item.Speed).First();

标签: c# list integer max


【解决方案1】:

O(n) 时间复杂度的解决方案以其高索引值返回更高的速度值。

int highestSpeed = 0;
int indexNumber = 0;

foreach (var item in lc4_highest_speed_2)
{
   var values = item.Split('-');
   if (values?.Count() == 2)
   {
       int.TryParse(values[0], out int parsedValue);
       if (parsedValue > highestSpeed)
       {
           highestSpeed = parsedValue;
           int.TryParse(values[1], out indexNumber);
           continue;
       }

       int.TryParse(values[1], out int parsedIndex);
       if (highestSpeed == parsedValue && parsedIndex > indexNumber) indexNumber = parsedIndex;
   }
}

【讨论】:

  • 比 linq 解决方案更快。如果不检查 >= 并为 indexNumber 添加单独的检查,可以做得更好一点。但它已经和现在一样好。
  • 有一个错误:考虑 [ "12 - 500", "13 - 100" ] 将导致最高速度 = 13, indexNumber = 500
  • 是的,当最高速度发生变化时,它应该将 indexNumber 重置为零,但是在 if 条件中的逻辑上需要采用不同的方法
  • @Fildor 是的,这是一个错误。我已经更新了答案
  • 非常感谢,这帮助我弄清楚我做错了什么以及如何去做
【解决方案2】:

您可以利用元组来执行此操作。元组根据实现IComparable&lt;T&gt; 的成员自动定义排序。 (按照声明元组成员的顺序进行比较。)

由于int 实现了IComparable&lt;T&gt;,如果我们构造一个元组,第一个元素是整数速度,第二个元素是整数索引,那么为元组生成的比较操作将正是您所需要的。

因此,您可以使用 Linq 表达式解决此问题,该表达式将每一行拆分为速度和索引字符串,将这些字符串解析为整数,并为每对速度和索引创建一个元组。然后你可以使用IEnumerable.Max()找到最大的:

var max = lc4_highest_speed_2.Select(item =>
{
    var elements = item.Split("-");
    return (speed: int.Parse(elements[0].Trim()), index: int.Parse(elements[1].Trim()));
}).Max();

请注意,max 是一个元组,它的第一个 int 元素称为 speed,第二个 int 元素称为 index

Try it on .Net Fiddle

【讨论】:

    【解决方案3】:

    另一种方法:

    var maxSpeed = lc4.Max(x => Convert.ToInt32(x.Split(' ')[0]));
    var maxLine = lc4.FirstOrDefault(x => x.StartsWith($"{maxSpeed} "));
    var maxIndex = Convert.ToInt32(maxLine.Split('-')[1].Substring(1));
    

    或者如果你想要所有索引:

    var maxSpeed = lc4.Max(x => Convert.ToInt32(x.Split(' ')[0]));
    var maxLines = lc4.Where(x => x.StartsWith($"{maxSpeed} "));
    var maxIndexes = maxLines.Select(x => Convert.ToInt32(x.Split('-')[1].Substring(1)));
    

    【讨论】:

      【解决方案4】:

      您可以将所有速度值存储在整数列表中,您可以在其中找到 mx 值并使用它的索引然后可以找到速度和索引值之间的关系。

      作为参考,我创建了这个小程序。希望你能理解

          using System;
           using System.Collections.Generic;
           using System.Linq;
      
           class HelloWorld {
           static void Main() {
            
            List<string> data = new List<string>();
            List<int> intdata = new List<int>();
            data.Add("012 - 82");
            data.Add("013 - 102");
            for(int i=0;i<data.Count;i++){
               intdata.Add(Int16.Parse(data[i].Substring(0,data[i].IndexOf("-"))));
            }
          Console.WriteLine(intdata.Max());
          }
        }
      

      【讨论】:

      • "... 但是也保持索引号的关系(在 - 之后)" - OP
      【解决方案5】:

      尝试以下:

                 string[] input = {
                                       "012 - 82",
                                       "012 - 83",
                                       "012 - 84",
                                       "012 - 85",
                                       "012 - 86",
                                       "012 - 87",
                                       "13 - 102",
                                       "13 - 103",
                                       "13 - 104",
                                       "13 - 105",
                                       "13 - 106"
                                   };
      
                  var output = input
                      .Select(x => x.Split(new char[] { '-' }))
                      .Select(x => new { speed = int.Parse(x.First()), index = int.Parse(x.Last()) })
                      .OrderByDescending(x => x.speed)
                      .GroupBy(x => x.speed)
                      .First()
                      .ToList();
      

      【讨论】:

      • 这是识别速度最快的条目的。不确定 OP 是否只需要一个条目(速度相等时的 IE 获得最高索引)
      • 这是在进行 O(N(LogN)) 排序以完成 O(N) 操作。
      • 是的,但是你会得到 First() 所以它没有做一个完整的排序。
      • @jdweng 是的,这是 .Net Core 中的优化。在 .Net Framework 4.8 中为 O(N(Log(N)),但在 .Net Core 3.1 中为 O(N)(如果您使用 .First())
      • 请注意,此输出为013 - 102 - 但尚不清楚 OP 是否希望输出为013 - 106(他们还没有回答关于这一点的查询,所以不要'不知道这是对还是错)
      猜你喜欢
      • 1970-01-01
      • 2019-04-11
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      • 2018-04-15
      • 1970-01-01
      • 2018-07-06
      • 1970-01-01
      相关资源
      最近更新 更多