Home > OS >  c# find row index of specific numbers in a 2 dimensonal array
c# find row index of specific numbers in a 2 dimensonal array

Time:01-10

There's an input:

8 4 6 6 6 6 6 6
7 5 7 6 6 6 6 5
6 6 6 5 5 5 5 6
8 6 8 7 7 7 7 6
8 6 6 6 6 6 6 6
8 6 6 6 6 6 6 1

I have to find the greatest numbers in each column and get their row index, if there's multiple of the same greatest number in one column, I have to get all of their row indexes, and put them in an array, but if there's multiple of the same row index I just need one, and I have to put them in ascending order.

The first column's greatest number is 8, so the indexes from the first column are 0, 3, 4, 5. The second colum's greatest number is 6, so the indexes from the second column are 2, 3, 4, 5 but I already have 3, 4, and 5 so I just need the 2 In the end I should have 0, 2, 3, 4, 5.

while (p < M)        //Getting the greatest numbers of each column
        {
            for (int l = 0; l < N; l  )
            {
                if (matrix[l, p] > max)
                {
                    max = matrix[l, p];
                }
            }
            greatestNum[p] = max;
            max = 0;
            p  ;
        }

I just need help with getting the indexes and with the no duplicates thing. I can do the ascending order by myself. Every help is appreciated.

CodePudding user response:

You can use HashSet<T> to store unique values of indexes.

GreatestNumberIndexes method finds maximums of current column and then adds the indexes of result HashSet. You can do ToArray() to get the indexes as an array too.

Here's the code:

private static HashSet<int> GreatestNumberIndexes(int[,] matrix,
    int rows, int cols)
{
    var indexes = new HashSet<int>();
    for (var i = 0; i < cols; i  )
    {
        var max = int.MinValue;
        for (int j = 0; j < rows; j  )
            if (matrix[j, i] > max)
                max = matrix[j, i];

        for (int j = 0; j < rows; j  )
            if (matrix[j, i] == max)
                indexes.Add(j);
    }

    return indexes;
}

CodePudding user response:

You can use HashSet<int> to store unique rows:

using System.Linq;

...

private static int[] myIndexes(int[,] data) {
  // distinct rows which contain max values
  HashSet<int> result = new HashSet<int>();

  // for each column we find rows that contain max values 
  for (int c = 0; c < data.GetLength(1);   c) {
    // max value so far
    int max = data[0, c];
    // List - we can have several rows with max value
    List<int> maxRows = new List<int>() {1}; 

    for (int r = 1; r < data.GetLength(0);   r)
      if (data[r, c] == max)
        maxRows.Add(r   1);
      else if (data[r, c] > max) {
        maxRows.Clear();
        max = data[r, c];
        maxRows.Add(r   1);  
      } 
 
    foreach (int item in maxRows)
      result.Add(item);
  }

  // let's return ordered rows - OrderBy
  return result
    .OrderBy(row => row) 
    .ToArray();
}

CodePudding user response:

Not the most elegant solution but:

int[,] matrix = new int[,]
{
    {8, 4, 6, 6, 6, 6, 6, 6},
    {7, 5, 7, 6, 6, 6, 6, 5},
    {6, 6, 6, 5, 5, 5, 5, 6},
    {8, 6, 8, 7, 7, 7, 7, 6},
    {8, 6, 6, 6, 6, 6, 6, 6},
    {8, 6, 6, 6, 6, 6, 6, 1}
};

HashSet<int> indicesOfMaxNumbers = new HashSet<int>();
for (int col = 0; col < matrix.GetLength(1); col  )
{
    int curMax = matrix[0, col];
    for (int row = 1; row < matrix.GetLength(0); row  )
    {
        if (curMax <= matrix[row, col])
        {
            curMax = matrix[row, col];
        }
    }

    for (int row = 0; row < matrix.GetLength(0); row  )
    {
        if (curMax == matrix[row, col])
        {
            indicesOfMaxNumbers.Add(row   1);
        }
    }


}
indicesOfMaxNumbers.Sort();
Console.WriteLine(string.Join(", ", indicesOfMaxNumbers));

I find the greatest element in each column and then I insert the index if it is not already been inserted.

P.S. you can play with it a bit to optimize it as I am 100% sure there is a better solution

CodePudding user response:

// init your example of rows
var matrixXY = new List<List<int>>
{
    new List<int>{8, 4, 6, 6, 6, 6, 6, 6},
    new List<int>{7, 5, 7, 6, 6, 6, 6, 5},
    new List<int>{6, 6, 6, 5, 5, 5, 5, 6},
    new List<int>{8, 6, 8, 7, 7, 7, 7, 6},
    new List<int>{8, 6, 6, 6, 6, 6, 6, 6},
    new List<int>{8, 6, 6, 6, 6, 6, 6, 1}
};

// turn it around for easier management
var matrixYX = new List<List<int>>();
for (int y = 0; y < matrixXY[0].Count; y  )
{
    matrixYX.Add(new List<int>());
    for (int x = 0; x < matrixXY.Count; x  )
    {
        matrixYX[y].Add(matrixXY[x][y]);
    }
}

// get index of each max number per column
var indexGroups = matrixYX.Select(values =>
{
    var maxValue = values.Max();
    return values
        .Select((value, i) => (Value: value, Index: i   1))
        .Where(tuple => tuple.Value == maxValue)
        .Select(tuple => tuple.Index);
});

// pass all indexes into one array
var result = indexGroups
    .SelectMany(indexes => indexes)
    .Distinct();
  •  Tags:  
  • Related