2

有两个列表:

List<int> list2 = new List<int>(new[] { 1, 2, 3, 5, 6 }); // missing: 0 and 4
List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 });

你如何比较两个列表,在 List1 中找到缺失的数字并从 List1 中删除这些数字?更准确地说,我需要找到一种方法来指定比较的开始和结束位置。

我想这个过程应该和这个非常相似:

第1步。

int start_num = 3; // we know that comparisons starts at number 3
int start = list2.IndexOf(start_num); // we get index of Number (3)
int end = start + 2; // get ending position
int end_num = list2[end]; // get ending number (6)

现在我们在 List2 (3,5,6) 中得到了数字(和数字本身)的位置供比较

第 2 步。要获取 List1 中数字的位置以进行比较 - 我们可以执行以下操作:

int startlist1 = list1.IndexOf(start_num); // starting position
int endlist1 = list1.IndexOf(end_num); // ending position

范围如下:(3,4,5,6)

步骤 3. 比较。棘手的部分从这里开始,我需要帮助

基本上现在我们需要比较 (3,5,6) 处的 list2 和 (3,4,5,6) 处的 list1。缺少的数字是“4”。

// I have troubles with this step but the result will be:

int remove_it = 4; // or int []

步骤 4. 去除奇数。

int remove_it = 4;
list1 = list1.Where(a => a != remove_it).ToList();

效果很好,但是如果我们有 2 个缺失的数字会发生什么?IE

int remove_it = 4 // becomes int[] remove_it = {4, 0}

结果如您所料,结果是新的 List1,其中没有数字 4。

richTextBox1.Text = "" + string.Join(",", list1.ToArray()); // output: 0,1,2,3,5,6

textBox1.Text = "" + start + " " + start_num; // output: 2 3
textBox3.Text = "" + end + " " + end_num; // output: 4 6

textBox2.Text = "" + startlist1; // output: 3
textBox4.Text = "" + endlist1; // output: 6

你能帮我完成第3步或指出正确的方向吗?

另外,你能说如果起始数字(start_num)是最后一个数字会发生什么,但我需要得到接下来的两个数字?在上面的示例中,数字是3,5,6,但它们应该与5,6,06,0,10,1,2没有区别。

4

10 回答 10

3

只回答第一部分:

 var list3 = list1.Intersect(list2);

这将设置list3{ 0, 1, 2, 3, 4, 5, 6 } - { 0, 4 } = { 1, 2, 3, 5, 6 }

以及对第 1 步的反应 :

int start_num = 3; // 我们知道比较从数字 3
开始 int start = list2.IndexOf(start_num); // 我们得到数字 (3) 的索引
int end = start + 2; // 获取结束位置

你从哪里得到所有这些神奇的数字 (3, + 2 ) ?

我觉得你想多了,很多。

于 2012-04-10T13:26:35.097 回答
1
var result = list1.Intersect(list2)

.ToList如果您确实需要将结果作为列表,则可以在末尾添加 a 。

于 2012-04-10T13:26:34.787 回答
1
        List<int> list2 = new List<int>(new[] { 1, 2, 3, 5, 6 }); // missing: 0 and 4 
        List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 });

        // find items in list 2 notin 1
        var exceptions = list1.Except(list2);

        // or are you really wanting to do a union? (unique numbers in both arrays)
        var uniquenumberlist = list1.Union(list2);

        // or are you wanting to find common numbers in both arrays
        var commonnumberslist = list1.Intersect(list2);
于 2012-04-10T13:38:43.733 回答
0

也许你应该使用 OrderedList 而不是 List...

于 2012-04-10T13:27:11.060 回答
0

像这样的东西:

list1.RemoveAll(l=> !list2.Contains(l));
于 2012-04-10T13:29:36.300 回答
0

您可以IntersectSkipand结合使用Take来获得与范围相结合的交集逻辑(这里我们忽略了缺少 0 的事实,因为我们跳过了它):

static void Main(string[] args)
{
    var list1 = new List<int> { 1, 2, 3, 4, 5 };
    var list2 = new List<int> { 0, 1, 2, 3, 5, 6 };

    foreach (var i in list2.Skip(3).Take(3).Intersect(list1))
        Console.WriteLine(i); // Outputs 3 then 5.

    Console.Read();
}

虽然如果我真的很诚实,我不确定要问什么 - 我唯一确定的是相交部分:

var list1 = new List<int> { 1, 2, 3, 4, 5 };
var list2 = new List<int> { 0, 1, 2, 3, 5, 6 };

foreach (var i in list2.Intersect(list1))
    Console.WriteLine(i); // Outputs 1, 2, 3, 5.
于 2012-04-10T13:30:37.107 回答
0

要获取存在于list1但不存在于的数字list2,请使用Except扩展方法:

IEnumerable<int> missing = list1.Except(list2);

要遍历此结果以从中删除它们list1,您必须意识到结果,否则它将在您更改列表时从列表中读取,并且您会得到一个异常:

List<int> missing = list1.Except(list2).ToList();

现在您可以删除它们:

foreach (int number in missing) {
  list1.Remove(number);
}
于 2012-04-10T13:31:46.403 回答
0

我不确定我是否理解你的问题,我希望我给你的解决方案对你有好处。

您有 2 个列表:

List list2 = new List(new[] { 1, 2, 3, 5, 6 }); // 缺失:0 和 4 列表 list1 = new List(new[] { 0, 1, 2, 3, 4, 5, 6 });

要从 list1 中删除 list2 中所有缺失的数字,我建议使用以下解决方案:构建一个缺少数字的新列表:

列表差异 = 新列表();

然后将您需要删除的所有数字放入此列表中。现在删除过程应该很简单,只需将您添加到 diff 中的所有元素从 list2 中删除即可。

于 2012-04-10T13:32:39.053 回答
0

我是否正确理解该算法是:1)在列表2中取第一个数字并在列表1中找到这样的数字,2)然后从列表1中删除所有内容,直到找到第二个数字形式列表2(5)3)重复步骤2)下一个数字在列表 2 中。?

于 2012-04-10T13:37:06.667 回答
0

好的,看来我没有很好地解释这个问题,对此感到抱歉。任何有兴趣的人都可以通过查看这段代码来理解我的意思:

        List<int> list2 = new List<int>() { 1, 2, 3, 5, 6 }; // missing: 0 and 4
        List<int> list1 = new List<int>() { 0, 1, 2, 3, 4, 5, 6 };

        int number = 3; // starting position

        int indexer = list2.BinarySearch(number);
        if (indexer < 0)
        {
            list2.Insert(~index, number); // don't look at this part
        }

        // get indexes of "starting position"
        int index1 = list1.Select((item, i) => new { Item = item, Index = i }).First(x => x.Item == number).Index;
        int index2 = list2.Select((item, i) => new { Item = item, Index = i }).First(x => x.Item == number).Index;

        // reorder lists starting at "starting position"
        List<int> reorderedList1 = list1.Skip(index1).Concat(list1.Take(index1)).ToList(); //main big
        List<int> reorderedList2 = list2.Skip(index2).Concat(list2.Take(index2)).ToList(); // main small


        int end = 2; // get ending position: 2 numbers to the right
        int end_num = reorderedList2[end]; // get ending number

        int endlist1 = reorderedList1.IndexOf(end_num); // ending position

        //get lists for comparison
        reorderedList2 = reorderedList2.Take(end + 1).ToList();
        reorderedList1 = reorderedList1.Take(endlist1 + 1).ToList();

        //compare lists
        var list3 = reorderedList1.Except(reorderedList2).ToList();
        if (list3.Count != 0)
        {
            foreach (int item in list3)
            {
                list1 = list1.Where(x => x != item).ToList(); // remove from list
            }
        }
        // list1 is the result that I wanted to see

如果有任何方法可以优化此代码,请通知我。干杯。

于 2012-04-10T20:11:07.650 回答