Swap method in C

tsj

tsj

Permabanned
Joined
7 May 2004
Posts
1,051
Location
United Kingdom
jint goal2_sort ()
{

int pinsert;
int temp;
int y,i,in,gap;
int value;
char tmpteam[20];
int tmpplayed;
int tmppoints;
int tmpgoalsf;
int tmpgoalsa;
int tmpwon;
int tmplost;
int tmpdraw;
y = 0;

value=0;

/** sort by points **/
for (y = 1; y < MAX_TEAMS; y++)
{

while (arrdetails[y].goalsfor > arrdetails[y - 1].goalsfor)
{
strcpy(tmpteam,arrdetails[y-1].team);
tmpplayed=arrdetails[y-1].played;
tmpwon=arrdetails[y-1].won;
tmplost=arrdetails[y-1].lost;
tmpdraw=arrdetails[y-1].draw;
tmppoints=arrdetails[y-1].points;
tmpgoalsf=arrdetails[y-1].goalsfor;
tmpgoalsa=arrdetails[y-1].goalsagainst;

strcpy(arrdetails[y-1].team,arrdetails[y].team);
arrdetails[y-1].played=arrdetails[y].played;
arrdetails[y-1].won=arrdetails[y].won;
arrdetails[y-1].lost=arrdetails[y].lost;
arrdetails[y-1].draw=arrdetails[y].draw;
arrdetails[y-1].points=arrdetails[y].points;
arrdetails[y-1].goalsfor=arrdetails[y].goalsfor;
arrdetails[y-1].goalsagainst=arrdetails[y].goalsagainst;

strcpy(arrdetails[y].team,tmpteam);
arrdetails[y].played=tmpplayed;
arrdetails[y].won=tmpwon;
arrdetails[y].lost=tmplost;
arrdetails[y].draw=tmpdraw;
arrdetails[y].points=tmppoints;
arrdetails[y].goalsfor=tmpgoalsf;
arrdetails[y].goalsagainst=tmpgoalsa;

y--;
}
}
return 0;

}

My current table is
Id Team Played Won Lost Drawn GoalsF GoalsA Points
0 england 1 1 0 0 3 1 3
1 wolves 1 1 0 0 7 5 3
2 liverpool 1 0 0 1 1 1 1
3 manu 1 0 0 1 1 1 1
4 everton 0 0 0 0 0 0 0
5 chelsea 0 0 0 0 0 0 0
6 nottingham 0 0 0 0 0 0 0
7 astonv 0 0 0 0 0 0 0
8 wigan 0 0 0 0 0 0 0
9 albion 0 0 0 0 0 0 0
10 coventry 0 0 0 0 0 0 0
11 arsenal 2 0 2 0 6 10 0

Team 11 (arsenal) is meant to be swapped.

my output after using the above method is:

Id Team Played Won Lost Drawn GoalsF GoalsA Points
0 arsenal 2 0 2 0 6 10 0
1 england 1 1 0 0 3 1 3
2 liverpool 1 0 0 1 1 1 1
3 manu 1 0 0 1 1 1 1
Ç*♥ 1 ÉÌ 1 0 0 0 536854672 536854552
5 everton 0 0 0 0 0 0 0
6 chelsea 0 0 0 0 0 0 0
7 nottingham 0 0 0 0 0 0 0
8 astonv 0 0 0 0 0 0 0
9 wigan 0 0 0 0 0 0 0
10 albion 0 0 0 0 0 0 0
11 coventry 0 0 0 0 0 0 0

Any ideas why im getting: Ç ♥ 1 ÉÌ 1 0 0 0 536854672 536854552

??

Thanks
 
DaveF said:
You might want to check that doing "y--;" isn't making y (or y-1, which you use as an index) go past the start of the array.

Also, doesn't C let you copy structs directly rather than piece by piece? (I can never remember what works in C++ but not in C).

E.g. To swap Team a,b, you can just do Team tmp; tmp = a; a=b; b=tmp;

(And if that doesn't work, memcpy will. Got to be better than your long list of assignments that you'll have to keep changing as you change the definition of a team).

Still cant get this to work :(
 
DaveF said:
You might want to check that doing "y--;" isn't making y (or y-1, which you use as an index) go past the start of the array.

Also, doesn't C let you copy structs directly rather than piece by piece? (I can never remember what works in C++ but not in C).

E.g. To swap Team a,b, you can just do Team tmp; tmp = a; a=b; b=tmp;

(And if that doesn't work, memcpy will. Got to be better than your long list of assignments that you'll have to keep changing as you change the definition of a team).

I dont wanna copy the entire array as it contains a team id which doesnt get swapped
 
DaveF said:
I know I'm going to regret asking this, but what is the actual point of the "team ID"?

when inputting scores... the team id is used to idenify the teams... it is going to be removed soon. as i will need to input teams by 'team name' instead of team id.

im not very good as c.

would it be possible to add one of you guys to msn for help?
 
DaveF said:
But do you not see that it is completely pointless (not to mention desperately confusing) to identify teams by an id that changes when you sort the teams? In general, the whole point of an id is that it doesn't change.

As far as your other problem, I don't think you've coded your sort properly. Try something like this:

Code:
int i,j;
	for (i=0;i<N_TEAMS;i++)
	{
		Team T = teams[i];
		for (j=i-1;j>=0 && teams[j].points<T.points;j--)
			teams[j+1]=teams[j];
		teams[j+1]=T;
	}
N.B. where I have teams, you have arrdetails, I think.

Note also that you need to sort for the number of teams you actually have, not whatever "maximum" you have coded.

ah ok mate. i have tried that... is the above code meant to copy and entire struct? or will i need to copy each individual part?
 
just tried to the code you gave mate...


Code:
Id Team       Played Won Lost Drawn GoalsF GoalsA Points
0            wolves      2       0       2       0       6       9       0
1           england      1       1       0       0       3       1       3
2         liverpool      1       0       0       1       1       1       1
3              manu      1       0       0       1       1       1       1
4           chelsea      1       1       0       0       7       5       3
5           everton      0       0       0       0       0       0       0
6        nottingham      0       0       0       0       0       0       0
7            astonv      0       0       0       0       0       0       0
8             wigan      0       0       0       0       0       0       0
9            albion      0       0       0       0       0       0       0
10         coventry      0       0       0       0       0       0       0
11          arsenal      0       0       0       0       0       0

my bad... i was calling the wrong method... it worked :D

it didnt seem to do it :S
 
Last edited:
Got a few more changes to make before i go on holiday next week. Will be back if i need more help... if thats ok :D
 
The specification says that I've gotta sort using the following criteria:

1) Points
2) Goals For minus Goals Against
3) Goals For

Any idea how i would do this?

I can get it to sort matching one of the criteria above, but I can't think of how I I would implement all three in one sort method.
 
Visage said:
Quick tip: implement a method:
Code:
int compare(int team_a, int team_b);

return value 0 if they are equal, 1 if team_a > team_b, -1 if team_b > team_a.

Implement the algorithm in that function to avoid cluttering your main code with details.

nice one mate... any idea how i can implement all three of the above criteria though?
 
DaveF said:
I take it you mean the actual criteria that you'd see in a "real" football table; that is, first look at the points, then if the points are equal, look at the goal difference, then if that is equal as well, look at the goals scored.

To compare two teams a, b;

Code:
int result = a.points-b.points;
if (!result)
    result = (a.goalsf-a.goalsa)-(b.goalsf-b.goalsa);
if (!result)
    result = a.goalsf - b.goalsf;

At the end, result is < 0 if a < b, result > 0 if a > b (and 0 if a, b are tied).

As Visage says, it would be a good idea to put this into a function. Do you know what pointers are yet?


sort of mate... ive done them and used them but i dont 100% get them... gonna read up on them now tho... gonna work on this till late tonight.

any of you guys got msn by chance?
 
tsj said:
sort of mate... ive done them and used them but i dont 100% get them... gonna read up on them now tho... gonna work on this till late tonight.

any of you guys got msn by chance?

Ok I still dont get what im doing wrong :(

From this:

Id Team Played Won Lost Drawn GoalsF GoalsA Points
0 england 1 1 0 0 3 1 3
1 wolves 2 0 2 0 6 9 0
2 liverpool 1 0 0 1 1 1 1
3 manu 1 0 0 1 1 1 1
4 everton 0 0 0 0 0 0 0
5 chelsea 1 1 0 0 7 5 3
6 nottingham 0 0 0 0 0 0 0
7 astonv 0 0 0 0 0 0 0
8 wigan 0 0 0 0 0 0 0
9 albion 0 0 0 0 0 0 0
10 coventry 0 0 0 0 0 0 0
11 arsenal 0 0 0 0 0 0 0

to this:

Id Team Played Won Lost Drawn GoalsF GoalsA Points
5 chelsea 1 1 0 0 7 5 3
3 manu 1 0 0 1 1 1 1
0 england 1 1 0 0 3 1 3
1 wolves 2 0 2 0 6 9 0
2 liverpool 1 0 0 1 1 1 1
4 everton 0 0 0 0 0 0 0
6 nottingham 0 0 0 0 0 0 0
7 astonv 0 0 0 0 0 0 0
8 wigan 0 0 0 0 0 0 0
9 albion 0 0 0 0 0 0 0
10 coventry 0 0 0 0 0 0 0
11 arsenal 0 0 0 0 0 0 0

my functions are:

int compare(team_info team_a, team_info team_b) {

int result = team_a.points;
if (!result)
result = (team_a.goalsfor-team_a.goalsagainst)-(team_b.goalsfor-team_b.goalsagainst);
if (!result)
result = team_a.goalsfor - team_b.goalsfor;
return result;
}


int sort_pass1() {

int i,j;
for (i=0;i<MAX_TEAMS;i++)
{
team_info T = arrdetails;
int check = compare(arrdetails[i+1],T);
int result;
for (j=i-1;j>=0 && check<0;j--)
arrdetails[j+1]=arrdetails[j];
arrdetails[j+1]=T;
}
return 0;

}



Please help me.... thanks
 
After working on it some more:

int compare(team_info team_a, team_info team_b) {
if (team_b.points<team_b.points)
return team_b.points-team_b.points;
return (team_a.goalsfor-team_a.goalsagainst)-(team_b.goalsfor-team_b.goalsagainst);
}

void sort_pass() {

int i,m,low_m;
for (i=0;i<MAX_TEAMS;i++)
{
team_info T = arrdetails;
team_info lowest;
low_m = i;
for (m=i+1; m<MAX_TEAMS ;m++)
{
if(compare(arrdetails[m],arrdetails)<0)
{
T=arrdetails[m];
low_m=m;
}
arrdetails[low_m]=arrdetails;
arrdetails=lowest;
}
}


After using the above code i got:

Id Team Played Won Lost Drawn GoalsF GoalsA Points
0 0 0 536876708 0 1 1073741856 5
0 0 0 536876708 0 1 1073741856 5
0 0 0 536876708 0 1 1073741856 5
0 0 0 536876708 0 1 1073741856 5
0 0 0 536876708 0 1 1073741856 5
0 0 0 536876708 0 1 1073741856 5
0 0 0 536876708 0 1 1073741856 5
0 0 0 536876708 0 1 1073741856 5
0 0 0 536876708 0 1 1073741856 5
0 0 0 536876708 0 1 1073741856 5
0 0 0 536876708 0 1 1073741856 5
11 arsenal 0 0 0 0 0 0 0
 
Visage said:
I really do think you need to go back to first principles;

1. Write down your program in pseudocode (at first glance it seems like a basic bubble sort).
2. For each line of the pseudo code, write a function call that will perform the specified action for that line.
3. Fill in the individual function bodies.

Ok mate will try this today

Thanks again, any more advice is appreciated
 
DaveF said:
I think it was actually supposed to be an insertion sort; that's why I provided a (correct) version of insertion sort in the answer I gave.

To be honest, not understanding how the sort works seems to be 90% of tsj's problem; maybe it would be better to use a bubble sort as that is easier to understand.

I don't really agree with this, because if taken literally, I think he's going to end up splitting the actual sort
across several functions, which is going to be a nightmare.

Tsj: What I would do is just go back to the code I gave you that worked (at least I think it worked for you). All you need to do is replace the bit that compares the points (in the for statement) with a check to see if "compare(a,b) < 0" (where a,b are the two things you're comparing: team[j] and T or some such).

Ok mate, im just going to try this after ive eaten some food then. will be back to let you know how it goes :D
 
After doing what you said:

Code:
int compare(team_info a, team_info b) {
                        
        int result = a.points-b.points;
        if (!result)
            result = (a.goalsfor-a.goalsagainst)-(b.goalsfor-b.goalsagainst);
        if (!result)
            result = a.goalsfor - b.goalsfor;
}
        
void sort_pass() {
                                 
int i,j;
        for (i=0;i<MAX_TEAMS;i++)
        {                       
                team_info T = arrdetails[i];
                for (j=i-1;j>=0 && compare(arrdetails[j],T)<0);j--)
                        arrdetails[j+1]=arrdetails[j];
                arrdetails[j+1]=T;
        }
        
}

That looks fine to me but it says there is not a valid return statement:

cc: Warning: final.c, line 230: Non-void function "compare" does not contain a return statement. (missingreturn)
 
tsj said:
After doing what you said:

Code:
int compare(team_info a, team_info b) {
                        
        int result = a.points-b.points;
        if (!result)
            result = (a.goalsfor-a.goalsagainst)-(b.goalsfor-b.goalsagainst);
        if (!result)
            result = a.goalsfor - b.goalsfor;
}
        
void sort_pass() {
                                 
int i,j;
        for (i=0;i<MAX_TEAMS;i++)
        {                       
                team_info T = arrdetails[i];
                for (j=i-1;j>=0 && compare(arrdetails[j],T)<0);j--)
                        arrdetails[j+1]=arrdetails[j];
                arrdetails[j+1]=T;
        }
        
}

That looks fine to me but it says there is not a valid return statement:

I've added

return result;

to the end of the compare function to return the value of result.

This solved that problem... now I'm missing a bunch of braces

----------------^
cc: Error: final.c, line 245: Missing ";". (nosemi)
for (j=i-1;j>=0 && compare(arrdetails[j],T)<0);j--)
-------------------------------------------------------------^
cc: Error: final.c, line 245: Missing ";". (nosemi)
for (j=i-1;j>=0 && compare(arrdetails[j],T)<0);j--)
------------------------------------------------------------------^

LOL
 
Visage said:
The error message tells you all you need to know.....

Ok nice one. i got that sorted now mate:

from this:
Code:
Id Team       Played Won Lost Drawn GoalsF GoalsA Points
0           england      1       1       0       0       3       1       3
1            wolves      2       0       2       0       6       9       0
2         liverpool      1       0       0       1       1       1       1
3              manu      1       0       0       1       1       1       1
4           everton      0       0       0       0       0       0       0
5           chelsea      1       1       0       0       7       5       3
6        nottingham      0       0       0       0       0       0       0
7            astonv      0       0       0       0       0       0       0
8             wigan      0       0       0       0       0       0       0
9            albion      0       0       0       0       0       0       0
10         coventry      0       0       0       0       0       0       0
11          arsenal      0       0       0       0       0       0       0

to this:
Code:
Id Team       Played Won Lost Drawn GoalsF GoalsA Points
5           chelsea      1       1       0       0       7       5       3
0           england      1       1       0       0       3       1       3
2         liverpool      1       0       0       1       1       1       1
3              manu      1       0       0       1       1       1       1
4           everton      0       0       0       0       0       0       0
6        nottingham      0       0       0       0       0       0       0
7            astonv      0       0       0       0       0       0       0
8             wigan      0       0       0       0       0       0       0
9            albion      0       0       0       0       0       0       0
10         coventry      0       0       0       0       0       0       0
11          arsenal      0       0       0       0       0       0       0
1            wolves      2       0       2       0       6       9       0

it seems to be working!!!!!
 
Thanks sooo much for the help guys. I'm going to try and get this entire assignment completed today. I gotta change the input from using ID's to using Strings(Team names instead of 0,1,2 etc) and a few other tweaks ;)
 
Back
Top Bottom