c#嵌套for循环检查比较列表中的每个元素返回奇数结果

本文关键字:元素 返回 结果 for 嵌套 循环 检查 列表 比较 | 更新日期: 2023-09-27 18:18:13

所以我有这个代码…这让我快疯了。结果是不一致的,它取决于列表中对象的顺序。

基本上复制对象列表,使用compareMembers()(100%没有问题)检查列表中的每个对象,然后如果它们的共同点多于允许的(num),则它们是"相似的",然后我们决定删除哪一个。接下来,得分较低的将从临时列表中删除,并在所有迭代后返回临时列表。

示例,如果我在删除类似的列表之前使用:

group.Sort((a, b) => -1 * a.GroupScore().CompareTo(b.GroupScore()));

返回的列表总是比我比较相似列表时包含的元素更少,并且列表是完全随机的。我知道问题出在这部分……希望它很简单,我只是盯着它看太久了。

这是给出冲突结果的代码。

    public List<MyGroup> RemoveSimilar(List<MyGroup> group, int num)
    {
        List<MyGroup> temp = group.ToList();
        for(int i = 0; i < group.Count - 1;i++)
        {
            for (int j = i + 1; j < group.Count;j++)
            {
                   if (group[i].compareMembers(group[j]) > num)
                    {
                        if (group[i].score < group[j].score)
                        {
                            temp.Remove(group[i]);
                            break;//removed this one might as well stop checking it
                        }
                        else
                        {
                            temp.Remove(group[j]);
                        }
                    }
                }
            }
        return temp;
    }
下面是MyGroup类:
    public class MyGroup
{
    public Member firstMember;
    public Member secondMember;
    public Member thirdMember;
    public double score;
    public MyGroup()
    {
    }
    public int compareMembers(MyGroup x)
    {
        int i = 0;
        if (this.firstMember == x.firstMember)
        { i++; }
        if (this.secondMember == x.secondMember)
        { i++; }
        if (this.thirdMember == x.thirdMember)
        { i++; }
        if (this.firstMember == x.secondMember)
        { i++; }
        if (this.firstMember == x.thirdMember)
        { i++; }
        if (this.secondMember == x.thirdMember)
        { i++; }
        return i;
    }

    public MyGroup(Member one, Member two, Member three)
    {
        firstMember = one;
        secondMember = two;
        thirdMember = three;

        groupScore = firstMember.mScore + secondMember.mScore + thirdMember.mScore;
    }
    public double GroupScore()
    {
        return score;
    }
}

下面是一个用于组成Group的成员的快速类:

    public class Member
{
    public string idNum;
    public string firstName;
    public string lastName;
    public double mScore;

    public Member()
    {
    }
    public Member(string id, string fnm, string lnm, double pt)
    {
        idNum = id;
        firstName = fnm;
        lastName = lnm;
        mScore = pt;
    }
    public override string ToString()
    { return firstName + " " + lastName; }

    public string Desc()
    {
        return idNum + " " + firstName + " " + mScore.ToString();
    }
 }

好的,所以我重新工作了一点,似乎得到一致的结果,不管列表的顺序....我还是很想知道为什么第一次尝试总是搞砸。以下是修改后的版本:

        public List<MyGroup> RemoveSimilar(List<MyGroup> group, int num)
    {
        List<MyGroup> temp = group.ToList();//take group argument and copy it into a new list
        for (int i = 0; i < group.Count - 1; i++)//first loop through each element of group list
        {
            if (temp.Contains(group[i])) //checks to make sure group[i] hasn't already been removed from temp list
            {
                for (int j = i + 1; j < group.Count; j++)//second loop through each element to compare to first
                {
                    if(group[i] != group[j]) //make sure we aren't comparing the same two objects
                    {
                        if (group[i].compareMembers(group[j]) > num)//check to see how "similar" groups are
                        {
                            if (group[i].score < group[j].score)//if the groups are similar, see which has a higher score
                            {
                                temp.Remove(group[i]);//outer element is not the best "unique group" so we remove it
                                break; //removed this one might as well stop checking it
                            }
                            else
                            {
                                temp.Remove(group[j]);//inner element was similar to outter, but not the best so we remove it
                            }
                        }
                    }
                }
            }
        }
        return temp; //return the list after all similar elements have been removed
    }

c#嵌套for循环检查比较列表中的每个元素返回奇数结果

当您有这样定义的函数时:

class MyGroup 
{
   public int compareMembers(MyGroup x);
}

在使用参数更改调用对象时,考虑这种情况是很重要的。您通常希望从以下调用获得相同的结果:

x.compareMembers(y);
y.compareMembers(x);

在您的情况下,您需要将函数compareMembers更改为:

public int compareMembers(MyGroup x)
{
    int i = 0;
    if (this.firstMember == x.firstMember)
    { i++; }
    if (this.secondMember == x.secondMember)
    { i++; }
    if (this.thirdMember == x.thirdMember)
    { i++; }
    if (this.firstMember == x.secondMember || this.secondMember == x.firstMember)
    { i++; }
    if (this.firstMember == x.thirdMember || this.thirdMember == x.firstMember )
    { i++; }
    if (this.secondMember == x.thirdMember || this.thirdMember == x.secondMember )
    { i++; }
    return i;
}
为了更清楚地说明函数的用途,函数名可以是countEqualMembers。