C# 像蛇一样打印矩阵

C# 像蛇一样打印矩阵,c#,matrix,spiral,C#,Matrix,Spiral,我要用C#像蛇一样打印一个矩阵,类似这样的东西。对如何进行有什么建议吗 1 2 3 4 5 6 6 1 2 3 4 6 1 4 6 1 4 6 1 4 6 1 3 4 6 1 6 1 2 3 4 5 6 这是我到目前为止的代码。基本上,我需要弄清楚如何跳过行和列 Console.WriteLine("Enter your number: "); int n = Convert.ToInt32

我要用C#像蛇一样打印一个矩阵,类似这样的东西。对如何进行有什么建议吗

1 2 3 4 5 6 
          6
1 2 3 4   6
1     4   6
1     4   6
1     4   6 
1   3 4   6
1         6
1 2 3 4 5 6
这是我到目前为止的代码。基本上,我需要弄清楚如何跳过行和列

Console.WriteLine("Enter your number: ");
        int n = Convert.ToInt32(Console.ReadLine());
        int[,] a = new int[n, n];
        int printVal = 1;
        int c1 = 0, c2 = n - 1;
        while(printVal <= n * n)
        {
            //dvizenje na desno
            for (int i = c1; i <= c2; i++)
                a[c1, i] = printVal++;

            //dvizenje nadolu
            for (int j = c1 + 1; j <= c2; j++)
                a[j, c2] = printVal++;

            // dvizenje na levo
            for (int i = c2 - 1; i >= c1; i--)
                a[c2, i] = printVal++;

            //dvizenje nagore
            for (int j = c2 - 1; j >= c1 + 1; j--)
                a[j, c1] = printVal++;
            c1++;
            c2--;
        }
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                Console.Write(a[i, j] + "\t");
            }
            Console.WriteLine();
        }
Console.WriteLine(“输入您的号码:”);
int n=Convert.ToInt32(Console.ReadLine());
int[,]a=新的int[n,n];
int printVal=1;
int c1=0,c2=n-1;

虽然(printVal类似的东西,它还没有完成,可以更有效,但它是想法(构建器设计模式)

公共类编号
{
私家侦探;
公开编号()
{
sb=新的StringBuilder();
}
公共无效地址编号(整数编号)
{
对于(int i=1;i
作为一个快速练习,我制作了完整的版本。如果有人感兴趣,请看以下内容:

enum Directions { Right, Down, Left, Up }

Dictionary<Directions, Point> moves = new Dictionary<Directions, Point>
{
    { Directions.Right, new Point(1, 0) },
    { Directions.Down,  new Point(0, 1) },
    { Directions.Left,  new Point(-1,0) },
    { Directions.Up,    new Point(0,-1) },
};

int?[,] MakeSpiral(int rows, int columns)
{
    int?[,] field = new int?[rows, columns];

    Point current = new Point(0, 0);
    Directions direction = Directions.Right;

    while(true)
    {
        field[current.Y, current.X] = current.X + 1;
        Point next = current + moves[direction];

        if(!IsFieldPositionValid(next, current))
        {
            // If we can't make a move, change direction clockwise
            direction = (Directions)((int)(direction + 1) % 4);
        }

        next = current + moves[direction];

        if(!IsFieldPositionValid(next, current))
        {
            // If we can't make a move after changing the direction
            // it means that we are stuck and we completed the spiral
            return field;
        }

        current = next;
    }

    // Checks whether we can put a value in a given position
    // taking into consideration whether it is out of bounds of the field 
    // and if it's too close to other values
    bool IsFieldPositionValid(Point position, Point previous)
    {
        if(IsFieldPositionOutOfBounds(position))
            return false;

        if(!CheckSurroundings(position, point => !field[point.Y, point.X].HasValue, previous))
            return false;

        return true;
    }

    // Checks the positions in 4 directions using the isValid predicate.
    // Doesn't check the point that is given as the exclude parameter:
    // this is used so that we don't count the point we just moved from
    bool CheckSurroundings(Point position, Predicate<Point> isValid, Point? exclude = null)
    {
        foreach(Point move in moves.Values)
        {
            Point newPosition = position + move;
            if(IsFieldPositionOutOfBounds(newPosition))
                continue;
            if(!isValid(newPosition) && (!exclude.HasValue || exclude.Value != newPosition))
                return false;
        }

        return true;
    }

    bool IsFieldPositionOutOfBounds(Point position)
    {
        return position.Y >= field.GetLength(0) || position.X >= field.GetLength(1) || position.Y < 0 || position.X < 0;
    }    
}

它不适用于大于11的值。下一个版本(稍微复杂一些)适用于:

var spiral = Spiral(14, 24);
for(int i = 0; i < spiral.GetLength(0); i++)
{
    for(int j = 0; j < spiral.GetLength(1); j++)
    {
        Console.Write(spiral[i, j]?.ToString() ?? new string(' ', (j + 1).ToString().Length));
        Console.Write(" ");
    }
    Console.WriteLine();
}

它需要一个来自某处的
结构,如果您不想导入任何依赖项,我也为此做了一个基本实现:

struct Point : IEquatable<Point>
{
    public int X { get; set; }
    public int Y { get; set; }
    public Point(int x, int y) { X = x; Y = y; }

    public static Point operator +(Point left, Point right) => new Point(left.X + right.X, left.Y + right.Y);
    public static Point operator -(Point point) => new Point(-point.X, -point.Y);
    public static Point operator -(Point left, Point right) => left + -right;
    public static bool operator ==(Point left, Point right) => left.Equals(right);
    public static bool operator !=(Point left, Point right) => !left.Equals(right);

    public bool Equals(Point point) => this.X == point.X && this.Y == point.Y;
    public override bool Equals(object other) => other is Point p ? Equals(p) : false;
    public override int GetHashCode() => unchecked(17 * (X + 31 * Y));
}
struct Point:IEquatable
{
公共整数X{get;set;}
公共整数Y{get;set;}
公共点(intx,inty){x=x;y=y;}
公共静态点操作符+(左点,右点)=>新点(左.X+右.X,左.Y+右.Y);
公共静态点操作符-(Point Point)=>新点(-Point.X,-Point.Y);
公共静态点操作符-(左点、右点)=>左+右;
公共静态布尔运算符==(点左,点右)=>左.等于(右);
公共静态布尔运算符!=(左点,右点)=>!左。等于(右);
公共bool=s(Point-Point)=>this.X==Point.X&&this.Y==Point.Y;
公共覆盖布尔等于(对象其他)=>其他为点p?等于(p):false;
public override int GetHashCode()=>未选中(17*(X+31*Y));
}

请出示你的代码。你尝试过什么。目的是什么?@CalculatingMachine我编辑了这篇文章,你可以看到我到目前为止有什么,但我不知道如何跳过行和列。@LeonBarkan-这是我的教授为整个小组布置的作业。我是我学习的第一年。@MongZhu我刚刚添加了代码。很抱歉…Th至少应该解决您的问题。如果用户键入9或11,会发生什么情况?@Mong Zhu如我所说,这是解决该问题的一个想法,但尚未完成(为了解决您的质疑,我们需要利益相关者提供的信息)。始终欢迎根据您的需要添加valitation
1 2 3 4 5 6 
          6 
1 2 3 4   6 
1     4   6 
1     4   6 
1     4   6 
1   3 4   6 
1         6 
1 2 3 4 5 6 
var spiral = Spiral(14, 24);
for(int i = 0; i < spiral.GetLength(0); i++)
{
    for(int j = 0; j < spiral.GetLength(1); j++)
    {
        Console.Write(spiral[i, j]?.ToString() ?? new string(' ', (j + 1).ToString().Length));
        Console.Write(" ");
    }
    Console.WriteLine();
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 
                                                            24 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22    24 
1                                                     22    24 
1   3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20    22    24 
1   3                                           20    22    24 
1   3   5 6 7 8 9 10 11 12 13 14 15 16 17 18    20    22    24 
1   3   5                                 18    20    22    24 
1   3   5                                       20    22    24 
1   3   5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20    22    24 
1   3                                                 22    24 
1   3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22    24 
1                                                           24 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 
struct Point : IEquatable<Point>
{
    public int X { get; set; }
    public int Y { get; set; }
    public Point(int x, int y) { X = x; Y = y; }

    public static Point operator +(Point left, Point right) => new Point(left.X + right.X, left.Y + right.Y);
    public static Point operator -(Point point) => new Point(-point.X, -point.Y);
    public static Point operator -(Point left, Point right) => left + -right;
    public static bool operator ==(Point left, Point right) => left.Equals(right);
    public static bool operator !=(Point left, Point right) => !left.Equals(right);

    public bool Equals(Point point) => this.X == point.X && this.Y == point.Y;
    public override bool Equals(object other) => other is Point p ? Equals(p) : false;
    public override int GetHashCode() => unchecked(17 * (X + 31 * Y));
}