简体   繁体   中英

Find intersection of two multi-dimensional Arrays in C# 4.0

Trying to find a solution to my ranking problem.

Basically I have two multi-dimensional double[,] arrays. Both containing rankings for certain scenarios, so [rank number, scenario number]. More than one scenario can have the same rank.

I want to generate a third multi-dimensional array, taking the intersections of the previous two multi-dimensional arrays to provide a joint ranking.

Does anyone have an idea how I can do this in C#?

Many thanks for any advice or help you can provide!

Edit:

Thank you for all the responses, sorry I should have included an example.

Here it is:

Array One:
[{0,4},{1,0},{1,2},{2,1},{3,5},{4,3}]

Array Two:
[{0,1},{0,4},{1,0},{1,2},{3,5},{4,3}]

Required Result:
[{0,4},{1,0},{1,2},{1,1},{2,5},{3,3}]

Here's some sample code that makes a bunch of assumptions but might be something like what you are looking for. I've added a few comments as well:

    static double[,] Intersect(double[,] a1, double[,] a2)
    {
        // Assumptions:
        //      a1 and a2 are two-dimensional arrays of the same size
        //      An element in the array matches if and only if its value is found in the same location in both arrays
        //      result will contain not-a-number (NaN) for non-matches
        double[,] result = new double[a1.GetLength(0), a1.GetLength(1)];
        for (int i = 0; i < a1.GetLength(0); i++)
        {
            for (int j = 0; j < a1.GetLength(1); j++)
            {
                if (a1[i, j] == a2[i, j])
                {
                    result[i, j] = a1[i, j];
                }
                else
                {
                    result[i, j] = double.NaN;
                }
            }
        }
        return result;
    }

For the most part, finding the intersection of multiple dimensional arrays will involve iterating over the elements in each of the dimensions in the arrays. If the indices of the array are not part of the match criteria (my second assumption in my code is removed), you would have to walk each dimension in each array - which increases the run-time of the algorithm (in this case, from O(n^2) to O(n^4).

If you care enough about run-time, I believe array matching is one of the typical examples of dynamic programming (DP) optimization; which you can read up on at your leisure.

I'm not sure how you wanted your results...you could probably return a flat collection of results that can be indexed by a pair, which would potentially save a lot of space if the expected result set is typically small. I went with a third fixed-sized array because it was the easiest thing to do.

Lastly, I'll mention that I don't see a keen C# way of doing this using IEnumerable, LINQ, or something like that. Someone more C# knowledgeable than I can chime in anytime now....

Given the additional information, I'd argue that you aren't actually working with multidimensional arrays, but instead are working with a collection of pairs. The pair is a pair of doubles. I think the following should work nicely:

public class Pair : IEquatable<Pair>
{
    public double Rank;
    public double Scenario;

    public bool Equals(Pair p)
    {
        return Rank == p.Rank && Scenario == p.Scenario;
    }

    public override int GetHashCode()
    {
        int hashRank= Rank.GetHashCode();
        int hashScenario = Scenario.GetHashCode();
        return hashRank ^ hashScenario;
    }
}

You can then use the Intersect operator on IEnumerable:

List<Pair> one = new List<Pair>();
List<Pair> two = new List<Pair>();
// ... populate the lists
List<Pair> result = one.Intersect(two).ToList();

Check out the following msdn article on Enumerable.Intersect() for more information: http://msdn.microsoft.com/en-us/library/bb910215%28v=vs.90%29.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM