6
\$\begingroup\$

I have written code for scanning an N x M matrix in spiral order using a recursive function.

It uses 5 parameters - including 2 extra variables:

  • call to keep track of the no. of current call
  • counter to keep track of no. of elements already printed

Example:

For matrix:

1 2 3
4 5 6
7 8 9

For call = 0:
Output: 1 2 3 6 9 8 7 4 counter = 8

For call = 1:
Output: 5 counter = 9

Can the code be improved so that it uses fewer no. of variables and is more efficient?

#include <stdio.h>
#include <stdlib.h>
void spiralscan(int a[][20],int n,int m,int call,int counter)
{
    int i,j;
    if(counter>=n*m)
        return;
    //scan top
    //if(m>call)
    {   printf("\ntop\n");
        for(j=call;j<m-call;j++)
        {printf(" %d ",a[call][j]);
        counter++;
        }
    }
        if(counter>=n*m)
        return;
    //scan right
   // if(n-call>0)
    {   printf("\nright\n");
        for(i=call+1;i<n-call;i++)
        {printf(" %d ",a[i][m-call-1]);
        counter++;
        }
    }
        if(counter>=n*m)
        return;

    //scan bottom
 //   if(m-call>0)
    {   printf("\nbottom\n");
        for(j=m-2-call;j>=call;j--)
        {printf(" %d ",a[n-1-call][j]);
        counter++;
        }
    }
        if(counter>=n*m)
        return;
    //scan left
   // if(call<n/2)
       {   printf("\nleft\n");
        for(i=n-2-call;i>call;i--)
        {printf(" %d ",a[i][call]);
         counter++;
        }
    }
        if(counter>=n*m)
        return;

    spiralscan(a,n,m,call+1,counter);
}
int main()
{
    int n,m,i,j,a[20][20];
    printf("\t\t\tSpiral Scanning\n\n");
    printf("no. of rows : ");
    scanf("%d",&n);
    printf("\nno. of columns : ");
    scanf("%d",&m);
    printf("\nEnter matrix elements : \n");
    for(i=0;i<n;i++)
    {
        for(j=0;j<m;j++)
             scanf("%d",&a[i][j]);
    }
    printf("\n\n\t\tScanning Spirally\n\n");
    spiralscan(a,n,m,0,0);
    return 0;
}
\$\endgroup\$
2
\$\begingroup\$

Your code is very clumped together.

I recommend that you add some spaces to enhance legibility.

For example, this

for(i=0;i<n;i++)

becomes

for(i = 0; i < n; i++)

This is a very disputable topic, but I believe that it is best to use the pre-increment operator over the post-increment operator.

So, this

i++

would become

++i

I say it is better to use the pre-increment operator because the value of whatever variable that is being incremented is immediately incremented; if you use the post-increment operator, the compiler may have to store a value (either the before or incremented) value for after the computation.


You've got a weird line-break thing going on with your for loops.

For example, you wrote this:

for(j=m-2-call;j>=call;j--)
{printf(" %d ",a[n-1-call][j]);
counter++;
}

I'd fix this up by moving a line break after the first { and then indenting the body of the loop.

That would look like this:

for(j=m-2-call;j>=call;j--)
{
    printf(" %d ",a[n-1-call][j]);
    counter++;
}

This is a little nit-picky, but since you aren't taking any command line arguments, I recommend that you put void in the arguments section.

\$\endgroup\$
  • \$\begingroup\$ Thanks for answering! I have one doubt, does this code need any further optimization that would improve its efficiency in terms of time complexity? \$\endgroup\$ – CyberLingo Apr 20 '15 at 2:30
  • \$\begingroup\$ @karma_geek Nothing really jumps out at me that seems to be hurting your efficiency. However, I'm not the handiest when it comes to C. The only thing that might improve efficiency would be to, referring back to my answer, use the pre-increment operator over the post-increment operator. \$\endgroup\$ – SirPython Apr 20 '15 at 2:33
3
\$\begingroup\$

It is very important you indent your code properly as it will make your code easier to read and less prone to errors. This statement in particular is problematic:

if(counter>=n*m)
return;

You should use returns around your if blocks and loops even when they are single-statement bodies, you should indent your code so it is clear the return is part of the if block, and you should use spaces around your operators to make it easier to read:

if(counter >= n * m) {
    return;
}

Right here, you should remove the if, braces, and indentation:

    //scan bottom
 //   if(m-call>0)
    {   printf("\nbottom\n");
        for(j=m-2-call;j>=call;j--)
        {printf(" %d ",a[n-1-call][j]);
        counter++;
        }
    }

It doesn't make sense to have messy, hard-to-read code like this lying around. Also, the final code shouldn't show fixed bugs and commented (dead) code - it should just be the working code and comments stating what it does as needed (I am not an advocate of a comment per line).

You should name your variables better:

void spiralscan(int a[][20],int n,int m,int call,int counter)

What are n and m anyway? Also, you should put spaces after your commas.

It will probably be easier to read your code if you use PascalCase, snake_case, or camelCase to name your variables and functions becausevariableandfunctionnameswithnowordseparatorsarehardtoreadwhenverylong. It seems snake_case is common among C programmers.

\$\endgroup\$
  • \$\begingroup\$ Thanks! Upvoted answer. n and m are the size of matrix (nXm). \$\endgroup\$ – CyberLingo Apr 20 '15 at 2:37
  • \$\begingroup\$ I thought it might be that, but I should have known without asking - that was my point. \$\endgroup\$ – Hosch250 Apr 20 '15 at 3:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.