[英]2d array search optimization
我寫了一段代碼,以便在二維數組的行/列中找到 3 個重復的元素。
private static bool SearchInRows(int[,] matrix)
{
int count = 1;
int repeatElement = int.MaxValue;
//Search in rows
for (int i = 0; i < matrix.GetLength(0); i++)
{
repeatElement = matrix[i, 0];
for (int j = 1; j < matrix.GetLength(1); j++)
{
if (repeatElement == matrix[i, j])
{
count++;
if (count >= 3)
{
Console.WriteLine($"Repeated elements are in positions i:{i}, j:{j - 2}, {j - 1}, {j}");
return true;
}
}
else
{
repeatElement = matrix[i, j];
count = 1;
}
}
}
return false;
}
private static bool SearchInCols(int[,] matrix)
{
int count = 1;
int repeatElement = int.MaxValue;
//Search in cols
for (int j = 0; j < matrix.GetLength(1); j++)
{
repeatElement = matrix[0, j];
for (int i = 1; i < matrix.GetLength(0); i++)
{
if (repeatElement == matrix[i, j])
{
count++;
if (count >= 3)
{
Console.WriteLine($"Repeated elements are in positions j:{j}, i:{i-2}, {i-1}, {i}");
return true;
}
}
else
{
repeatElement = matrix[i, j];
count = 1;
}
}
}
return false;
}
它工作正常,但我會做這樣的事情:
while (!SearchInRows(matrix) && !SearchInCols(matrix))
{
SearchInRows(matrix);
SearchInCols(matrix);
//modify the matrix
}
我想知道,如果我可以使用一些東西來提高我的代碼的性能,比如在每個方法上添加 Task.Run 或其他東西(我為此將方法拆分為 cols 和 rows)。
您的問題有更高效的解決方案,因為您的函數本質上要求您對每個元素進行兩次迭代(一次用於列,一次用於行)。 通過你調用函數的方式,你有更多的迭代。
這是我想出的一個更有效的解決方案,但可能還有更好的解決方案。 基本上,我只對每個元素迭代一次,並檢查列和行中接下來的兩個元素是否匹配。 例如,讓我們看看下面的 8x8 二維數組。 我對紅色框中的每個元素進行一次迭代,並檢查行/列中接下來的兩個元素是否匹配。 這讓我有兩行和兩列未選中,我必須單獨檢查。
這是代碼:
private static void FindThreeRepeatedElements(int[,] matrix)
{
// iterate once trough each element (red box) and check
// if the next 2 elements in the row / column match
for(int row = 0; row < matrix.GetLength(0) - 2; row++)
{
for (int column = 0; column < matrix.GetLength(1) - 2; column++)
{
CheckRow(matrix, row, column);
CheckColumn(matrix, row, column);
}
}
// check the last remaining 2 rows
CheckRow(matrix, matrix.GetLength(0) - 2, matrix.GetLength(0) - 3);
CheckRow(matrix, matrix.GetLength(0) - 1, matrix.GetLength(0) - 3);
// check the last remaining 2 columns
CheckColumn(matrix, matrix.GetLength(0) - 3, matrix.GetLength(0) - 2);
CheckColumn(matrix, matrix.GetLength(0) - 3, matrix.GetLength(0) - 1);
}
private static void CheckRow(int[,] matrix, int row, int column)
{
int element = matrix[row, column];
if (element == matrix[row, column + 1] && element == matrix[row, column + 2])
{
Console.WriteLine($"Three repeated elements with value {element} are found in row {row} at the positions: [{row}, {column}], [{row}, {column + 1}], [{row}, {column + 2}]");
}
}
private static void CheckColumn(int[,] matrix, int row, int column)
{
int element = matrix[row, column];
if(element == matrix[row + 1, column] && element == matrix[row + 2, column])
{
Console.WriteLine($"Three repeated elements with value {element} are found in column {column} at the positions: [{row}, {column}], [{row + 1}, {column}], [{row + 2}, {column}]");
}
}
正如您剛才在評論中指出的那樣,在某些情況下可以跳過某些元素的檢查,因為它們之前已經過檢查。 例如,如果我們再次查看 8x8 二維數組,在比較藍色框中的元素后,我們看到前兩個元素匹配(均為 7),因此我們檢查第三個元素是否也具有值 7,這失敗(它的值為 4)。 現在我們已經知道我們可以跳過對行中接下來三個元素的檢查(橙色框),因為當我們到達值為 7、4 和 5 的元素時,我們已經在前一個元素中對前兩個元素進行了比較迭代。
我修改了上面的代碼以跳過這些比較,這給我們留下了更多的代碼,但在技術上比較更少(不確定它是否實際上性能更高)。 在此示例中,bool _skipNextRowCheck在藍色框中進行比較后將為真,這將完全跳過檢查橙色框中的 3 個元素是否具有相等的值。
這是修改后的代碼:
private static bool _skipNextRowCheck = false;
private static bool _skipNextColumnCheck = false;
private static void FindThreeRepeatedElementsWithSkips(int[,] matrix)
{
// iterate trough each element and check
// if the next 2 elements in the row / column match
for (int row = 0; row < matrix.GetLength(0) - 2; row++)
{
for (int column = 0; column < matrix.GetLength(1) - 2; column++)
{
CheckRowWithSkips(matrix, row, column);
CheckColumnWithSkips(matrix, row, column);
}
}
// check the last remaining 2 rows
CheckRowWithSkips(matrix, matrix.GetLength(0) - 2, matrix.GetLength(0) - 3);
CheckRowWithSkips(matrix, matrix.GetLength(0) - 1, matrix.GetLength(0) - 3);
// check the last remaining 2 columns
CheckColumnWithSkips(matrix, matrix.GetLength(0) - 3, matrix.GetLength(0) - 2);
CheckColumnWithSkips(matrix, matrix.GetLength(0) - 3, matrix.GetLength(0) - 1);
}
private static void CheckRowWithSkips(int[,] matrix, int row, int column)
{
if(_skipNextRowCheck)
{
_skipNextRowCheck = false;
return;
}
int element = matrix[row, column];
if (element == matrix[row, column + 1])
{
if(element == matrix[row, column + 2])
{
Console.WriteLine($"Three repeated elements with value {element} are found in row {row} at the positions: [{row}, {column}], [{row}, {column + 1}], [{row}, {column + 2}]");
}
else
{
_skipNextRowCheck = true;
}
}
}
private static void CheckColumnWithSkips(int[,] matrix, int row, int column)
{
if (_skipNextColumnCheck)
{
_skipNextColumnCheck = false;
return;
}
int element = matrix[row, column];
if (element == matrix[row + 1, column])
{
if(element == matrix[row + 2, column])
{
Console.WriteLine($"Three repeated elements with value {element} are found in column {column} at the positions: [{row}, {column}], [{row + 1}, {column}], [{row + 2}, {column}]");
}
else
{
_skipNextColumnCheck = true;
}
}
}
這是一個帶有圖片二維數組的主程序 function,只需將主程序 function 和所有其他函數復制到一個程序class 中即可試用:
static void Main(string[] args)
{
int[,] matrix = new int[8, 8]
{
{ 7, 7, 7, 4, 5, 6, 1, 8 },
{ 1, 4, 3, 4, 3, 9, 3, 8 },
{ 1, 2, 3, 4, 3, 6, 7, 8 },
{ 1, 4, 7, 4, 5, 4, 7, 8 },
{ 1, 2, 3, 4, 5, 5, 3, 5 },
{ 1, 1, 1, 7, 5, 9, 9, 9 },
{ 1, 2, 7, 6, 5, 9, 9, 9 },
{ 1, 2, 3, 4, 5, 9, 9, 9 },
};
Console.WriteLine("\nSearching for three repeated elements in the 2d array:");
FindThreeRepeatedElements(matrix);
Console.WriteLine("\nSearching for three repeated elements in the 2d array, and skipping unneccessary comparisons:");
FindThreeRepeatedElementsWithSkips(matrix);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.