检查2D数组中某些元素是否相等C#Sharp [英] Check if some elements are equal in 2D array c# sharp

查看:106
本文介绍了检查2D数组中某些元素是否相等C#Sharp的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出数组:

string [,] arr =新字符串[n,n]. 如何检查每一行,每一列和两个对角线的元素是否相等?

string[,] arr = new string[n,n]. How do you check if the elements are equal for each row, for each column and for the two diagonals?

这是一种井字游戏:编写一个控制台应用程序,以输入X和0的N个移动作为坐标作为输入日期. (0,0)是左上角,(2,2)是右下角.第一行是移动数N,第二行是移动,每行一个.第一个动作是玩家的X动作,然后是玩家的0动作,然后是X动作,依此类推. . 这是我尝试过的,但没有结果:

It is a kind of tic tac toe: Write a console application that receives as input date N moves of X and 0 as coordinates. (0, 0) is the top left corner and (2, 2) is the bottom right corner. On the first line is the number of moves N, and from line two there are moves, one on each line. The first move is of the player with X, followed by the move of the player with 0, then again X and so on.The application will analyze the received moves and will display the winner: X, 0 or draw if there is no winner. This is what i tried, but no result:

static void Main()
    {
        int numberOfMoves = Convert.ToInt32(Console.ReadLine());
        const int size = 3;
        string[,] boardGame = new string[size, size];
        for (int i = 0; i < numberOfMoves; i++)
        {
            string strCoordinates = Console.ReadLine();
            string[] lineCoordinates = strCoordinates.Split(' ');
            int coordinateX = Convert.ToInt32(lineCoordinates[0]);
            int coordinateY = Convert.ToInt32(lineCoordinates[1]);
            const int value = 2;
            boardGame[coordinateX, coordinateY] = i % value == 0 ? "X" : "0";
        }

        // CheckElements(boardGame); in construction
        Console.Read();
    }

    static void CheckRows(int x, int y)
    {
        string[,] boardGame = new string[3, 3];
        int cols = boardGame.GetLength(1);
        const int value = 2;
        for (int i = 0; i < cols; i++)
        {
            if ((boardGame[0, 0] == boardGame[0, 1] && boardGame[0, 1] == boardGame[0, value]) || (boardGame[1, 0] == boardGame[1, 1] && boardGame[1, 1] == boardGame[1, value]))
            {
                Console.WriteLine(boardGame[0, 0]);
            }

            if ((boardGame[1, 0] == boardGame[1, 1] && boardGame[1, 1] == boardGame[1, value]) || (boardGame[value, 0] == boardGame[value, 1] && boardGame[value, 1] == boardGame[value, value]))
            {
                Console.Write(boardGame[0, 0]);
            }
        }

        Console.WriteLine(boardGame[x, y]);
    }

    static void CheckColumns(int x, int y)
    {
        string[,] boardGame = new string[3, 3];
        int rows = boardGame.GetLength(0);
        const int value = 2;
        for (int i = 0; i < rows; i++)
        {
            if ((boardGame[0, 0] == boardGame[1, 0] && boardGame[1, 0] == boardGame[value, 0]) || (boardGame[0, 1] == boardGame[1, 1] && boardGame[1, 1] == boardGame[value, 1]))
            {
                Console.WriteLine(boardGame[0, 0]);
            }

            if ((boardGame[0, 1] == boardGame[1, 1] && boardGame[1, 1] == boardGame[value, 1]) || (boardGame[0, value] == boardGame[1, value] && boardGame[1, value] == boardGame[value, value]))
            {
                Console.WriteLine(boardGame[0, 1]);
            }
        }

        Console.WriteLine(boardGame[x, y]);
    }

    static void CheckDiagonals(int x, int y)
    {
        string[,] boardGame = new string[3, 3];
        int m = boardGame.Length;
        const int value = 2;
        for (int i = 0; i < m; i++)
        {
            m--;
            for (int j = 0; j < m; j++)
            {
                if (boardGame[0, 0] == boardGame[1, 1] && boardGame[1, 1] == boardGame[value, value])
                {
                    Console.WriteLine(boardGame[0, 0]);
                }
            }
        }

        Console.WriteLine(boardGame[x, y]);
    }

推荐答案

鉴于方阵,有一种方法可以在单个循环中进行所有检查. 但是在进行优化之前,我们先清理和简化.

Given a square matrix there is a way to do all the check in a single loop. But before going for optimisation let's clean up and simplify.

给出以下方阵,可能很难通过换位找到获胜者.

Given the following square matrix, It may be hard to make all commutation to find the winner.

var input = new [,]{
    {"x","x","x"},
    {"x","x","o"},
    {"x","o","o"},
};

但是,如果我们能够切成行,列和对角线. 在给定{"x","x","x"},{"x","x","o"}的情况下,更容易找到赢家.

But if we were able to slice into Rows, Column, and Diagonals . It will be easier to to find a winner given {"x","x","x"}, or {"x","x","o"}.

根据您先前的问题b,您已经在2D数组上可以使用GetLength(1)GetLength(0)来计算列数和行数.

Based on your previous questionb you already that on a 2D array we can num the number of Cols and Rows using GetLength(1) and GetLength(0).

在此示例中,第一行索引为:
{ (0,0), (0,1), (0,2) }.

For this example the first row indexes are :
{ (0,0), (0,1), (0,2) }.

static string[] GetRow(string[,] source, int rowNumber)
{
    var rows = source.GetLength(0);
    var result = new string[rows];
    for (int i = 0; i < rows; i++)
    {
        result[i] = source[rowNumber, i];
    }
    return result;
}

自然,对于列,我们将具有相同的代码:

Naturally for columns we will have the same code:

static string[] GetColumn<T>(string[,] source, int columnNumber)
{
    var cols = source.GetLength(1);
    var result = new string[cols];
    for (int i = 0; i < cols; i++)
    {
        result[i] = source[i, columnNumber];
    }
    return result;
}

对角线

使用 https://en.wikipedia.org/wiki/Main_diagonal.
主要对角线索引将为{(0,0) , (1,1), (2,2)}.
看起来像是同一循环,但带有(i,i)

Diagonals

Lets name the diagonal using https://en.wikipedia.org/wiki/Main_diagonal.
The main diagonal indexes will be {(0,0) , (1,1), (2,2)}.
It's look like the same loop but with (i,i)

string[] GetSquareMatrixMainDiagonal(string[,] source)
{// {(0,0) , (1,1), (2,2)}

    var cols = source.GetLength(0);
    var rows = source.GetLength(1);
    if (cols != rows) // diagonal will not work on not square matrix.
        throw new ArgumentException($"2D Array [{rows},{cols}], is not a Square matrix");

    var result = new string[rows];
    for (int i = 0; i < rows; i++)
    {
        result[i] = source[i, i];
    }
    return result;
}

对于对角线索引将为{(0,2) , (1,1), (2,0)}.
行从0开始递增. 1> 2.
而专栏做的恰恰相反. 2> 1> 0

For the Anti Diagonal indexes will be {(0,2) , (1,1), (2,0)}.
Rows is incrementing from 0 > 1 > 2.
While columns are doing the contrary. 2 > 1 > 0

static string[] GetSquareMatrixAntiDiagonal(string[,] source)
{
    var cols = source.GetLength(0);
    var rows = source.GetLength(1);
    if (cols != rows) throw new ArgumentException($"2D Array [{rows},{cols}], is not a Square matrix");

    var result = new string[rows];
    var row = 0;
    var col = rows - 1;
    for (int i = 0; i < rows; i++)
    {
        result[i] = source[row++, col--];
    }
    return result;
}

以下是获取行,列和对角线的简单示例:
https://dotnetfiddle.net/FjPIqY

Here a simple example of getting Rows, Columns and Diagonals:
https://dotnetfiddle.net/FjPIqY

现在,我们有了一种方法来获取像{"x","x","o"}这样的2d数组的Slice.我们需要比较数组中所有元素的方法,以发现它们是否相同. 我们将保存第一个元素的值.并检查其他所有条件是否都相等.

Now that we have a way to get Slice of the 2d array like {"x","x","o"}. We need way to compare all the elment of an array to find if they are the same. We will save the value of the first element. And check if All the others are equals to it.

static string Winner(string[] source)
{
    var val = source.First();
    var isTheSame = source.Skip(1).All(x => x == val);
    return isTheSame ? val : default(string);
}    

小心,这将返回空值作为{"","",""}上的赢家. 但是我们可以在最终检查中简单地排除这一点.

Carefull this will return empty value as a winner on {"","",""}. But we can simply rules this one out in the final check.

这是没有LinQ的另一个版本.并正确处理空单元格的空字符串和默认值. 免责声明:此方法中使用的有效符号与小提琴输入不匹配.

Here is an other version without LinQ. And proper handling of empty string and default value fo an empty cell. Disclaimer: valid symbols used in this method does not match the fiddle input.

static bool CheckWinner(string[] source, out string winnerSymbol)
{
    winnerSymbol= "-"; // "-", arbitrary representation of an empty cell. 1 char for simple layout.
    
    var firstVal = source[0];
    for(int i = 1; i < source.Length; i++){ 
        if(source[i] != firstVal){
            return false;
        }
    }
    
    // Will be nice to have valid Symbols in an array.
    if(firstVal!= "0" && firstVal != "X"){      
        return false;
    }
    
    winnerSymbol = firstVal;
    return true;
}

static void ExampleUsageOf_CheckWinner(){
    var winInput= new []{"0","0","0"};  
    var looseInput= new []{"0","0","X"};


    if(CheckWinner(winInput, out string winnerSymbol)){
        Console.WriteLine( winnerSymbol +"is a Winner in winInput")
    }
    else{
        Console.WriteLine( "No winner in winInput!")
    }
    
    
    if(CheckWinner(looseInput, out string winnerSymbol)){
        Console.WriteLine( winnerSymbol +"is a Winner in looseInput")
    }
    else{
        Console.WriteLine( "No winner in looseInput!")
    }
} 

重新分解

所有方法的工作方式相同:循环行或列数. 但是在平方矩阵中,行数和列数是相同的..
为了获得所有行,我们将需要一个循环以便不写:

Re Factorisation

All methode work the same way: A loop on number of rows or columns. But in a square matric number of rows and column are the same..
In order to get All the row we will need a loop in order to not write:

var r1 = GetRow(input, 0);
var r2 = GetRow(input, 1);
var r3 = GetRow(input, 2);

如果您重命名行数或列数",变成大小.在检查它是一个方矩阵之后. 每个方法都可能处于同一循环中.让我们尝试合并GetRowGetColumn进行说明:在第一行和第一列中使用col_row_index = 0;.

If you rename the "number of rows or columns" into size. After checking that it's a square matrix. Every methods may be able to be in the same loop. Let try to merge GetRow and GetColumn to illustrate: with col_row_index = 0; for the first row and column.

var size = source.GetLength(0);

var currentColumn = new string[size]; // old result variable
var currentRow = new string[size];    // old result variable

for (int i = 0; i < size; i++)
{
    currentColumn[i] = source[i, col_row_index];
    currentRow[i] = source[col_row_index, i];
}

我们现在可以检查其中一个是否是获胜者:

We now can check if one of them is the winner :

var winnerC = Winner(currentColumn);
var winnerR = Winner(currentColumn);

if(winnerC != ""){
    // Stop everything! We have a winner 
    // Console.WriteLine + Break, if we are in a loop.
    // Set a boolean to true, if we use some State machine.
    // Return if we are in method
}

if(winnerR != ""){ // Same
}

示例.

我让您对角线进行合并.并且您应该能够进行较小的修改就可以对整个电路板进行检查.

I let you do the merge for the diagonal. And you should be able to do the whole board checking with minor modification.

这篇关于检查2D数组中某些元素是否相等C#Sharp的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆