如何删除具有 2 个常见元素的数组/结构列表的元素

本文关键字:元素 常见 数组 列表 结构 何删除 删除 | 更新日期: 2023-09-27 18:30:42

有一个结构列表或者一个数组 列出每个包含 3 个元素的列表,例如

12 8 7
5  1 0
7  3 2
10 6 5
6  2 1
8  4 3
6  1 5
7  2 6
8  3 7
9  4 8
11 7 6
13 9 8
11 6 10
12 7 11
13 8 12
14 9 13
我想

摆脱列表中有 2 个常见子项的项目,在我想删除的示例中

5  1 0
6  2 1
6  1 5
7  3 2
7  2 6
8  4 3
8  3 7   has 2 same items as row 7,3,2
9  4 8   has 2 same items as row 8,4,3
10 6 5
11 7 6
11 6 10 has 2 same items as row 11,7,6
12 7 11 has 2 same items as row 11,7,10
12 8 7
13 8 12
13 9 8
14 9 13 has 2 same items as row 13,9,8

因此,使用结构方法,我正在考虑按元素 A 对列表进行排序,然后循环和比较元素,如果当前元素有 2 个值等于列表中的其他元素,我不将其添加到结果列表中,但是我卡住了,不知道是否有更好的方法

struct S
        {
            public int A;
            public int B;
            public int C;            
        }
public void test() 
        {
            List<S> DataItems = new List<S>();
            DataItems.Add(new S { A = 1, B = 2, C=3} );
            DataItems.Add(new S { A = 12, B = 8, C = 7 });
            DataItems.Add(new S { A = 5, B = 1, C = 0 });
            DataItems.Add(new S { A = 7, B = 3, C = 2 });
            DataItems.Add(new S { A = 10, B = 6, C = 5 });
            DataItems.Add(new S { A = 6, B = 2, C = 1 });
            DataItems.Add(new S { A = 8, B = 4, C = 3 });
            DataItems.Add(new S { A = 6, B = 1, C = 5 });
            DataItems.Add(new S { A = 7, B = 2, C = 6 });
            DataItems.Add(new S { A = 8, B = 3, C = 7 });
            DataItems.Add(new S { A = 9, B = 4, C = 8 });
            DataItems.Add(new S { A = 11, B = 7, C = 6 });
            DataItems.Add(new S { A = 13, B = 9, C = 8 });
            DataItems.Add(new S { A = 11, B = 6, C = 10 });
            DataItems.Add(new S { A = 12, B = 7, C = 11 });
            DataItems.Add(new S { A = 13, B = 8, C = 12 });
            DataItems.Add(new S { A = 14, B = 9, C = 13 });
            var sortedList = DataItems.OrderBy(x => x.A);
            List<S> resultList = new List<S>();
            for (int i = 0; i < sortedList.Count (); i++)
            {
               for (int j = i+1; j < sortedList.Count(); j++)
               {
                 if (sortedList.ElementAt(i).A == sortedList.ElementAt(j).A || sortedList.ElementAt(i).A == sortedList.ElementAt(j).B || sortedList.ElementAt(i).A == sortedList.ElementAt(j).C)                        
                {
                  //ONE HIT, WAIT OTHER
                }
               }
            }
        }

有没有更有效的方法来获取列表,而无需具有 2 个相同项目的项目,以便我会得到,而不是硬编码解决方案?

5  1 0
6  2 1
6  1 5
7  3 2
7  2 6
8  4 3
10 6 5
11 7 6
12 8 7
13 8 12
13 9 8

如何删除具有 2 个常见元素的数组/结构列表的元素

给定一个项目...

{ A = 1, B = 2, C = 3 }

您有 3 种可能的组合可以在另一个项目中重复,例如

AB, AC & BC which is {1, 2}, {1, 3} & {2, 3}

所以我要做的是遍历你的列表,将这些组合添加到带有分隔符字符的字典中(首先是最小的数字,所以如果 B

"1-2", "1-3", "2-3"

现在,当您添加每个项目时,请检查键是否已存在,如果存在,则可以忽略该项(不要将其添加到结果列表中)。

在性能方面,这将是一次遍历整个列表,并使用字典检查具有 2 个常用数字的项目。

解决它的一种方法是在struct S中引入中间方法:

public struct S {
    public int A;
    public int B;
    public int C;
    public bool IsSimilarTo(S s) {
        int similarity = HasElement(A, s) ? 1 : 0;
        similarity += HasElement(B, s) ? 1 : 0;
        return similarity >= 2 ? true : HasElement(C, s);           
    }
    public bool HasElement(int val, S s) {
        return val == s.A || val == s.B || val == s.C;
    }
    public int HasSimilarInList(List<S> list, int index) {
        if (index == 0)
            return -1;
        for (int i = 0; i < index; ++i)//compare with the previous items
            if (IsSimilarTo(list[i]))
                return i;
        return -1;
    }
}

然后你可以这样解决它,而无需订购:

public void test() {
    List<S> DataItems = new List<S>();
    DataItems.Add(new S { A = 1, B = 2, C = 3 });
    DataItems.Add(new S { A = 12, B = 8, C = 7 });
    DataItems.Add(new S { A = 5, B = 1, C = 0 });
    DataItems.Add(new S { A = 7, B = 3, C = 2 });
    DataItems.Add(new S { A = 10, B = 6, C = 5 });
    DataItems.Add(new S { A = 6, B = 2, C = 1 });
    DataItems.Add(new S { A = 8, B = 4, C = 3 });
    DataItems.Add(new S { A = 6, B = 1, C = 5 });
    DataItems.Add(new S { A = 7, B = 2, C = 6 });
    DataItems.Add(new S { A = 8, B = 3, C = 7 });
    DataItems.Add(new S { A = 9, B = 4, C = 8 });
    DataItems.Add(new S { A = 11, B = 7, C = 6 });
    DataItems.Add(new S { A = 13, B = 9, C = 8 });
    DataItems.Add(new S { A = 11, B = 6, C = 10 });
    DataItems.Add(new S { A = 12, B = 7, C = 11 });
    DataItems.Add(new S { A = 13, B = 8, C = 12 });
    DataItems.Add(new S { A = 14, B = 9, C = 13 });
    int index = 1; //0-th element does not need to be checked
    while (index < DataItems.Count) {
        int isSimilarTo = DataItems[index].HasSimilarInList(DataItems, index);
        if (isSimilarTo == -1) {
            ++index;
            continue;
        }
        DataItems.RemoveAt(index);
    }
}