how to use qsort

This is a discussion on how to use qsort within the C Programming forums, part of the General Programming Boards category; Code: struct student { int id; float score; }s[3]{1,90},{2,80},{2,90}}; int cmp(const void *b,const void *a) { register struct student *p1=(struct ...

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    168

    how to use qsort

    Code:
    struct student
    {
          int id;
          float score;
    }s[3]{1,90},{2,80},{2,90}};
    int cmp(const void *b,const void *a)
    {
        register struct  student *p1=(struct  student *)a;
        register struct  student *p2=(struct  student *)b;
    
        return (p1->id)>(p2->id)? 1:( (p1->id)<(p2->id) ? -1:0 );
    }
    qsort(s,10,sizeof(student),cmp);
    how to sort?
    first: sort by id
    second: if id equal. then sort by score

    output:
    2 90
    2 80
    1 90

  2. #2
    Registered User
    Join Date
    Sep 2009
    Location
    Pune, India
    Posts
    4
    zcrself 12-28-2009 12:45 PM
    why no print?

    train.h
    Code:
    //PARSEPARAarse para by step by step
    int parseP(const char *a,float *p)
    {
    float start,end,step;
    int pCount = 0;
    int pNum = 0;
    pNum = sscanf(a,"%f-%f-%f",&start,&end,&step);
    //printf("start:[%f]\n",start);

    if ( pNum < 3 )
    {
    printf("Error:format of windowSize,K-value,noequalPunish and percentRatio must be start-end-step.\n");
    exit(0);
    }
    if ( end < start )
    {
    printf("Error: end must be more than start in [%s]\n",a);
    exit(0);
    } else if ( step <= 0 )
    {
    printf("Error: step must be more than 0 in [%s]\n",a);
    exit(0);
    }

    //float j;
    while ( start <= end )
    {
    *p = start;
    start = start+step;
    p++;
    pCount++;
    }

    return pCount;
    //printf("pNum:%f\n",step);
    }
    zero.cpp
    Code:
    #include "train.h"
    int main( int argc,char *argv[])
    {
    float a[30] = {'\0'};
    parseP("0-5-1",a);

    for ( int i = 0; a[i] != '\0' ; i++ )
    {
    printf("a[%d]:%f\n",i,a[i]);
    }
    return 0;
    }



    If parseP("0-5-1",a); print is nothing
    if parseP("1-5-1",a); print is as follows:
    a[0]:1.000000
    a[1]:2.000000
    a[2]:3.000000
    a[3]:4.000000
    a[4]:5.000000


    why ? how to solve this problem?



    REPLY *****************

    Use of for loop in the function main was incorrect
    refer to the following answer


    #include "stdio.h"
    #include <stdlib.h>

    int parseP(const char*,float*);

    int main()// int argc,char *argv[])
    {
    int i;
    float a[30] = {'\0'};
    int count;
    count = parseP("0-5-1",a);

    for ( i = 0; i < count ; i++ )
    {
    printf("a[%d]:%f\n",i,a[i]);
    }
    return 0;
    }

    //PARSEPARAarse para by step by step
    int parseP(const char *a,float *p)
    {
    float start,end,step;
    int pCount = 0;
    int pNum = 0;
    pNum = sscanf(a,"%f-%f-%f",&start,&end,&step);
    //printf("start:[%f]\n",start);

    if ( pNum < 3 )
    {
    printf("Error:format of windowSize,K-value,noequalPunish and percentRatio must be start-end-step.\n");
    exit(0);
    }
    if ( end < start )
    {
    printf("Error: end must be more than start in [%s]\n",a);
    exit(0);
    } else if ( step <= 0 )
    {
    printf("Error: step must be more than 0 in [%s]\n",a);
    exit(0);
    }

    //float j;
    while ( start <= end )
    {
    *p = start;
    start = start+step;
    p++;
    pCount++;
    }

    return pCount;
    //printf("pNum:%f\n",step);
    }

  3. #3
    Registered User
    Join Date
    Sep 2009
    Location
    Pune, India
    Posts
    4
    You have not used the for loop correctly in the function main()
    Read the following code


    #include "stdio.h"
    #include <stdlib.h>

    int parseP(const char*,float*);

    int main()// int argc,char *argv[])
    {
    int i;
    float a[30] = {'\0'};
    int count;
    count = parseP("0-5-1",a);

    for ( i = 0; i < count ; i++ )
    {
    printf("a[%d]:%f\n",i,a[i]);
    }
    return 0;
    }

    //PARSEPARAarse para by step by step
    int parseP(const char *a,float *p)
    {
    float start,end,step;
    int pCount = 0;
    int pNum = 0;
    pNum = sscanf(a,"%f-%f-%f",&start,&end,&step);
    //printf("start:[%f]\n",start);

    if ( pNum < 3 )
    {
    printf("Error:format of windowSize,K-value,noequalPunish and percentRatio must be start-end-step.\n");
    exit(0);
    }
    if ( end < start )
    {
    printf("Error: end must be more than start in [%s]\n",a);
    exit(0);
    } else if ( step <= 0 )
    {
    printf("Error: step must be more than 0 in [%s]\n",a);
    exit(0);
    }

    //float j;
    while ( start <= end )
    {
    *p = start;
    start = start+step;
    p++;
    pCount++;
    }

    return pCount;
    //printf("pNum:%f\n",step);
    }

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Since you broke your own thread, and decided to take over this one with your own code, here is why yours doesn't work:
    Code:
    //float j;
    while ( start <= end )
    {
        *p = start;
    If start is 0, that means *p is given the value of zero. Since you are checking to see if zero is entered to stop your loop, the first element stops your loop. Read the top of the forum, and learn how to use code tags before you post again.


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

  5. #5
    Registered User
    Join Date
    Aug 2009
    Posts
    168
    Quote Originally Posted by quzah View Post
    Since you broke your own thread, and decided to take over this one with your own code, here is why yours doesn't work:
    Code:
    //float j;
    while ( start <= end )
    {
        *p = start;
    If start is 0, that means *p is given the value of zero. Since you are checking to see if zero is entered to stop your loop, the first element stops your loop. Read the top of the forum, and learn how to use code tags before you post again.


    Quzah.
    How to correct?

  6. #6
    Registered User
    Join Date
    Aug 2009
    Posts
    168
    Quote Originally Posted by quzah View Post
    Since you broke your own thread, and decided to take over this one with your own code, here is why yours doesn't work:
    Code:
    //float j;
    while ( start <= end )
    {
        *p = start;
    If start is 0, that means *p is given the value of zero. Since you are checking to see if zero is entered to stop your loop, the first element stops your loop. Read the top of the forum, and learn how to use code tags before you post again.


    Quzah.
    how to write cmp function to process two-dimensional sort?

  7. #7
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,529
    I was going to write about stability, but then I noticed something. Why isn't id unique? The whole point of numerical ids is to serve as primary keys in databases. Please consider enforcing this.

    Anyway, you need to pick another algorithm. Quoting you:

    how to sort?
    first: sort by id
    second: if id equal. then sort by score
    This is a problem for quick sort. It is not guaranteed to keep ids in order if it has to consider grades at all. A stable sort algorithm would keep ids in order even if it does sort by grade. Using a stable sort makes this no problem at all just sort by id and then by grade.

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,269
    Quote Originally Posted by whiteflags View Post
    I was going to write about stability, but then I noticed something. Why isn't id unique? The whole point of numerical ids is to serve as primary keys in databases. Please consider enforcing this.

    Anyway, you need to pick another algorithm. Quoting you:

    This is a problem for quick sort. It is not guaranteed to keep ids in order if it has to consider grades at all. A stable sort algorithm would keep ids in order even if it does sort by grade. Using a stable sort makes this no problem at all just sort by id and then by grade.
    It would be a question of stability if he wanted items with equal "id" but different "score" members to remain in the same order they were relative to each other, prior to the sorting. However he hasn't asked that they remain in their existing order, he has asked that tie-breakers are furthur sorted by additional criteria.
    He therefore does not need to pick another algorithm because this is not a question of stability here. It's simply a matter of coding up a suitable comparison function that considers multiple sort keys. Any non-stable sorting algorithm can do that just fine.

    Here is one such comparison function that will do what was asked for:
    Code:
    int cmp(const void *b, const void *a)
    {
        struct student *p1 = (struct student*)a;
        struct student *p2 = (struct student*)b;
    
        if (p1->id != p2->id)
            return (p1->id < p2->id) ? -1 : 1;
        if (p1->score != p2->score)
            return (p1->score < p2->score) ? -1 : 1;
        return 0;
    }
    Note: Don't use the "register" keyword. It doesn't do anything useful.

    What Hrishikesh posted does not belong in this thread at all and so is being ignored by me.
    Guys, don't feed the thread hijackers eh!
    Last edited by iMalc; 12-29-2009 at 02:10 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    Registered User
    Join Date
    Jul 2009
    Location
    Croatia
    Posts
    272
    Note: Don't use the "register" keyword. It doesn't do anything useful.
    Doesnt it speeds up operations done on register declared objects by storing them into one of the registers? Atleast thats what i did read in K&R book.
    Last edited by Tool; 12-29-2009 at 02:23 PM.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    The program may suggest "register", but it will not usually be followed. The compiler will optimize your code as it sees fit. Unless you're very good with assembly, it will do it better than you can.

    Compilers used to be much more primitive than they are today - they have graduated and don't need any hints about what should go into a register and what shouldn't.

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,269
    Quote Originally Posted by Tool View Post
    Doesnt it speeds up operations done on register declared objects by storing them into one of the registers? Atleast thats what i did read in K&R book.
    A compiler tries to put all the stuff that it knows should be in registers into registers only to perhaps find that you've told it to put some other stupid things into registers so that it doesn't have enough left for the important stuff, making it a whole lot slower.
    'register' was only ever meant for those times where you've actually analysed the generated assembly and worked out the compiler didn't do things properly, and that using the keyword makes a positive difference in the resulting generated assembly after yet more analysis.
    I say "was" because most compilers just ignore it now since too many people simply put it in code because they heard that it can speed things up, when it could often just make things worse if it has any effect at all.

    I have only seen one usage of it that was known to have been beneficial, in the last 15 years, and that was not recently.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Registered User
    Join Date
    Aug 2009
    Posts
    168
    Quote Originally Posted by iMalc View Post
    It would be a question of stability if he wanted items with equal "id" but different "score" members to remain in the same order they were relative to each other, prior to the sorting. However he hasn't asked that they remain in their existing order, he has asked that tie-breakers are furthur sorted by additional criteria.
    He therefore does not need to pick another algorithm because this is not a question of stability here. It's simply a matter of coding up a suitable comparison function that considers multiple sort keys. Any non-stable sorting algorithm can do that just fine.

    Here is one such comparison function that will do what was asked for:
    Code:
    int cmp(const void *b, const void *a)
    {
        struct student *p1 = (struct student*)a;
        struct student *p2 = (struct student*)b;
    
        if (p1->id != p2->id)
            return (p1->id < p2->id) ? -1 : 1;
        if (p1->score != p2->score)
            return (p1->score < p2->score) ? -1 : 1;
        return 0;
    }
    Note: Don't use the "register" keyword. It doesn't do anything useful.

    What Hrishikesh posted does not belong in this thread at all and so is being ignored by me.
    Guys, don't feed the thread hijackers eh!
    Your suggestion is appreciated!
    Thanks a lot!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. An interesting problem of qsort()
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 03-05-2008, 11:09 AM
  2. qsort() in Array of Pointer to String
    By vb.bajpai in forum C Programming
    Replies: 8
    Last Post: 06-16-2007, 04:18 PM
  3. How to write my own qsort routine
    By tonbarius in forum C Programming
    Replies: 3
    Last Post: 05-14-2006, 12:34 PM
  4. Throw away members in qsort
    By xxxrugby in forum C Programming
    Replies: 4
    Last Post: 04-24-2005, 06:08 AM
  5. C++ link error with qsort
    By bvnorth in forum C++ Programming
    Replies: 7
    Last Post: 10-24-2003, 02:22 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21