Thread: urgent help with sorting a two D array

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    4

    urgent help with sorting a two D array

    Hi all I need to get in an assignment to night, and I cant get a 2 D array to sort correctly. The arry has 5 columbs and 10000 rows. The columbs are Postcode, Month, Year, Bedrooms and Price. I have to sorted in ascending order according by price, then if 2 prices are the same then year, then if 2 prices and years are the same then month, and the same for then postcode and last bedrooms.

    This is how the data is when it is put in,

    | Postcode Month Year Bedrooms Price |
    +----------------------------------------+
    | 2081 12 2007 4 795500 |
    | 2180 07 2009 6 165000 |
    | 2140 12 2008 5 689000 |
    | 2153 03 2008 4 491500 |
    | 2140 02 2010 5 886500 |
    | 2005 11 2007 4 776500 |
    | 2151 07 2007 5 305500 |
    | 2199 12 2010 5 895000 |
    | 2101 04 2010 7 389500 |
    | 2176 02 2008 2 959500 |



    and this is what it is like afte the sort, it seem that bedrooms and postcodes do not move with the others.

    +========================================+
    | Postcode Month Year Bedrooms Price |
    +----------------------------------------+
    | 2151 07 2009 5 165000 |
    | 2180 07 2007 6 305500 |
    | 2101 04 2010 7 389500 |
    | 2153 03 2008 4 491500 |
    | 2081 12 2008 4 689000 |
    | 2005 11 2007 4 776500 |
    | 2140 12 2007 5 795500 |
    | 2140 02 2010 5 886500 |
    | 2199 12 2010 5 895000 |
    | 2176 02 2008 2 959500 |

    What I believe to the relevent bits of code are below

    Code:
    #include <stdio.h>
    #define ROWS 10000
    #define COLUMNS 5
    
    void printHeader (void);
    void printTable (int realestate[ROWS][COLUMNS], int i, int j);
    void printStage (int stage);
    void swap(int realestate[ROWS][COLUMNS] , int i, int k);
    
    //int improve_order(int[][COLUMNS], int);
    
    int main(int argc, char *argv[]) {
        int tallyCount[10000]={0};
        int realEstate[ROWS][COLUMNS];
        int postSum[10000]={0};
        int avgPostSum[10000]={0};
        int yearCount[3000][2]= {{0}};
        int median[200]={0};
        int swapped1=1;
        int yearSum=0;
        int i, j, k, l;
        int num=1;
        int numberrow;
        char c=0;
                              //Ignores the headers//
        while(c != '\n') {
            scanf("%c", &c);
        }
    
        for(i=0; (i<ROWS && num==1); i=i+1) {
            for(j=0; j<COLUMNS; j=j+1) {
                num=scanf("%8d", &realEstate[i][j]);
            }
        }
    
        numberrow=i-1;
    
        for(i=0; i<numberrow; i=i+1) {
            for(l=1000;l<9999;l=l+1) {
                if(realEstate[i][0]==l) {
                    tallyCount[l]=tallyCount[l]+1;
                    postSum[l]=(postSum[l]+realEstate[i][4]);
                }
            }
        }
    
        
    
         while (swapped1==1){
                swapped1=0;
            for(i=0; i < numberrow-1; i++){
                if(realEstate[i][4]>realEstate[i+1][4]) {
                    swap(realEstate, i, 4);
                    swap(realEstate, i, 3);
                    swap(realEstate, i, 2);
                    swap(realEstate, i, 1);
                    swap(realEstate, i, 0);
                    swapped1=1;
                }
                 else if ( (realEstate[i][4]==realEstate[i+1][4]) && (realEstate[i][2] > realEstate[i+1][2]) ) {
                    swap(realEstate, i, 3);
                    swap(realEstate, i, 2);
                    swap(realEstate, i, 1);
                    swap(realEstate, i, 0);
                    swapped1=1;
                }
                 else if ( (realEstate[i][2]==realEstate[i+1][2]) && (realEstate[i][1] > realEstate[i+1][1]) ) {
                    swap(realEstate, i, 3);
                    swap(realEstate, i, 1);
                    swap(realEstate, i, 0);
                    swapped1=1;
                }
                 else if ( (realEstate[i][1]==realEstate[i+1][1]) && (realEstate[i][0] > realEstate[i+1][0]) ) {
                    swap(realEstate, i, 3);
                    swap(realEstate, i, 0);
                    swapped1=1;
                }
                 else if ( (realEstate[i][0]==realEstate[i+1][0]) && (realEstate[i][3] > realEstate[i+1][3]) ) {
                    swap(realEstate, i, 3);
                    swapped1=1;
                }
            }
        }
            swapped1=0;
    
       printStage(4);
        printf("Sales sorted in ascending order according to price, etc.:\n");
        printHeader();
    
        for (i=0; i < numberrow; i=i+1) {
            for (j=0; j < COLUMNS; j=j+1) {
                printTable(realEstate, i, j);
            }
        }
    
    
    return 0;
    }
    
    oid printHeader (void) {
    
        printf("+========================================+\n");
        printf("| Postcode Month Year Bedrooms     Price |\n");
        printf("+----------------------------------------+\n");
    }
    
    void printTable (int realEstate[ROWS][COLUMNS], int i, int j) {
        if (j==0) {
            printf("|   %4d", realEstate[i][j]);
        } else if (j==1) {
            printf("    %02d", realEstate[i][j]);
        } else if (j==2) {
            printf("   %4d", realEstate[i][j]);
        } else if (j==3) {
            printf("  %4d    ", realEstate[i][j]);
        } else if (j==4) {
            printf(" %8d |\n", realEstate[i][j]);
        }
    
    }
    
    void swap(int realEstate[ROWS][COLUMNS] , int i, int k) {
        int temp;
        temp = realEstate[i][k];
        realEstate[i][k] = realEstate[i+1][k];
        realEstate[i+1][k] = temp;
    }

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You should make something like:
    Code:
    void swaprow( type row1[], type row2[], size_t cols )
    {
        int x = 0;
        for( x = 0; x < cols; x++ )
        {
            type t = row1[ x ];
            row1[ x ] = row2[ x ];
            row2[ x ] = t;
        }
    }
    Then call it something like this:
    Code:
    ...doing stuff...
    swaprow( twodeearray[ row ], twodeearray[ anotherrow ] );

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You definitely want a swapRows function - it really shortens the code and makes things clearer. Doing a multi-key sort on a 2D array is not as trivial as you seem to think it to be, imo.

    "All I need to do is..." Welcome to the heart of your assignment, Kevin.

    I'd make up a little 5 to 20 row test array of data, and work through the logic of sorting by the keys, one key at a time - but get swapRows up and working, first.

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This is an incomplete example of how to do it. I used some of your data, and copied and also altered a few parts of it, so the multi-key sorting would be shown.

    Here's the data file I used, named "multiKey.txt":
    | Postcode Month Year Bedrooms Price |
    +----------------------------------------+
    2081 12 2007 4 795500
    2081 12 2007 4 795500
    2081 11 2007 4 795500
    2081 10 2007 4 795500
    2081 12 2008 4 795500
    2081 12 2007 3 795500
    2081 12 2007 5 795500
    2081 12 2007 4 895500
    2081 12 2007 4 855500
    2081 12 2006 4 795500
    2081 12 2006 1 795500
    2081 12 2007 4 495500
    2180 07 2009 6 165000
    2140 12 2008 5 689000
    2153 03 2008 4 491500
    2140 02 2010 5 886500
    2005 11 2007 4 776500
    2151 07 2007 5 305500
    2199 12 2010 5 895000
    2101 04 2010 7 389500
    2176 02 2008 2 959500
    And here's the incomplete program. Note how the swap_rows function works:

    Code:
    /*
    Key Priorities:
    key0 = price,
    key1 = year
    key2 = month
    key3 = postcode
    key4 = bedrooms
    
    postcode, month, year, bedroom, price
    */
    
    #include <stdio.h>
    
    #define N 5
    #define R 21
    void sort(unsigned long data[R][N]);
    void swap_rows(unsigned long data[][N], int i, int j);  //swaps data[i] and data[j] 
    
    int main() {
      FILE *fp;
      char buff[80] = {'\0'};
      int i, j, n ; 
      unsigned long int data[R][N] = {{ 0 }};
      if((fp = fopen("multiKey.txt", "rt")) == NULL) {
        printf("\nError opening file");
        return 1;
      }    
      //get past 2 header rows
      fgets(buff, sizeof(buff), fp);
      fgets(buff, sizeof(buff), fp);
      printf("\n\n\n");
      j = 0;
      for(i = 0; i < R; i++) {
        fscanf(fp, "%U%U%U%U%U", 
        &data[i][j],&data[i][j+1],&data[i][j+2],&data[i][j+3],&data[i][j+4]);
        printf("%lu %lu %lu %lu %lu\n", 
        data[i][j],data[i][j+1],data[i][j+2],data[i][j+3],data[i][j+4]);
      }  
      sort(data);
    
    
      printf("\n\n\t\t\t     press enter when ready");
      fclose(fp);
      i = getchar(); ++i;
      return 0;
    }
    /* Key Priorities: key0 = price, key1 = year key2 = month key3 = postcode
                       key4 = bedrooms
       Order in file: postcode, month, year, bedroom, price
    */
    void sort(unsigned long data[R][N]) {
       int i, j, pc, mo, yr, bed, price;
       pc = 0; mo = 1, yr = 2, bed = 3, price = 4;
    
       for(i = 0; i < R; i++) {  //sort by price
         for(j = i +1; j < R; j++) 
           if(data[i][price] > data[j][price])
             swap_rows(data, i, j);
    
           else if((data[i][price] == data[j][price]) && 
                (data[i][yr] > data[j][yr]))
             swap_rows(data, i, j);
    
    
       }
    
    /* this is a naive way to resort according to multiple keys. It does 
    exactly the same thing as the "else if(" statement, directly above this
    */
    /*   printf("\n\n");  
       for(i = 0; i < R; i++) {  //sort by year
         for(j = i +1; j < R; j++) 
           if((data[i][price] == data[j][price]) && (data[i][yr] > data[j][yr]))
             swap_rows(data, i, j);
       }
    */
       printf("\n\n");  
       
    /* You can keep the naive approach, but why not add it into the main
       sorting loops, up above, just like was done with the code right
       above this?
    */
    
       for(i = 0; i < R; i++) {  //sort by month
         for(j = i +1; j < R; j++) 
           if(data[i][price]==data[j][price]) {
             if((data[i][yr] == data[j][yr]) && (data[i][mo] > data[j][mo]))
               swap_rows(data, i, j);
           }
       }
       printf("\n\n");  
    
    
    
    
       //show in row order, and priority in left to right columns
      for(i = 0; i < R; i++) {
        printf("%lu %lu %lu %lu %lu\n",
       data[i][price],data[i][yr],data[i][mo],data[i][pc],data[i][bed]);
      }
    }
    void swap_rows(unsigned long data[R][N], int i, int j) { //swaps data[i] and data[j] 
      int k;
      unsigned long temp[N];
      
      for(k = 0; k < N; k++)   //make assignments to temp
        temp[k] = data[i][k];
    
      for(k = 0; k < N; k++)   //make assignments to i
        data[i][k] = data[j][k];
    
      for(k = 0; k < N; k++)   //make assignments to j
        data[j][k] = temp[k];   
    
    }
    I've run this through and not seen any problems, but that's not saying it's been tested, and it IS incomplete.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 03-31-2009, 12:34 PM
  2. Sorting an int array highest to lowest
    By switchback in forum C Programming
    Replies: 3
    Last Post: 07-27-2008, 03:30 AM
  3. Sorting: Getting permutation index array
    By flyvholm in forum C Programming
    Replies: 2
    Last Post: 09-20-2006, 07:07 PM
  4. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM
  5. sorting array efficiently...can't find the error
    By Unregistered in forum C++ Programming
    Replies: 4
    Last Post: 04-09-2002, 02:32 PM