# Thread: urgent help with sorting a two D array

1. ## 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 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;
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");

for (i=0; i < numberrow; i=i+1) {
for (j=0; j < COLUMNS; j=j+1) {
printTable(realEstate, i, j);
}
}

return 0;
}

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. 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.

3. 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. 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;
}
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);

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.