【问题标题】:Find string with most frequency of a character in List of strings using LINQ C#使用LINQ C#在字符串列表中查找字符频率最高的字符串
【发布时间】:2016-04-28 16:02:58
【问题描述】:

我正在处理二进制向量,所以 List<string> 中的每个 string 看起来像

vectors[0] = "1 0 0 0 1 1 1 0 0 0 1 0 1 1 0 0 0 0 1 0 0 1"; 
vectors[1] = "1 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1";

我想从List<string> 中获取最大的字符串,其中包含最多的 1。

【问题讨论】:

  • 我很困惑,你想要的结果是vectors[0] 还是1 1 1 来自vectors[0]?还是完全不同的东西?
  • 1 位置对这个权重有影响吗?
  • @MichaelMcGriff 任何东西,索引或字符串或计数。只想要一个单行解决方案来找到最大的字符串。

标签: c# arrays linq list


【解决方案1】:

我觉得这里提供的解决方案太复杂了。 所以这是我的:

vectors.OrderByDescending(v => v.Count(c => c == '1')).First();

请注意,每个“向量”仅计算一次 Count。 EnumerableSorter 为你做这件事。

如果您想要更高效的解决方案,请选择@octavioccls answer

【讨论】:

  • 是的,最简单的答案。谢谢。
【解决方案2】:

我会这样做:

var biggest= vectors.Select(v=> new {Vector = v, Count = v.Count(c => c=='1')})
                    .Aggregate((seed, current) => seed.Count < current.Count ? current:seed)
                    .Vector;

您也可以使用OrderBy 扩展方法,但Aggregate 是O(n) 而OrderBy 是O(n* log n)。

我首先调用Select分机以避免多次计算seed的1的数量:

var biggest= vectors.Aggregate((seed, current)=>seed.Count(c=>c=='1')<current.Count(c=>c=='1')?current:seed);

【讨论】:

  • @Charpie 我不明白为什么这么复杂,我认为这是一个见仁见智的问题,但这是一个有效的解决方案,我不知道为什么被否决
  • @octavioccl - 因为您使用的是 Aggregate 而不是 orderby 或 max
  • AggregateOrderBy 效率更高,OrderBy 是 O(n* log n)
  • +1 用于考虑复杂性。我确实有一个大数据集(约 100k 个向量),所以我将尝试将最简单的答案(vectors.OrderByDescending(v => v.Count(c => c == '1')).First()) 与这个进行比较基于性能。
  • @TahaRehmanSiddiqui 如果您有大型数据集并且确实关心性能,那么您根本不应该使用 LINQ - 一个简单的 foreach 将胜过所有已发布的 LINQ 解决方案。
【解决方案3】:

你可以使用Count()方法:

int index = 0;
int max = vectors[0].Count(x => x == '1');

for (int a = 1; a < vectors.Length; a++)
{
    var count = vectors[a].Count(x => x == '$');
    if (count > max)
    {
        max = count;
        index = a;
    }
}

在循环之后,您将获得最大为 '1' 的字符串索引

【讨论】:

  • 为什么额外的循环为什么不只是 `int max = vectors[0].Count(x => x == '1').max(x => x)
  • 我想要一个单一的解决方案,这就是我在标题中提到 LINQ 的原因。无论如何,谢谢。
【解决方案4】:

使用 LINQ

var result = vectors.Select(d => new { Item = d,
                                       OneCount = d.Split(' ').Count(y => y == "1")})
                    .OrderByDescending(t => t.OneCount)
                    .Select(k=>k.Item).FirstOrDefault();

【讨论】:

  • 不需要拆分,只计算每个向量中的char '1'。此外,每个向量仅对 Count 进行一次评估,因此您不必将其结果“缓存”为匿名类型。
【解决方案5】:
vectors.OrderByDescending(b => b.Split('1').Length).First()

【讨论】:

  • 只想数的时候不用split。此方法也返回错误的结果(它应该是 Length-1)
  • length-1 :P 这有什么区别?
【解决方案6】:

您可以对列表进行循环,并以这种方式为每个字符串计算“1”的出现次数:

int count = myString.Split('1').Length - 1;

然后存储一个具有局部最大值的临时变量和具有该最大值的字符串数。 像这样:

int max = list[0].Split('1').Length - 1;
int stringMax = 0;

for (int i = 1; i < list.Length; i++)
{
    var count = list[i].Split('1').Length - 1;
    if (count > max)
    {
        max = count;
        stringMax = i;
    }
}

最后 stringMax 是具有最大值的字符串,max 是那个值

【讨论】:

  • 我想要一个单一的解决方案,这就是我在标题中提到 LINQ 的原因。无论如何,谢谢。
【解决方案7】:
var vectors = new[] { 
    "1 0 0 0 1 1 1 0 0 0 1 0 1 1 0 0 0 0 1 0 0 1",
    "1 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1",
};
var q = from v in vectors
        select new
        {
            v,
            c = v.Split(' ').Count(b => b == "1"),
        };
var m = q.First(c => c.c == q.Max(b => b.c)).v;

【讨论】:

    【解决方案8】:
    using System;
    using System.Collections.Generic;
    
    public class Program
    {
        public static void Main()
        {
            Console.WriteLine("Hello World");
            var vectors = new List<string>();
            vectors.Add("1 0 0 0 1 1 1 0 0 0 1 0 1 1 0 0 0 0 1 0 0 1"); 
            vectors.Add("1 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1");
    
    
            foreach(var v in vectors)
            {
                var result = new List<string>();
                int max = 0;
                foreach(var c in v)
                {
                    if(string.IsNullOrEmpty(c.ToString().Trim())) continue;
                    //Console.Write(c);
                    //Console.Write(max);
                    if(c != '1')
                    {
                        max = 0;
                    }
                    else
                    {
                        max++;
                        if(max > result.Count)
                        {
                            result.Add(c.ToString());
                        }
                    }
                }
    
                Console.WriteLine("Final Result: " + string.Join(" ", result));
            }
        }
    }
    

    【讨论】:

    • 我想要一个单一的解决方案,这就是我在标题中提到 LINQ 的原因。无论如何,谢谢。
    猜你喜欢
    • 2011-05-07
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多