简体   繁体   中英

Spiral Matrix algorithm problem

Hey guys, My code is populating spiral matrix. It works just fine when rows=columns but when different it gives an error on the first bent of the spiral!!! I've tried debugging it with a breakpoint but wasn't able to find anything wrong! So a few extra tips about my code: bentCounter looks for when a row or column is filled and if so it swirls the spiral by incrementing j. When j++ the next elements of arrays B and C are used and thus the direction is changed of the indexes p,q of A array! When we have both filled row followed by column a sub matrix is left so n--; m--; When j=3 it should be nullified to start a new swirl. Hope that's clear enough!

static void Main(string[] args)
        {
            //n - quantity of rows, m - quantity of columns
            // p,q - references to current element of The Matrix A[][]
            // p=1, q=3 ----> A[0][3] - the element of crossing first row and fourth column

            int p = 0;
            int q = 0;
            int j = 0;
            int a = 0;
            int b = 0;
            int bentCounter = 0;

            a = int.Parse(Console.ReadLine());
            b = int.Parse(Console.ReadLine());

            int n = a;
            int m = b;
            int mn = m * n;

            int [,] A = new int [a,b];
            int[] B = new int[] { 0, 1, 0, -1 };
            int[] C = new int[] { 1, 0, -1, 0 };

            for (int i = 0; i < mn ; i++)
            {
                bentCounter++;
                if (bentCounter == n) {j++;}
                if (bentCounter == m + n - 1)
                {
                    if (j == 3) { j = -1; }
                    j++;
                    bentCounter = 0;
                    n--; m--;
                }

                A [p,q] = i;
                p += B[j];
                q += C[j];                              
            }

            for (int r = 0; r < A.GetLength(0); r++)
            {
                for (int c = 0; c < A.GetLength(1); c++)
                {
                    Console.Write(" " + A[r, c] + " ");
                }
                Console.WriteLine();
            }

10x appreciate your help BR

Also, below codes may be useful for those who want to create a spiral matrix with a given size.

static void Main(string[] args)
{
    Console.WriteLine("Enter dimension for spiral matrix:");
    int matrisDim = int.Parse(Console.ReadLine());

    int[,] matris = new int[matrisDim, matrisDim];
    matris.Initialize();

    int apsisIterator = 0, ordinatIterator = 0, sum = 1;
    bool increment = true;

    for (int i = 0; i < matrisDim; i++)
    {
        matris[apsisIterator, ordinatIterator] = sum;
        if (increment)
        {
            while (apsisIterator + 1 < matrisDim && matris[apsisIterator + 1, ordinatIterator] == 0)
                matris[++apsisIterator, ordinatIterator] = ++sum;

            while (ordinatIterator + 1 < matrisDim && matris[apsisIterator, ordinatIterator + 1] == 0)
                matris[apsisIterator, ++ordinatIterator] = ++sum;
        }
        else
        {
            while (apsisIterator > 0 && matris[apsisIterator - 1, ordinatIterator] == 0)
                matris[--apsisIterator, ordinatIterator] = ++sum;

            while (ordinatIterator > 0 && matris[apsisIterator, ordinatIterator - 1] == 0)
                matris[apsisIterator, --ordinatIterator] = ++sum;
        }
        increment = !increment;
    }

    for (int i = 0; i < matrisDim; i++)
    {
        for (int j = 0; j < matrisDim; j++)
            Console.Write(matris[j, i] + "\t");
        Console.WriteLine();
    }
    Console.ReadKey();
}

You can see this codes on Github Gist too: Gist - C# Spiral Matrix

You're incrementing the dimensions the wrong way and going out of bounds, a quick solution is to swap them round so change int [,] A = new int [a,b] into

int [,] A = new int [b,a];

and all is good ;)

EDIT : Also changing this line to pad the output gives you a nice square matrix

Console.Write(" " + A[r, c].ToString().PadLeft(mn.ToString().Length, ' '));

You can also change following

if (bentCounter == n) { j++; }

to

if (bentCounter == m) { j++; }

and it should work fine. The reason is your B and C prefix is organised in that way.

Try it: It is a 100% dynamic spiral matrix for the user.

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <table>
            <tr>
                <td>Total Row Column :</td>
                <td>
                    <input type="text" runat="server" id="txtbox" style="width: 100px;" /></td>
            </tr>
            <tr>
                <td >Starting No :</td>
                <td>
                    <input type="text" runat="server" id="txtstartwith" style="width: 100px;" /></td>
            </tr>
            <tr>
                <td colspan="2" style="text-align:center;">
                    <asp:Button ID="Button1" runat="server" Text="Generate Spiral Matrix" OnClick="Button1_Click" /></td>
            </tr>
        </table>
        <div id="divsp" runat="server">
        </div>
    </form>
</body>
</html>

protected void Button1_Click(object sender, EventArgs e)
        {
            divsp.InnerHtml = "";
            int ignoreMe;
            bool successfullyParsed = int.TryParse(txtbox.Value, out ignoreMe);
            if (successfullyParsed)
            {
                successfullyParsed = int.TryParse(txtstartwith.Value, out ignoreMe);
                if (successfullyParsed)
                {
                    // ...
                }
                else
                {
                    txtstartwith.Value = "0";
                }
            }
            else
            {
                txtbox.Value = "0";
            }

            if (txtbox.Value != "" && txtbox.Value != "0" && Convert.ToInt32(txtbox.Value) > 0 && txtstartwith.Value != "")
            {
                int N = Convert.ToInt32(txtbox.Value);
                int row = N;
                int column = N;

                int[,] A = new int[N, N];
                int ele = N * N;
                ele = ele + (Convert.ToInt32(txtstartwith.Value) - 1);
                int no = Convert.ToInt32(txtstartwith.Value);

                int a = 0;
                int b = 0;

                int bo = 0;
                int le = 0;

                int loopbreak = 0;
                while (no <= ele)
                {
                    for (; b < N; b++)
                    {
                        A[a, b] = no;
                        if (no == ele)
                        {
                            loopbreak = 1;
                            break;
                        }
                        else
                        {
                            no++;
                        }

                    }
                    if (loopbreak == 1)
                    {
                        break;
                    }

                    if (b == N)
                    {
                        b = N - 1;
                        for (; a < b; a++)
                        {
                            int i = a + 1;

                            A[i, b] = no;
                            if (no == ele)
                            {
                                loopbreak = 1;
                                break;
                            }
                            else
                            {
                                no++;
                            }
                        }
                    }
                    if (loopbreak == 1)
                    {
                        break;
                    }
                    if (a == N - 1)
                    {
                        for (; b > le; b--)
                        {
                            int i = b - 1;
                            A[a, i] = no;
                            if (no == ele)
                            {
                                loopbreak = 1;
                                break;
                            }
                            else
                            {
                                no++;
                            }
                        }
                    }
                    if (loopbreak == 1)
                    {
                        break;
                    }
                    if (a == N - 1 && b == bo)
                    {
                        for (; a > le + 1; a--)
                        {
                            int i = a - 1;
                            A[i, b] = no;
                            if (no == ele)
                            {
                                loopbreak = 1;
                                break;
                            }
                            else
                            {
                                no++;
                            }
                        }
                        b = b + 1;
                    }
                    N = N - 1;
                    bo = bo + 1;
                    le = le + 1;
                }
                StringBuilder str = new StringBuilder();


                str.Append("<table>");
                for (int m = 0; m < row; m++)
                {
                    str.Append("<tr>");
                    for (int k = 0; k < row; k++)
                    {
                        str.Append("<td style='padding:5px;text-align:center;'>" + A[m, k].ToString() + "</td>");
                    }
                    str.Append("</tr>");
                }
                str.Append("</table>");
                divsp.InnerHtml = str.ToString().Trim();
            }
        }

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