d'hondt verfahren in c



  • okay ich dachte ich würd allein zurecht kommen aber ich hab überhaupt keine idee mehr wie ich an das problem raangehen soll.
    Bitte kann mir jemand helfen ich muss das Programm am Montag abgeben.
    mfg
    CJ



  • Wenn du nicht weißt, wie man ein Array in C sortiert, dann fehlen dir absolute Grundlagen. Die musst du dir dann eben aneignen, d.h. hinsetzen und lernen.



  • ich weiss wie man ein array sortiert(z.B. mit bubblesort), ich weiss nur nicht wie ich dieses Programm realisieren soll-.-



  • Hast du denn schon Code, der funktioniert? Fang doch schon mal mit der Einlesefunktion an. Du hast zwar eine gepostet, aber funktioniert die auch? Etwas wirr/umständlich sieht das schon aus. Das geht wesentlich einfacher.
    Es wäre hilfreich wenn du eine Funktion schreibst, welche die Parteien mit den erhaltenen Stimmmen einliest und in der Konsole ausgibt.
    Wenn das funzt, gehst du einen Schritt weiter und speicherst diese Daten in Strukturen, als Vorbereitung für die Berechnung, usw.
    Poste doch auch mal das Dateiformat - sind alle Daten in einer Zeile, oder pro Partei eine Zeile, etc.



  • So ich habe die Eingabe jetzt soweit das sie funktioniert und habe jetzt auch einen ansatz zur Berechnung, wobei dieser noch nicht alle Fälle abdeckt.
    Aber ich bekomme nun einen Fehler:
    error C2371: 'berechneSitze': Neudefinition; unterschiedliche Basistypen c:\users\cj\documents\visual studio 2010\projects\einlesen.c\einlesen.c\einlesen.c Zeile:80 1 einlesen.c

    Der komplette Code dazu ist folgender:(Wobei sich der Fehler auf die berechneSitze() bezieht, da seit dem ich diese Funktion eingebaut habe ich denn Fehler bekomme.

    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>
    
    #define N_PARTEIEN 200
    #define N_SITZE 300
    #define N_STRING 80
    #define N_ZAHL 10
    
    typedef struct{
    	char name[N_STRING];
    	int stimmen;
    	int sitze;
    	double prozent;
    }PARTEI;
    
    void printPartei (PARTEI p) {
      printf ("Partei %-20s Stimmen=%8d Sitze = %5d Prozent = %3.2lf%%\n", 
        p.name, p.stimmen, p.sitze, p.prozent*100);
    }
    
    PARTEI liesPartei (char * zeile) {
      PARTEI partei = {"", 0, 0, 0.0 };
      char zahl[N_ZAHL];
      char c = '#';
      int i, o;
      for (i = 0; i < N_STRING; i++) {
        if (zeile[i] == c) {
          partei.name[i] = 0;
          break;
        }
        partei.name[i] = zeile[i];
      }
      if (zeile[i] != c)
    	  printf ("# fehlt");
      for (o=0, i++; i < N_STRING && o < N_ZAHL; i++, o++) {
        zahl[o] = zeile[i];
        if (zeile[i] == 0) {
          break;
        }
      }
      partei.stimmen = atoi (zahl);
      return partei;
    }
    
    	PARTEI partei[N_PARTEIEN];
    	int anzahlSitze = 0;
    	int anzahlParteien = 0;
    	int anzahlStimmen = 0;
    
    void eingabe (char* name)
    {
    	int i = 0;
    	PARTEI p[N_PARTEIEN];
      char zeile[N_STRING];
      FILE* f = fopen (name, "r");
      if (f == NULL) 
        printf("Datei nicht gefunden");
      fscanf (f, "%d\n", &anzahlSitze);
      while (fgets (zeile, N_STRING-1, f))
      {
    	i++;
        p[i] = liesPartei (zeile);
        printPartei (p[i]);
    
      }
      berechneSitze(p);
    }
    
      void ausgabe()
      {
      int i = 0;
      printf ("Anzahl der Parteien = %d \\n", anzahlParteien);
      for (i = 0; i < anzahlParteien; i++)
        printPartei (partei[i]);
    }
    
      void berechneSitze(PARTEI pa[])
      {
    	  int m,j, k, l;
    	for(k = 1; k <= anzahlSitze; k++)
    {		
    	for(m = 1, j = 1;  m < anzahlParteien && j < anzahlParteien;)
    	{
    		if(pa[m].stimmen < pa[j].stimmen)
    		{
    			m++;
    		}
    		else
    		{
    			if(pa[j].stimmen < pa[m].stimmen)
    			{
    				j++;
    			}
    			else
    			{
    				if(pa[m].stimmen == pa[j].stimmen && m == j)
    				{
    					m++;
    				}
    				else
    				{
    					printf("Fehler");
    				}
    			}
    		}
    	}
    		if (pa[m].stimmen < pa[j].stimmen)
    		{
    			pa[j].sitze++;
    			printf("Partei %d hat %d Sitze", j, pa[j].sitze);
    			pa[j].stimmen = pa[j].stimmen/(k + 1);
    
    		}
    		else
    		{
    			if(pa[j].stimmen <= pa[m].stimmen)
    			{
    				pa[m].sitze++;
    				printf("Partei %d hat %d Sitze", m, pa[m].sitze);
    				pa[m].stimmen = pa[m].stimmen/(k + 1);
    
    			}
    
    		}
    	}
    }
    
    int main()
    {
    	char *name = "C:\\Users\\cj\\Desktop\\dhondt-ergebnisse.txt"; 
    	eingabe (name);
    
    }
    

    Das aufgerufene Format ist wie oben genannt .txt.
    Und die txt ist wie folgt aufgebaut:
    Partei A # 1000
    Partei B # 2000
    Name der Partei # Stimmen

    Ich hoffe die Informationen konnten euch helfen hier einblick zu erhalten.



  • ich konnte denn fehler jetzt lösen indem ich die berechneSitze() vor der eigabe() schrieb. Allerdings wird die berechneSitze() jetzt nicht bearbeitet-.- und somit einfch beim debuggen übersprungen



  • Der Funktionsaufruf in Zeile 68 ging schief, weil der Prototyp nicht bekannt war.
    Wenn du am den Anfang des Programms die Funktion deklarierst,

    void berechneSitze(PARTEI pa[]);
    

    dann funzt das.
    Die Funktion berechneSitze wird bestimmt aufgerufen, aber vllt. passiert deshalb nichts weiter weil vllt. anzahlSitze Null ist?



  • ALso das Programm fürht nun die berechneSitze() aus allerdings übernimmt es mir nicht die aus der Datei eingelesenen Dateien in die berechneSitze(). Wie kann ich die eingelesene Partei denn nun in die berechneSitze übergeben?
    Danke wegen der Hilfe bis jetzt:)



  • cjarma schrieb:

    while (fgets (zeile, N_STRING, f))  
      {
        i++;
        p[ i ] = liesPartei (zeile);
        printPartei (p[ i ]);
       
      }
    

    Du solltest i nur dann inkrementieren, wenn ein Datensatz erfolgreich eingelesen wurde, sonst steht da Datenmüll drin.

    Es ist auch gar nicht nötig, dass du anzahlSitze global deklarierst.
    Das gilt auch für die übrigen Variable.
    Du kannst die Anzahl der eingelesenen Datensätze beim Einlesen zählen und dann
    als Parameter übergeben:

    void berechneSitze(PARTEI pa[N_PARTEIEN], int anzahl );
    


  • okay ich habe das Programm jetz soweit zum laufen gebracht und es funktioniert auch, wobei ich noch die Prozentberechnung einbauen muss aber das dürfte kein Problem ergeben. Allerdings bekomme ich jetzt wenn das Programm beendet ist den Fehler: Run-Time Check Failure #2 - Stack around the variable 'p' was corrupted.

    hier nochmal der code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>
    
    #define N_PARTEIEN 200
    #define N_SITZE 300
    #define N_STRING 80
    #define N_ZAHL 10
    
    typedef struct{
    	char name[N_STRING];
    	int stimmen;
    	int sitze;
    	double prozent;
    }PARTEI;
    
    void printPartei (PARTEI p) {
      printf ("Partei %-20s Stimmen=%8d Sitze = %5d\n", 
        p.name, p.stimmen, p.sitze, p.prozent*100);
    }
    
    PARTEI liesPartei (char * zeile) {
      PARTEI partei = {"", 0, 0, 0.0 };
      char zahl[N_ZAHL];
      char c = '#';
      int i, o;
      for (i = 0; i < N_STRING; i++) {
        if (zeile[i] == c) {
          partei.name[i] = 0;
          break;
        }
        partei.name[i] = zeile[i];
      }
      if (zeile[i] != c)
    	  printf ("# fehlt");
      for (o=0, i++; i < N_STRING && o < N_ZAHL; i++, o++) {
        zahl[o] = zeile[i];
        if (zeile[i] == 0) {
          break;
        }
      }
      partei.stimmen = atoi (zahl);
      return partei;
    }
    
    	PARTEI partei[N_PARTEIEN];
    	int anzahlSitze = 0;
    	int anzahlParteien = 0;
    	int anzahlStimmen = 0;
    
    void ausgabe (PARTEI parteien[]) {
      int i = 0;
      printf ("Anzahl der Parteien = %d \\n", anzahlParteien);
      for (i = 0; i < anzahlParteien; i++)
        printPartei (parteien[i]);
    }
    
    	void berechneSitze(PARTEI pa[])
      {
    	  int a[N_PARTEIEN], b,m,j, k, l, o[N_SITZE], p[N_SITZE], n;
    	  for(n = 0; n <= N_SITZE; n++)
    	  {
    		  o[n] = 0;
    		  p[n] = 0;
    	  }
    	  for(n = 1; n <= anzahlParteien; n++)
    	  {
    		  a[n] = pa[n].stimmen;
    	  }
    	for(k = 1; k <= anzahlSitze; k++)
    {		
    	for(m = 1, j = 1;  m < anzahlParteien && j < anzahlParteien;)
    	{
    		if(pa[m].stimmen < pa[j].stimmen)
    		{
    			m++;
    		}
    		else
    		{
    			if(pa[j].stimmen < pa[m].stimmen)
    			{
    				j++;
    			}
    			else
    			{
    				if(pa[m].stimmen == pa[j].stimmen && m == j && m == anzahlParteien)
    				{
    					break;
    				}
    				else
    				{
    				m++;
    				}
    			}
    		}
    	}
    		if (pa[m].stimmen < pa[j].stimmen)
    		{
    			o[j]++;
    			pa[j].sitze++;
    			m++;
    			printf("%-20s hat %d Sitze\n", pa[j].name, pa[j].sitze);
    			pa[j].stimmen = a[j]/(o[j] + 1);
    
    		}
    		else
    		{
    			if(pa[j].stimmen <= pa[m].stimmen)
    			{
    				p[m]++;
    				pa[m].sitze++;
    				j++;
    				printf("%-20s hat %d Sitze\n", pa[m].name, pa[m].sitze);
    				pa[m].stimmen = a[m]/(p[m] + 1);
    
    			}
    
    		}
    	}
    	printf("Endergebnis:\n");
    	for(n = 1; n <= anzahlParteien; n++)
    	{
    		printf ("Partei %-20s Stimmen=%8d Sitze = %5d\n", 
    			pa[n].name, a[n], pa[n].sitze);
    	}
    }
    
    void eingabe (char* name)
    {
    	int i = 0;
    	PARTEI p[N_PARTEIEN];
      char zeile[N_STRING];
      FILE* f = fopen (name, "r");
      if (f == NULL) 
        printf("Datei nicht gefunden");
      fscanf (f, "%d\n", &anzahlSitze);
      while (fgets (zeile, N_STRING-1, f))
      {
    	anzahlParteien++;
    	i++;
        p[i] = liesPartei (zeile);
        printPartei (p[i]);
    
      }
      berechneSitze(p);
    }
    
    int main()
    {
    	char *name = "C:\\Users\\cj\\Desktop\\dhondt-ergebnisse.txt";
    	printf("Zu verteilende Sitze eingeben:");
    	scanf("%d", &anzahlSitze);
    	eingabe (name);
    
    }
    


  • An manchen Stellen in deinem Code werden Arraygrenzen überschritten.
    Das macht den Stack kaputt.



  • Habs gefunde 😃 war in der schleife die die felder des arrays auf 0 setzt.
    Hey ich wollte mich nochmal für die Hilfe bedanken, du hast mir echt geholfen 😃
    mfg
    cj



  • Okay, was ich aber meine sind Stellen im Code a la

    for(n = 0; n <= N_SITZE; n++)
    

    Das sprengt dir den Stack.
    Ich würde den Code noch vernünftig gliedern von den Einrückungen ganz zu schweigen.
    Und vor allem:
    Die Funktionen rufen sich verkettet gegenseitig auf, das ist stilistisch nicht besonders schön und später auch selbst für den Programmierer schwer lesbar/nachvollziehbar/wartbar.
    Wenn ich das bewerten müsste, würde ich fette Abzüge in der B-Note machen.
    :p


Anmelden zum Antworten