Click here to Skip to main content
15,885,985 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
I Have this code is receive the array from TextBox and then print it in the clockwise ,but doesn't print in correct way when I make trace to this code I Don't have error but when run it don't show the result in a clockwise I Don't know where the error

C#
int i, k = 0, l = 0;
int m=4; 
int n=4;

/*  k - starting row index
    m - ending row index
    l - starting column index
    n - ending column index
    i - iterator
*/


string [,]a = new string[4,4];
string s = null;

for(int q=0;q<=4;q++){
    for(int j=0;j<=4;j++){
        a[q,j] = textBox1.Text[q].ToString();
    }
}

while (k < m && l < n)
{
    /* Print the first row from the remaining rows */
    for (i = l; i < n; i++)
    {
        s += a[k, i].ToString();
    }

    k++;

    /* Print the last column from the remaining columns */
    for (i = k; i < m; i++)
    {
        s += a[i, n - 1].ToString();
    }
    n--;

    /* Print the last row from the remaining rows */
    if (k < m)
    {
        for (i = n - 1; i >= l; i--)
        {
            s += a[m - 1, i].ToString();
        }
        m--;
    }

    /* Print the first column from the remaining columns */
    if (l < n)
    {
        for (i = m - 1; i >= k; i--)
        {
            s += a[i, l].ToString();
        }
        l++;
    }
    richTextBox1.Text = s.ToString();
}
Posted
Comments
Maciej Los 30-Nov-14 16:02pm    
See this algorithm: Rotate a matrix 90 degrees clockwise[^] and follow the link on bottom of related page.
BillWoodruff 30-Nov-14 17:15pm    
Might help if you describe exactly what you mean by "clockwise" here and how that translates into a linear rendering (all text on line, reading left-to-right).
[no name] 30-Nov-14 17:26pm    
send
help
soon
Iwant print in this way
sendpnooshel
BillWoodruff 30-Nov-14 17:39pm    
Yes, I saw that, before. It's still not clear to me what principle you want to apply. Try explaining this to a small child :)
Sergey Alexandrovich Kryukov 30-Nov-14 22:57pm    
did
you
see
the
previous
comment?

1 solution

EDIT 1: Added an alternative method body

Hi.

Here is my solution.

You will find 3 overloaded methods to accept a 2D matrix of all chars (char[,]), a list of lines (string[]), a text (string).
The char[,] overload is the only doing the computation (the others two delegates to it).

C#
static string RebuildClockwise(string text)
{
    // Delegate computation to "string[]" overload
    var result = RebuildClockwise(text.Split(new[] { Environment.NewLine }, StringSplitOptions.None));
    return result;
}
static string RebuildClockwise(params string[] lines)
{
    // Fetch total counts of rows/lines and columns (max length of all lines)
    var nRowCount = lines.Length;
    var nColCount = lines.Max(line => line.Length);
    // Loop all lines with lesser length and pad them with spaces
    for (int ixLine = 0; ixLine < lines.Length; ixLine++)
    {
        var line = lines[ixLine];
        if (line.Length < nColCount)
            lines[ixLine] = line.PadRight(nColCount);
    }
    // Translate the lines into chars
    var chars = new char[nRowCount, nColCount];
    for (int ixRow = 0; ixRow < nRowCount; ixRow++)
    {
        for (int ixCol = 0; ixCol < nColCount; ixCol++)
        {
            chars[ixRow, ixCol] = lines[ixRow][ixCol];
        }
    }
    // Delegate computation to "char[,]" overload
    var result = RebuildClockwise(chars);
    return result;
}
static string RebuildClockwise(char[,] chars)
{
    // Fetch total count of chars for loop safety
    var nTotalCount = chars.GetLength(0) * chars.GetLength(1);

    // Store the limits
    var aLimits = new int[4];
    aLimits[Dir_Right] = chars.GetLength(1) - 1;
    aLimits[Dir_Down] = chars.GetLength(0) - 1;
    aLimits[Dir_Left] = 0;
    aLimits[Dir_Up] = 0;

    var result = string.Empty;

    // Start at Top Left corner (0,0) pointing Right
    var ixCol = 0;
    var ixRow = 0;
    var nDirection = Dir_Right;
    // For safety, check the count of processed chars to avoid infinite loop
    for (var nProcessedCount = 0; nProcessedCount < nTotalCount; nProcessedCount++)
    {
        result += chars[ixRow, ixCol];

        if (!RebuildClockwise_Move(aLimits, ref nDirection, ref ixCol, ref ixRow))
            break;
    }

    return result;
}


The main function (RebuildClockwise(char[,] chars)), first stores the matrix limits and initializes the direction and cell location to start with.
Then loops updating the result and calling another function (RebuildClockwise_Move) that changes the cell location and direction.

C#
private static bool RebuildClockwise_Move(int[] aLimits, ref int nDirection, ref int ixCol, ref int ixRow)
{
    // Try all 4 directions
    for (var nTrial = MinDir + 1; nTrial <= MaxDir + 1; nTrial++)
    {
        switch (nDirection)
        {
            case Dir_Right:
                // There are still unprocessed columns on the Right
                if (ixCol < aLimits[nDirection])
                {
                    // Select next column to the Right
                    ixCol++;
                    return true;
                }

                // If we get here, then we have exhasuted all the Columns for the current Row: discard current Row
                aLimits[(nDirection + 3) % 4]++;
                break;
            case Dir_Down:
                // There are still unprocessed rows Below
                if (ixRow < aLimits[nDirection])
                {
                    // Select next row to Below
                    ixRow++;
                    return true;
                }

                // If we get here, then we have exhasuted all the Rows for the current Column: discard current Column
                aLimits[(nDirection + 3) % 4]--;
                break;
            case Dir_Left:
                // There are still unprocessed columns on the Left
                if (ixCol > aLimits[nDirection])
                {
                    // Select next column to the Left
                    ixCol--;
                    return true;
                }

                // If we get here, then we have exhasuted all the Columns for the current Row: discard current Row
                aLimits[(nDirection + 3) % 4]--;
                break;
            case Dir_Up:
                // There are still unprocessed rows Above
                if (ixRow > aLimits[nDirection])
                {
                    // Select next row to Above
                    ixRow--;
                    return true;
                }

                // If we get here, then we have exhasuted all the Rows for the current Column: discard current Column
                aLimits[(nDirection + 3) % 4]++;
                break;
        }

        // Pick the next (clockwise) direction
        nDirection++;
        if (nDirection > MaxDir)
            nDirection = MinDir;
    }

    // We Tried all directions, then we are at the center of the matrix and should stop
    return false;
}


RebuildClockwise_Move, based on the direction, change the row and/or column index and updates the limits.
When no row or column is available, it returns false to stop looping.

Both methods make use of some constants to manage the direction:

C#
const int Dir_Right = 0;
const int Dir_Down = Dir_Right + 1;
const int Dir_Left = Dir_Down + 1;
const int Dir_Up = Dir_Left + 1;
const int MinDir = 0;
const int MaxDir = 3;


The following test code allow to check the computation is correct:

C#
MessageBox.Show(RebuildClockwise("1234", "CDE5", "BGF6", "A987"));
MessageBox.Show(RebuildClockwise("12345", "EFGH6", "DKJI7", "CBA98"));
MessageBox.Show(RebuildClockwise("1234", "EFG5", "DKH6", "CJI7", "BA98"));
MessageBox.Show(RebuildClockwise("12345678"));
MessageBox.Show(RebuildClockwise("1234", "8765"));
MessageBox.Show(RebuildClockwise("12", "83", "74", "65"));
MessageBox.Show(RebuildClockwise("1", "2", "3", "4", "5", "6", "7", "8"));


They should display a text between 12345678 and 123456789ABCDEFGHIJK (the input values are arranged in order to obtain an understandable result).

Overall, this solution is more generalized (and complex) than your sample code but it can be simplified replacing the aLimits array and the switch block with code using constants or plain variables.

Regards,
Daniele.

EDIT 1: The following functions is an alternative to the char[,] overload.
This one will use two concurrent variables to move row and column instead of relying on the nDirection variable; this version also incorporate the movement logic.

C#
static string RebuildClockwise(char[,] chars)
{
    // Fetch maximum column and row indices
    var nMaxCol = chars.GetLength(1) - 1;
    var nMaxRow = chars.GetLength(0) - 1;
    // Fetch total count of chars for loop safety
    var nTotalCount = (nMaxRow + 1) * (nMaxCol + 1);

    var result = string.Empty;

    // Fixed minimum column and row indices
    var nMinCol = 0;
    var nMinRow = 0;
    // Start at 0,0
    var ixCol = 0;
    var ixRow = 0;
    // Initial direction is Col++ (toward Right)
    var nDeltaCol = 1;
    var nDeltaRow = 0;

    // For safety, check the count of processed chars to avoid infinite loop
    for (var nProcessedCount = 0; nProcessedCount < nTotalCount; nProcessedCount++)
    {
        result += chars[ixRow, ixCol];

        var bMoved = false;
        // Try all 4 directions
        for (var nTrial = 1; nTrial <= 4; nTrial++)
        {
            // Compute new location
            var ixColN = ixCol + nDeltaCol;
            var ixRowN = ixRow + nDeltaRow;
            // If location is within min and max, then accept it
            if ((ixColN >= nMinCol) && (ixColN <= nMaxCol) && (ixRowN >= nMinRow) && (ixRowN <= nMaxRow))
            {
                ixCol = ixColN;
                ixRow = ixRowN;

                // Tell outside of for loop that the new location has been found
                bMoved = true;
                break;
            }

            // If location is beyond min column, discard (current) max row
            if (ixColN < nMinCol)
                nMaxRow--;
            // If location is beyond max column, discard (current) min row
            else if (ixColN > nMaxCol)
                nMinRow++;
            // If location is beyond min row, discard (current) min column
            else if (ixRowN < nMinRow)
                nMinCol++;
            // If location is beyond max row, discard (current) max column
            else if (ixRowN > nMaxRow)
                nMaxCol--;

            // Rotate increments (they are like cosine and sine of angles 0, 90, 180, 270)
            var nTemp = nDeltaCol;
            nDeltaCol = -nDeltaRow;
            nDeltaRow = nTemp;
        } 
        // We Tried all directions, then we are at the center of the matrix and should stop
        if (!bMoved)
            break;
    }

    return result;
}
 
Share this answer
 
v3
Comments
[no name] 11-Dec-14 8:01am    
@Daniele Rota Nodari ,thank u so much but this code is very hard for me ,my code is easier I can understand it ,can u discover where the error in it because when trasing it I don't have any error ,thanks again
Daniele Rota Nodari 11-Dec-14 9:47am    
It seem I overlooked your problem.

It could be that all your problems are within the initial loop.

for(int q=0;q<=4;q++){
for(int j=0;j<=4;j++){
a[q,j] = textBox1.Text[q].ToString();
}
}

try to rewrite it as

var asLines = textBox1.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
for(int q=0;q<=4;q++){
for(int j=0;j<=4;j++){
a[q,j] = asLines[q][j].ToString();
}
}

Let me know the result

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900