0

我有一个逗号分隔的字符串列表,如下所示:

    List<string> IdList=new List<string>();

并且列表的每个元素都有逗号分隔的字符串,例如

     1,2,4,5,6,7,8,10,12,15,16
     2,3,5,7,8,9,0,10,16,17
     4,5,89,12,13,1,2,3,6,7,10,16

我想在这个字符串列表上应用 AND 操作,所以我得到如下输出:

      2,5,7,10,16

有没有什么有效的方法来实现交叉点操作?

4

3 回答 3

4

你实际上是在寻找一个交叉点

如果您不需要按数字顺序排列的值,您可以将每个字符串视为逗号分隔的值。从第一个列表开始,然后适当地相互交叉:

HashSet<string> set = new HashSet<string>(list[0].Split(','));
foreach (var item in list.Skip(1))
{
    set.IntersectWith(item.Split(','));
}
string result = string.Join(",", set);

完整的示例代码:

using System;
using System.Collections.Generic;
using System.Linq;

class Test
{
    static void Main()
    {
        var list = new List<string>
        {
            "1,2,4,5,6,7,8,10,12,15,16", 
            "2,3,5,7,8,9,0,10,16,17",
            "4,5,89,12,13,1,2,3,6,7,10,16"
        };

        HashSet<string> set = new HashSet<string>(list[0].Split(','));
        foreach (var item in list.Skip(1))
        {
            set.IntersectWith(item.Split(','));
        }
        string result = string.Join(",", set);
        Console.WriteLine(result);
    }
}

结果(不保证订单):

2,5,7,10,16
于 2013-07-20T11:28:47.793 回答
2

我不知道“更少的内存利用率”,但我第一次尝试这将是这些方面的东西(未经测试,在浏览器中编码,没有 Visual Studio 方便 yadda yadda):

Dictionary<int,int> occurences = new Dictionary<int,int>();
int numberOfLists = YourCollectionOfOuterLists.Count;

foreach (string list in YourCollectionOfOuterLists) {
    foreach (string value in list.Split(',')) {
        occurences[value] = ((occurences[value] as int) ?? 0) + 1;
    }
}

List<int> output = new List<int>();
foreach (int key in occurences.Keys) {
    if (occurences[key] == numberOfLists) {
        output.Add(key);
    }
}

return String.Join(output.Select(x => x.ToString()), ",");

很可能可以更简洁地编写代码,但是完成您似乎想要完成的任何事情仍然必须执行大致相同的步骤:确定所有列表中存在哪些元素(这与数字相比有点不重要)列表的数量未知),然后从这些值中创建一个新列表。

如果您可以访问它,类似的东西Parallel.ForEach()可能有助于减少挂钟执行时间,至少在第二个循环(可能是第一个,适当的锁定/同步到位)。

如果您追求的不是这个,请澄清您的问题以准确描述您想要什么。

于 2013-07-20T11:06:45.773 回答
0

我不确定性能,但您可以使用Aggregate扩展方法来“折叠交叉点”。

var data = new List<string>
{
    "1,2,4,5,6,7,8,10,12,15,16",
    "2,3,5,7,8,9,0,10,16,17",
    "4,5,89,12,13,1,2,3,6,7,10,16",
};

var fold = data.Aggregate(data[0].Split(',').AsEnumerable(), (d1, d2) => d1.Intersect(d2.Split(',')));
于 2013-07-20T11:58:25.053 回答