Thread: Sorting problem

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    6

    Sorting problem

    Hi there

    I'm having some trouble with a C program for an assignment. Its a program which is designed to read exam data from a text file, store them and then output a certain exam in order of marks. Heres the code so far:-

    Code:
    #include <stdio.h>
    
    int results[40][5];
    
    void bubblesort (int students, int test)
    {int j, k, tmp1, tmp2;
    
    for (k=0;k < students - 1; ++k)
      for(j=students-1;j>k;--j)
        if(results[j-1][test] < results[j][test]);
          {tmp1 = results[j-1][test];
            results[j-1][test]=results[j][test];
            results[j][test]=tmp1;
           tmp2 = results[j-1][0];
            results[j-1][0]=results[j][0];
            results[j][0]=tmp2;
    }
    }
    
    
    int main (void)
    
    {
    
    int junkcontinue, x = 0, count = 0, choice = 3;
    FILE *my_in, *my_out;
    
    
    
        printf("\nWelcome. This program is specifically designed to read and assess");
        printf("\nexam data retrieved from the 'datafile.txt' file in your U: drive.");
        printf("\n\nIf you are confident such a file exists in your U: drive, type");
        printf("\n'y' and press Enter.\n\n");
        
        scanf("%d", &junkcontinue);
        
        if ((my_in = fopen ("C:\\datafile.txt","rt")) == NULL)
        {
            printf("\nDatafile.txt is not found.\n");
    		system("pause");
            return(1);
        }
        
        if ((my_out = fopen ("C://dataout.txt","wt")) == NULL)
        {
            printf("\nError: Dataout.txt is not found.\n");
    		system("pause");
            return(1);
        }  
        
        printf("\nFile found. Reading file...\n\n");
    
        while  (fscanf(my_in, "%d,%d,%d,%d,%d", &results[x][0], &results[x][1], &results[x][2], &results[x][3], &results[x][4])!= EOF)
        {
            printf("*");
            x += 1;
            count++;
        }  
        
        int testnumber;
        
        printf("\n\nFiles Imported to array.\n\n");
    
    
        printf("Please type which test you would like to output (1,2,3,4) and press Enter:");
        fflush(stdin);
        scanf("%d", &testnumber);
        
        printf("\nYou have selected test %d.", testnumber);
        printf("\nOutputting results to dataout.txt...");
        
        printf("\n\nThe count is %d.\n\n", count);
        printf("\n\nThe testnumber is %d.\n\n", testnumber);
        
        printf("\n\t%d\t%d\t%d\t%d\t%d", results[0][0], results[0][1], results[0][2], results[0][3], results[0][4]);
        printf("\n\t%d\t%d\t%d\t%d\t%d", results[1][0], results[1][1], results[1][2], results[1][3], results[1][4]);
        printf("\n\t%d\t%d\t%d\t%d\t%d", results[2][0], results[2][1], results[2][2], results[2][3], results[2][4]);
        printf("\n\t%d\t%d\t%d\t%d\t%dn\n", results[3][0], results[3][1], results[3][2], results[3][3], results[3][4]);
        
        
        
        bubblesort(count-1, testnumber);
    
        printf("\n\t%d\t%d\t%d\t%d\t%d", results[0][0], results[0][1], results[0][2], results[0][3], results[0][4]);
        printf("\n\t%d\t%d\t%d\t%d\t%d", results[1][0], results[1][1], results[1][2], results[1][3], results[1][4]);
        printf("\n\t%d\t%d\t%d\t%d\t%d", results[2][0], results[2][1], results[2][2], results[2][3], results[2][4]);
        printf("\n\t%d\t%d\t%d\t%d\t%dn\n", results[3][0], results[3][1], results[3][2], results[3][3], results[3][4]);
    
        
        while (x < count)
        {
            fprintf(my_out, "%d,%d\n", results[x][0], results[x][3]);
            x += 1;
        }
        
        printf("\n\nDataout.txt file has finished writing.");
    
        fclose(my_in);
        fclose(my_out);
    
        system("pause");
    
    return (0);
    }
    Code:
    The testnumber is 3.
    
    
            105683  23      65      0       100
            105475  96      72      35      61
            105286  23      45      15      86
            104762  23      17      5       56n
    
            105475  23      65      35      100
            105683  96      72      0       61
            105286  23      45      15      86
            104762  23      17      5       56n
    The above shows the data in the array before the bubble sort, and after the bubble sort. Row 3 should be in order 35/15/5/0 but as you can see it appears only the top 2 values have been swapped. I know the code is messy (I'm v.new to this) but can anyone spot the problem? I just cant figure this out.

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    You are using testnumber as the index (relative to 1) for which set of scores to test. You pass that as test to your bubblesort, and use it as an index, but it is still relative to 1, not zero, and, it's not used as the correct index either.

    There are various other problems with your code as well I choose to not comment on.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    6
    Thanks for the quick reply, but I'm afraid I have no idea what you are suggesting I do. The 'index' you refer to is in the function header I presume? How do I make the index relative to 0 as appose to 1? And forget the rest of the code, its a... work in progress.

  4. #4
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    You start out with a user entered value:
    Code:
    printf("Please type which test you would like to output (1,2,3,4) and press Enter:");
    fflush(stdin);   <-- P.S.  no such thing 
    scanf("%d", &testnumber);
    ...
    bubblesort(count-1, testnumber);  // testnumber is 1, 2, 3 or 4
    Then in bubblesort, you use testnumber (now test) as an index into the results array:
    Code:
    void bubblesort (int students, int test)
    {int j, k, tmp1, tmp2;
    
    for (k=0;k < students - 1; ++k)
      for(j=students-1;j>k;--j)
    // test (previously known as testnumber) is still 1 through 4, and it's supposed to 
    // be 0 through 3, and the first index, not the second
        if(results[j-1][test] < results[j][test]);
          {tmp1 = results[j-1][test];
            results[j-1][test]=results[j][test];
            results[j][test]=tmp1;
           tmp2 = results[j-1][0];
            results[j-1][0]=results[j][0];
            results[j][0]=tmp2;
    }
    }
    On another note, you subtract 1 from count here...
    Code:
    bubblesort(count-1, testnumber);
    and then do it again (above in green).
    Mainframe assembler programmer by trade. C coder when I can.

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    >    if(results[j-1][test] < results[j][test]);
    Another problem. Notice you've also got a semicolon at the end of this if(). This means that the if() statement is basically ignored.

    Also as Todd explained:
    Code:
    bubblesort(count-1, testnumber);
    Why count-1 here? Just pass in the number of students, and let the bubblesort() function do the offset, probably in the inner for-loop, not the outer one.

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    >    while (x < count)
    >    {
    >        fprintf(my_out, "%d,%d\n", results[x][0], results[x][3]);
    >        x += 1;
    >    }
    x would need to be reset back to 0, because you already incremented it in a prior loop. For-loops work nicely for this purpose:
    Code:
        for (x=0; x<count; x++)
        {
            fprintf(my_out, "%d,%d\n", results[x][0], results[x][3]);
        }

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    6
    Thanks guys, it was the semicolon ignoring the if function. I've actually fixed it by just rebuilding it with an insertion sort instead and it worked.

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    6
    Another problem now...I'm trying to sort the test data from my arrays into another array based on the test# and size. For example test1 0-9 has 1 value, 10-19 has 0 values etc..

    For simplicity I'm building it only for test 1 at the moment which has results 23,96,23,23. Heres the code:-

    Code:
    int grouping[10][4];  
    int a = 0, b = 9, c = 0, d = 0, e = 0;    
      
       
    while (e < 10)
    {
          while (d < count)
          {
          if (a <= results[d][1] && results[d][1] <= b)
             {
             c += 1;
             }
          d += 1;
          }
    grouping[e][0] = c;
    a += 10;
    b += 10;
    e += 1;
    }    
    
        
        printf("\n%d\n", grouping[0][0]);
        printf("\n%d\n", grouping[1][0]);
        printf("\n%d\n", grouping[2][0]);
        printf("\n%d\n", grouping[3][0]);
        printf("\n%d\n", grouping[4][0]);
        printf("\n%d\n", grouping[5][0]);

    This just returns:

    Code:
    0
    0
    0
    0
    0
    0

    any ideas?

  9. #9
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    step through your code in debugger and see by yourself what is happening
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    6
    I've been messing around with the debugger in Dev-C++ but I still cant figure out whats wrong, it seems like it should work

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Your code doesn't include a variable type declaration for "count", so that can't be right.

    Since this sorting code is seriously flawed, why not start with your insertion sorting code that works, and just make the alterations so it sorts according to the keys you want it to sort on, in this case?

  12. #12
    Registered User
    Join Date
    Apr 2008
    Posts
    6
    Count is declared earlier on in the code so its not that I think.

    Since this sorting code is seriously flawed, why not start with your insertion sorting code that works, and just make the alterations so it sorts according to the keys you want it to sort on, in this case?
    I dont know what you mean here...I'm trying to group all the test results from test 1 by size into an array - 0-9 in cell [0][0] for example. You say this code is seriously flawed but how? I'm new to C and to me this seems like it should work, so whats wrong?

  13. #13
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    >      if (a <= results[d][1] && results[d][1] <= b)
    With the numbers you have in the array (23,96,23,23), how is this condition ever going to be true?

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by buxBonehead View Post
    Count is declared earlier on in the code so its not that I think.

    I dont know what you mean here...I'm trying to group all the test results from test 1 by size into an array - 0-9 in cell [0][0] for example. You say this code is seriously flawed but how? I'm new to C and to me this seems like it should work, so whats wrong?

    I'm sure you're right about "count". My point is that when you don't have it in the code you post, we don't know WTD is going on, and left to guess.

    I understand what you're trying to do, but you should understand that your sorting code is absolutely the worst stew of misguided thinking for a sort function, that I've ever seen.

    You can't throw it away, fast enough.

    You can't just "write a sorting function" that "seems like it should work".

    First, you learn how a sort algorithm works, preferably a simple one, what it should look like, and play with that basic algorithm a bit - try this, try that, try something else - but now you know what the basic algorithm should look like, and come at the problem from a basic foundation of knowledge.

    You don't have that foundation, yet. Looking at the code, without your text, I'd have no idea that you were even trying to sort.

    I'll edit this now that I believe you're actually serious, with some code.

    OK, this is your previous post and code:

    Code:
    another problem now...I'm trying to sort the test data from my arrays into 
    another array based on the test# and size. 
    
    For example test1 0-9 has 1 value, 10-19 has 0 values etc..
    
    For simplicity I'm building it only for test 1 at the moment which has results 23,96,23,23. Heres the code:-
    
    Code:
    
    int grouping[10][4];  
    int a = 0, b = 9, c = 0, d = 0, e = 0;    
      
       
    while (e < 10)
    {
          while (d < count)
          {
          if (a <= results[d][1] && results[d][1] <= b)
             {
             c += 1;
             }
          d += 1;
          }
    grouping[e][0] = c;
    a += 10;
    b += 10;
    e += 1;
    }    
    
        
        printf("\n%d\n", grouping[0][0]);
        printf("\n%d\n", grouping[1][0]);
        printf("\n%d\n", grouping[2][0]);
        printf("\n%d\n", grouping[3][0]);
        printf("\n%d\n", grouping[4][0]);
        printf("\n%d\n", grouping[5][0]);
    
    
    This just returns:
    
    Code:
    
    0
    0
    0
    0
    0
    0
    
    
    any ideas?
    So int test1[] = {23, 96, 23, 23}, and you want the sorted data output to results[], right?
    Code:
    #include <stdio.h>
    
    int main(void)   {
       int i, j, temp, gar;
       int test[] = { 23, 96, 0, 22 };  //number change to test the sort better.
       int results[4] = { 0 };
    
       for(i = 0; i < 3; i++)   {
          for(j = i + 1; j < 4; j++)   {
             if(test[i] > test[j])   {
                temp = test[i];
                test[i] = test[j];  
                test[j] = temp;    
             }
          }
       }
       for(i = 0; i < 4; i++)
          printf("%d, ", test[i]);
       gar = getchar(); gar++;
       return 0;
    
    
    //888888888888888888888  Doesn't work 8888888888888888888888888888
    for(i = 0; i < 3; i++)   {
       for(j = i + 1; j < 4; j++)   {
          if(test[i] > test[j]   {
             temp = test[i];
    //         test[i] = test[j];  //remark out this line if you want test to remain unsorted
    //         test[j] = temp;   //    "        "       "    "    "   "      "      "     "      "           "
          
              //above portion sorts test, in place. this puts the data into results[], instead of sorting in place.
              results[i] = test[j];
              results[j] = temp;
          }
          else
              results[i] = test[i];
    
    
          }
       }
    }
    //888888888888888888888888888 Doesn't work 8888888888888888
    Second half of above code doesn't work because results[] never gets re-sorted, after the first pass. All the comparisons are
    made with test[], and none are made with results[].

    I would just sort test[] in place, and then write it's contents to results[]. Or, you could set up an index array, sort the index, by the
    content of test[], and then write out the contents of test[], using that new, sorted, index. This is slightly more advanced, but a slick thing to know.

    The latter sort by using an index, would leave test[] unsorted, but results would be sorted.

    Hope that helps.
    Last edited by Adak; 05-02-2008 at 11:11 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sorting problem?
    By audinue in forum C Programming
    Replies: 5
    Last Post: 01-06-2009, 02:16 PM
  2. Array Sorting problem
    By ___________ in forum C++ Programming
    Replies: 4
    Last Post: 07-22-2008, 12:17 AM
  3. What is problem about the sorting?
    By Mathsniper in forum C Programming
    Replies: 2
    Last Post: 04-17-2005, 07:00 AM
  4. Sorting text file problem...
    By John-m in forum C Programming
    Replies: 3
    Last Post: 10-01-2002, 04:51 PM
  5. Sorting array output problem
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 02-19-2002, 01:44 PM