如何比较2组数组的不同匹配项

时间:2018-06-26 09:40:38

标签: c# arrays algorithm linq

鉴于我有4个整数数组:(我将这些称为主数组)

我还有x个单独的整数数组:(称这些为数据数组)

我希望能够计算出我拥有多少个数据阵列,其中至少一个条目也位于4个主阵列之一中,但其中一个主阵列只能使用一次。

理想情况下,我追求C#解决方案,但伪代码就足够了。

一些示例:

给出主数组:

[1],
[2, 3],
[4, 5, 6, 7],
[8]

带有数据数组:

[1],
[2],
[3, 9]

结果应为2。

  • 与主1匹配的数据数组1。
  • 数据数组2与Master 2匹配。
  • 数据数组3与Master 2匹配(但Master 2已被使用)。

带有数据数组:

[1],
[2, 8]
[2],
[9]

结果应为3。

  • 与主1匹配的数据数组1。
  • 数据数组2与主数据2和主数据4相匹配(应该只计数一次,但以后的条目将决定使用哪个)。
  • 数据数组3与Master 2匹配(上面已匹配2个,但是匹配了4个)。
  • 数据数组4不匹配

3 个答案:

答案 0 :(得分:2)

这似乎很简单:

var masters = new[]
{
    new[] { 1 },
    new[] { 2, 3 },
    new[] { 4, 5, 6, 7 },
    new[] { 8 }
};

var data = new[] 
{
    new[] { 1 },
    new[] { 3, 9 },
    new[] { 2 },
};

// Has masters[i] already been "consumed"?
var used = new bool[masters.Length];

// The found indexes in masters. -1 if not found/already used
var res = new int[data.Length];

for (int i = 0; i < data.Length; i++)
{
    // The default condition is "not found"
    res[i] = -1;

    for (int j = 0; j < masters.Length; j++)
    {
        // If masters[j] already used/consumed, then skip it
        if (used[j])
        {
            continue;
        }

        // We are looking for an intersection between masters[j] and data[i]
        if (masters[j].Intersect(data[i]).Any())
        {
            used[j] = true;
            res[i] = j;
            break;
        }
    }
}

然后您就可以

int count = res.Count(x => x != -1);

请注意,此算法的“时间”复杂度为O(n ^ 2)(如果我们考虑O(master.Length * data.Length)的中等长度,则类似于O(n^3)data[x].Length

答案 1 :(得分:2)

对不起我的答复,我已经从头开始重写了它。我们有一个众所周知的图问题,确切地说是最大二分匹配。哪里

  • 第1部分顶点master数组
  • 第2部分顶点data数组
  • 边缘:如果数据阵列与主阵列共享至少一项(交集不为空)

完成此操作后,您可以解决问题

https://www.geeksforgeeks.org/maximum-bipartite-matching/

https://www.cs.cmu.edu/~ckingsf/bioinfo-lectures/matching.pdf

答案 2 :(得分:0)

也许这不是完美的解决方案,但它可行

        int[,] master = new int[4,4];
        master[0,0]=1;
        master[1,0]=2;
        master[1,1]=3;
        master[2,0]=4;
        master[2,1]=5;
        master[2,2]=6;
        master[2,3]=7;
        master[3,0]=8;
        int[,] data = new int[3,2];
        data[0,0]=1;
        data[1,0]=2;
        data[2,0]=3;
        data[2,1]=9;

        bool [] usedmaster= new bool[4];
        for (int i=0;i<4;i++) usedmaster[i]=false;    

        for (int di=0;di<3;di++)
        {
            for (int dj=0;dj<2;dj++)
            {
                if (data[di,dj]>0)
                {
                    int mi=0,mj=0,k=0;
                    foreach (int n in master)
                    {
                        if (data[di,dj]==n)
                        {
                            string ss="";

                                if (usedmaster[k]==true) ss="{but master "+(k).ToString()+ " used}";

                            Console.WriteLine("Data array "+(di).ToString()+" matched with master "+(k).ToString()+ss);
                            usedmaster[k]=true;
                            k+=1;

                            break;
                        }
                        mj +=1;
                        if (master[mi,mj]==0) 
                        {
                            k +=1;
                            mi +=1;
                            mj=0;
                        }
                        if (mj>3) 
                        {
                            mj=0;
                            mi +=1;  
                            k +=1;
                        }
                    }
                }
            }
        }