Thread: Move 0s at top of each column in a MxN array

  1. #1
    Registered User
    Join Date
    Dec 2018
    Posts
    13

    Move 0s at top of each column in a MxN array

    Hello,

    I have a matrix of NxM (the dimensions are set by the user) and I want a function to move 0s at the top of each column, and leave the rest integers as they are. Look at the example:


    Move 0s at top of each column in a MxN array-matrix-png

    After the movement of 0s I want to have:

    0 0 0 2 1
    1 0 3 4 1
    3 0 3 3 1
    3 1 2 1 4
    4 4 5 3 5

    Someone please correct my zerototopMatrix function below:

    Code:
    #include <stdio.h> #include <stdlib.h> 
    #include <time.h>
    
    
    
    
    
    
    void printMatrix(int (*arr), int rows, int cols,int level)
    {
        int i, j;
    
    
        printf("\n");
        printf("\n");
        
        
        printf("The matrix elements are:\n   ");
        for (i = 0; i < cols+level; i++) {
            printf("%d ", i+1);
        } 
           printf("\n");
        for (i = 0; i < (cols*2+1+level); i++) {
            printf("-");
        } 
        printf("-\n");
       for (i = 0; i < rows+level; i++) {
           printf("%d| ", i+1);
                 for (j = 0; j < cols+level; j++) {
                     
             printf("%d ", *(arr + i*cols + j)); 
          }     
          printf("\n");
          
       }
    }
    
    
    
    
    
    
       void zerototopMatrix(int (*arr), int rows, int cols,int level)
    {
        int i, j;
    
    
        printf("\n");
        printf("\n");
        
        int count = 0,temp = 0;
        
        for (j = 0; j < cols+level; j++) {
        for (i = 0; i < rows+level; i++) {
                 
                 if (*(arr + i*cols + j)==0)
    
    
                 {
                 
                
                (*(arr + i*cols + j)= (*(arr + count*cols + j)));
                (*(arr + count*cols + j))=0;
                count++;
            }
                           
          }     
         
          
       }
        
       
       
    }
        
    
    
    
    
    
    
    int main() { 
        
    int number;
    
    
        srand ( time(NULL) );
        int level = 0;
        
        int row,col,colors;
        int points = 0;
        
        
        printf("How many rows:\n");
        scanf("%d", &row);
        
        printf("How many columns:\n");
        scanf("%d", &col);
        
        printf("How many colors:\n");
        scanf("%d", &colors);
        
        
       int *arr = (int *)malloc(row * col * sizeof(int)); 
       int i, j; 
        
    
    
    
    
       for (i = 0; i < row+level; i++) 
          for (j = 0; j < col+level; j++) {
              number = rand() % colors ;
             *(arr + i*col + j) = number;   
        }
       
    
    
       
    
    
       
       printMatrix(arr, row, col,level);
       
       printf("\n\nMove 0s to top:\n");
         zerototopMatrix(arr, row, col,level);
       
        printMatrix(arr, row, col,level);
        
        
       free(arr); 
       return 0; 
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I suggest using array index notation, e.g., *(arr + i*cols + j) would be arr[i*cols + j]. It tends to be easier to read that way.

    Incidentally, this sounds like a situation where bubble sort would be easy to visualise: use a bubble sort on each column to "bubble up" the 0s until no more bubbling is done. More generally (and efficiently if your matrix has enough rows), pretty much any stable sorting algorithm to sort the 0s before the other values would work.

    EDIT:
    Okay, thinking about this a bit more, general sorting would be overkill. Maybe a solution inspired more by counting sort: start from the bottom of each column with a read and a write pointer. If the read pointer points to a 0, move the read pointer up one element in the column, and increment a counter. Otherwise, write the element at the read pointer to the element at the write pointer (if the counter is non-zero), then move both read and write pointers up by one. When the read pointer reaches the top of the column, use the counter with the write pointer to fill in the remaining top of the column with 0s.

    I say read and write pointers, but you don't actually need to use pointers; array indices will do.
    Last edited by laserlight; 05-11-2019 at 12:32 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Dec 2018
    Posts
    13
    Quote Originally Posted by laserlight View Post
    I suggest using array index notation, e.g., *(arr + i*cols + j) would be arr[i*cols + j]. It tends to be easier to read that way.

    Incidentally, this sounds like a situation where bubble sort would be easy to visualise: use a bubble sort on each column to "bubble up" the 0s until no more bubbling is done. More generally (and efficiently if your matrix has enough rows), pretty much any stable sorting algorithm to sort the 0s before the other values would work.

    EDIT:
    Okay, thinking about this a bit more, general sorting would be overkill. Maybe a solution inspired more by counting sort: start from the bottom of each column with a read and a write pointer. If the read pointer points to a 0, move the read pointer up one element in the column, and increment a counter. Otherwise, write the element at the read pointer to the element at the write pointer (if the counter is non-zero), then move both read and write pointers up by one. When the read pointer reaches the top of the column, use the counter with the write pointer to fill in the remaining top of the column with 0s.
    laserlight Thank you for your help!!! ... nice saying.... but I can't do that. Will you write a few sentences of code for me, and correct my code?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What have you tried?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Dec 2018
    Posts
    13
    Quote Originally Posted by laserlight View Post
    What have you tried?

    OK! I found my error and corrected it. Thank you. Case closed!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 11-11-2018, 07:31 PM
  2. sorting a 2d array by column
    By antros48 in forum C Programming
    Replies: 4
    Last Post: 10-24-2013, 09:11 AM
  3. Subtracting one column in a 2d array from another?
    By zaihed13 in forum C Programming
    Replies: 6
    Last Post: 10-19-2013, 09:29 AM
  4. Adding a new column in array
    By Tomislav Pti in forum C Programming
    Replies: 3
    Last Post: 11-22-2012, 04:48 AM
  5. Replies: 6
    Last Post: 12-09-2010, 06:27 PM

Tags for this Thread