Avatar billede darkie88 Nybegynder
03. november 2003 - 19:30 Der er 11 kommentarer og
1 løsning

Sortering i struct

Hejsa!
Jeg sidder og roder med noget c og jeg kunne godt tænke mig at lave en funktion som sortere på nogle data jeg har i en struct..

Min struct ser således ud:

struct data {           
    char navn[20];
    char sort[20];
    char farve[20];
    int pris;
};


jeg vil have den til at sortere efter navn variablen, så de data med a kommer før b osv.

Jeg vil blive meget glad hvis i gider kommentere/forklare den kode i laver!
På forhånd tak! :)
Avatar billede arne_v Ekspert
03. november 2003 - 19:36 #1
Jeg lavede den her kode til et andet spørgsmål:

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

struct info
{
  char *name;
  int grade;
};

void qs_help(int n1,int n2,struct info *a)
{
  struct info tmp;
  char pivot[33];
  int l = n1;
  int r = n2;
  strcpy(pivot,a[(n1+n2)/2].name);
  do {
      while(strcmp(a[l].name,pivot) < 0) l++;
      while(strcmp(a[r].name,pivot) > 0) r--;
      if(l<=r) {
        tmp = a[l];
        a[l] = a[r];
        a[r] = tmp;
        l++;
        r--;
      }
  } while(l<=r);
  if(n1<r) qs_help(n1,r,a);
  if(l<n2) qs_help(l,n2,a);
  return;
}

void qs(int n,struct info *a)
{
  qs_help(0,n-1,a);
  return;
}

#define KEY1 "Name:"
#define KEY2 "Grade:"

int main()
{
  int i,n;
  char line[133],*p1,*p2;
  struct info data[5000];
  FILE *fp,*fp2;
  fp = fopen("list.dat", "r");
  n=0;
  while(!feof(fp))
  {
      if(fgets(line,sizeof(line),fp))
      {
          p1 = strstr(line,KEY1) + strlen(KEY1);
          while(*p1==' ') p1++;
          p2 = strchr(p1,' ');
          data[n].name = (char *)malloc(p2-p1);
          strncpy(data[n].name,p1,p2-p1);
          data[n].name[p2-p1] = '\0';
          data[n].grade = atoi(strstr(line,KEY2)+strlen(KEY2));
          n++;
      }
  }
  fclose(fp);
  qs(n,data);
  fp2 = fopen("sortlist.dat", "w");
  for(i=0;i<n;i++)
  {
      fprintf(fp2,"%s %s %s %d\n",KEY1,data[i].name,KEY2,data[i].grade);
  }
  fclose(fp2);
  return 0;
}
Avatar billede arne_v Ekspert
03. november 2003 - 19:38 #2
Du kan ignorere indlæsning og udskrivning af data, fordi den er sikkert
anderledes hos dig.

Så er der selve sorteringen.

Hvor jeg har valgt at lave en QuickSort.
Avatar billede darkie88 Nybegynder
03. november 2003 - 19:38 #3
hehe.. ja det forstår jeg jo så ikke så meget af.. kan du ikke forklare koden lidt?
Avatar billede arne_v Ekspert
03. november 2003 - 19:39 #4
Der er flere alternativer.

Hvis der kun er få elementer man skal have sorteret kan man vælge
en primitiv sortering.

Eller man kan vælge at bruge C's indbyggede qsort funktion.
Avatar billede arne_v Ekspert
03. november 2003 - 19:40 #5
Er det selve sorteringen du mangler forståelse for ?
Avatar billede darkie88 Nybegynder
03. november 2003 - 19:46 #6
ja.. min nuværrende sortering ser sådan ud:

void sorter(int nr, vine l[]){   
    if (nr>=3) {
        int i,j,t;
        t=0;
        for (i=1; i<nr;    i++) {
            for (j=1; j<nr;    j++){
                t = t + 1;   
                if (l[j].navn > l[j+1].navn){
                    l[0]  = l[j];
                        l[j]  = l[j+1];                 ´                      l[j+1] = l[0];
                    }
                }
            }
        cout<<"\nDe"<<" "<<nr-1<<" "<<"vine er soteret"<<endl;
    } else
        {
    cout<<"\nDer enten ingen vin, eller ogsaa var der ikke nok til at sortere"<<endl;
    }
    return;
}





nr er min pointer og l er navnet på min struct når jeg stopper data i den!
Avatar billede darkie88 Nybegynder
03. november 2003 - 19:47 #7
det skulle gerne være en bublesort.. men den virker ikke helt..
Avatar billede arne_v Ekspert
03. november 2003 - 19:47 #8
Prøv og kig på det her meget simple eksempel:

#include <stdio.h>
#include <string.h>

struct data
{         
    char navn[20];
    char sort[20];
    char farve[20];
    int pris;
};

int main()
{
    int i,j;
    struct data a[3],tmp;
    /* initialiser data */
    strcpy(a[0].navn,"ccc");
    a[0].pris = 100;
    strcpy(a[1].navn,"bb");
    a[1].pris = 10;
    strcpy(a[2].navn,"a");
    a[2].pris = 1;
    /* udskriv data */
    for(i=0;i<3;i++)
    {
      printf("%s %d\n",a[i].navn,a[i].pris);
    }
    /* sorter */
    for(i=0;i<3;i++)
    {
        for(j=(i+1);j<3;j++)
        {
            if(strcmp(a[i].navn,a[j].navn)>0)
            {
                tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }
        }
    }
    /* udskriv data */
    for(i=0;i<3;i++)
    {
      printf("%s %d\n",a[i].navn,a[i].pris);
    }
    return 0;
}
Avatar billede darkie88 Nybegynder
03. november 2003 - 19:48 #9
prøver lige!
Avatar billede arne_v Ekspert
03. november 2003 - 19:49 #10
Selve sorteringen er faktisk til at forstå:

    /* sorter */
    for(i=0;i<3;i++)
    {
        for(j=(i+1);j<3;j++)
        {
            if(strcmp(a[i].navn,a[j].navn)>0)
            {
                tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }
        }
    }
den yderste løkker kører over alle elementer
den inderstre løkke kører over alle elementer som ligger efter det vi står med
så bruger vi strcmp til at sammenligne strenge med
og hvis de ikke passer så bytter vi rundt på dem ved hjælp af tmp
Avatar billede darkie88 Nybegynder
03. november 2003 - 19:53 #11
hmmm jeg kigger lige på det til i morn.. du får nok pointene alligevel :)
Avatar billede segmose Nybegynder
04. november 2003 - 11:31 #12
C qsort exemple (ikke testet).

typedef struct data {
  char navn[20];
  char sort[20];
  char farve[20];
  int pris;
} Data;

Data data[MAXNOOFDATA];

/*
  cmp function for qsort
*/
#define CMPSTR(X)\
int cmp##X(const void *x1, const void *x2) {\
  return strncmp(((Data *)x1)->X, ((Data *)x2)->X, sizeof(Data.X));\
}
CMPSTR(navn)
CMPSTR(sort)
CMPSTR(farve)
int cmpPris(const void *x1, const void *x2) {
  if (((Data *)x1)->pris > ((Data *)x2)->pris)
    return 1;
  if (((Data *)x1)->pris < ((Data *)x2)->pris)
    return -1;
  return 0;
}

void SortAfter(void) {
  char
    choise;

  printf("Sort after (Nanv, Sort, Color, Price):");
  choise = getchar();
 
  switch(choise) {
    case 'n': case 'N':
      qsort((void *)data, index, sizeof(data[0]), cmpNavn);
      break;
    case 'p': case 'P':
      qsort((void *)data, index, sizeof(data[0]), cmpPris);
      break;
    case 's': case 'S':
      qsort((void *)data, index, sizeof(data[0]), cmpSort);
      break;
    case 'c': case 'C':
      qsort((void *)data, index, sizeof(data[0]), cmpFarve);
      break;
    default:
      printf("Unknown sorting choise\n");
      break;
  }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester