Primfaktorzerlegung in C mit Schnittstelle

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Bumblebe3
Beiträge: 10
Registriert: Fr Mai 15, 2015 1:21 pm

Primfaktorzerlegung in C mit Schnittstelle

Beitrag von Bumblebe3 » Fr Mai 15, 2015 1:24 pm

Ich habe folgende Rahmenbedingungen:

- keine globalen Variablen
- innerhalb der Funktion keine Ein- und Ausgabe erlaubt
- die Kommunikation muss über die Schnittstelle erfolgen

Also das Programm mit der Primfaktorzerlegung muss in folgende Schnittstelle gepackt werden:
int primfaktor ( int );

Die Funktion gibt bei jedem Funktionsaufruf mit einem Parameter n den nächsten Primfaktor von n
zurück (also numerisch aufsteigend, mehrfach vorkommende Faktoren werden auch mehrfach zurückgegeben). Sobald sich der Wert der übergebenen Zahl n ändert beginnt die Funktion wieder von vorne mit der Primfaktorzerlegung. Hat die Funktion alle Primfaktoren für ein n errechnet und zurückgegegeben so gibt sie (bis zum Aufruf mit einem neuen Wert n) immer -1 zurück.

Im Fehlerfall gibt die Funktion immer den Wert -2 zurück.

Mir fehlt jetzt eigentlich nur noch das mit -1 und mit -2 aber wie bau ich das noch ein?

Code: Alles auswählen

#include <stdio.h>
#include <math.h>
 
int primfaktor(int n)
{
     int i;
 
  while (n%2 == 0)
  {
  printf("%d ", 2);
  n = n/2;
  }
 
 
  for (i = 3; i <= sqrt(n); i = i+2)
  {
 
  while (n%i == 0)
  {
  printf("%d ", i);
  n = n/i;
  }
  }
 
 
  if (n > 2)
  printf ("%d ", n);
}
int main()
{
  int pf;
 
  while ((pf = primfaktor (12))> 1)
  printf ("%d\n", pf);
  while ((pf = primfaktor(7)) > 1)
  printf ("%d\n", pf);
  printf ("%d\n" , primfaktor (1));
  system("PAUSE");
  return 0;
 
}	
Die Ausgabe sollte so aussehen:
2
2
3
7
-2 usw.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Primfaktorzerlegung in C mit Schnittstelle

Beitrag von cloidnerux » Fr Mai 15, 2015 1:52 pm

Hi und Willkommen im Forum :D
Also das Programm mit der Primfaktorzerlegung muss in folgende Schnittstelle gepackt werden:
int primfaktor ( int );
Vorweg: ich habe ein Problem mit dem Begriff "Schnittstelle". Schnittstellen hat man egt in einem anderen Kontext.
Was man hier hat ist eine Funktion mit einer vorgegeben Signatur.
Mir fehlt jetzt eigentlich nur noch das mit -1 und mit -2 aber wie bau ich das noch ein?
Ich denke mal, dass du Punkt 2 deiner Aufgabenstellung misachtet hast:
innerhalb der Funktion keine Ein- und Ausgabe erlaubt

Code: Alles auswählen

int primfaktor(int n)
{
     int i;

  while (n%2 == 0)
  {
  printf("%d ", 2);
  n = n/2;
  }
Um das vlt nochmal klar zu machen:
Du sollst eine Funktion "primfaktor" schreiben, die bei folgendem Aufuruf:

Code: Alles auswählen

printf("%d\n", primfaktor(10));
printf("%d\n", primfaktor(10));
printf("%d\n", primfaktor(10));
printf("%d\n", primfaktor(7));
printf("%d\n", primfaktor(7));
folgende Ausgabe liefert:

Code: Alles auswählen

2
5
-1
7
-1
Die Aufgabe spielt darauf an, dass du mit statischen Variablen Werte von vorhergehenden Durchläufen speichern kannst, um so abhängig von vorhergehenden Aufrufen die Ausgabe anzupassen.
Damit wird auch dein momentanes Problem recht einfach: Wurde die Funktion irgendwann so oft aufgerufen, dass es keine weiteren Primfaktoren mehr gibt, gibst du -1 zurück.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Bumblebe3
Beiträge: 10
Registriert: Fr Mai 15, 2015 1:21 pm

Re: Primfaktorzerlegung in C mit Schnittstelle

Beitrag von Bumblebe3 » Fr Mai 15, 2015 2:07 pm

Mir wurde beigebracht das es Schnittstellen sind :D Eine Frage, die ganzen printf() kann ich doch durch return ersetzen oder?

Wie soll das mit statischen Variabeln aussehen?

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Primfaktorzerlegung in C mit Schnittstelle

Beitrag von cloidnerux » Fr Mai 15, 2015 2:32 pm

Mir wurde beigebracht das es Schnittstellen sind :D
Jeder darf alles nennen wie er will, man muss dann nur damit rechnen, dass andere einen nicht verstehen.
ine Frage, die ganzen printf() kann ich doch durch return ersetzen oder?
Das kannst du machen, das wird in deinem Fall aber nicht funktionieren, weil du deine Funktion falsch angefangen hast.
Wie soll das mit statischen Variabeln aussehen?
Ich werde dir jetzt nicht deine Aufgabe lösen, daher nur konzeptionell:

Statische Variablen behalten ihren Wert, wenn die Funktion erneut aufgerufen wird.
Du überprüfst als erstes, ob das n aus dem vorherigen Aufruf mit dem n aus dem jetzigen Aufruf überein stimmt. Ist dem nicht der Fall alle anderen Variablen zurück setzten.

Dann hast du eine weitere statische Variable primRest.
primRest ist für den ersten Aufruf mit einem neuen n gleich n und wird mit jedem weiteren Aufruf durch den gefundenen Primfaktor geteilt.
Damit ist die Endedingung, dass primRest gleich 1 ist.
Solange primRest nicht 1 ist, suchst du von 2 an eine natürliche Zahl i, mit der du primRest Restfrei Teilen kannst. Findest du einen, teilst du primRest dadurch und gibst den primFaktor zurück.

Du musst also deine Funktion einmal komplett neu schreiben, sonst wirst du die Aufgabe nicht lösen können.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Bumblebe3
Beiträge: 10
Registriert: Fr Mai 15, 2015 1:21 pm

Re: Primfaktorzerlegung in C mit Schnittstelle

Beitrag von Bumblebe3 » Fr Mai 15, 2015 2:37 pm

Code: Alles auswählen

int primfaktor(int n)
{
  int i;
 
  if(n < 1)
  	return -2;
 
  if(n==1)
  	return -1;
 
  if (n%2 == 0)
  {
    return 2;
  }
 
  for (i = 3; i <= sqrt(n); i = i+2)
  {
    if (n%i == 0)
  	{
  		return i;
  	}
  }
 
  return n;
}
 
int main()
{
  int r, pf=65535;
 
  while ((r = primfaktor (pf))> 1)
  {
  	printf("%d\n",r);
  	pf=pf/r;
  }
  
  return 0;
}
Meinst das könnte stimmen?

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Primfaktorzerlegung in C mit Schnittstelle

Beitrag von cloidnerux » Fr Mai 15, 2015 3:18 pm

Meinst das könnte stimmen?
Das ist schon mal fast das, was du machen sollst.
Jetzt musst du das Teilen durch dein r nur noch in deine Funktion packen. Eben mit statischen Variablen.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Bumblebe3
Beiträge: 10
Registriert: Fr Mai 15, 2015 1:21 pm

Re: Primfaktorzerlegung in C mit Schnittstelle

Beitrag von Bumblebe3 » Fr Mai 15, 2015 3:23 pm

Und wie? Wir haben statische Variabeln noch nicht behandelt :(

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Primfaktorzerlegung in C mit Schnittstelle

Beitrag von cloidnerux » Fr Mai 15, 2015 4:57 pm

Hier steht was eine statische Variable ist:
https://www.proggen.org/doku.php?id=c:attr:static
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Primfaktorzerlegung in C mit Schnittstelle

Beitrag von Xin » Mo Mai 18, 2015 2:39 pm

cloidnerux hat geschrieben:
Mir wurde beigebracht das es Schnittstellen sind :D
Jeder darf alles nennen wie er will, man muss dann nur damit rechnen, dass andere einen nicht verstehen.
Ich glaube, ihr meint beide das Richtige...

Eine einzelne Funktion hat erstmal eine Signatur, wie cloidnerux richtig sagt, die man halt innerhalb eines Programms aufrufen kann.
Eine Schnittstelle hat eine oder mehrere Funktionen, die eben die Kommunikation zwischen zwei Programmteilen standardisiert.
Wenn wir davon ausgehen, dass eine Funktion einen Programmteil kapselt, so stellt eine einzelne Funktion durchaus auch eine Schnittstelle dar - was z.B. bei der Datenbank BTrieve dazu führt, dass es nur eine Funktion gibt mit deren Aufruf man die komplette Datenbank steuert, reinschreibt oder daraus ausliest. Das wäre dann ebenfalls eine Schnitstelle. Weil das eher grausam ist, haben Schnittstellen eher mehrere Funktionen und kapseln größere Programmeeinheiten und nicht nur ein kleines Unterprogramm.

Das sind aber eigentlich eher gefühlte Wahrheiten. Ich tendiere hier auch eher zu cloidnerux Sichtweise (weil die Begriffe sonst keinen Sinn ergeben würden), aber man kann die eine Funktion durchaus als die kleinstmögliche Schnittstelle bezeichnen, womit sie ein Spezialfall wäre - oder eben als ganz normale Signatur.

Diese sprachliche Ungenauigkeit könnte sich auch in der Aufgabenstellung wiederspiegeln. Die Lösung ist sicherlich legitim, aber mit einer solchen Signatur/Schnittstelle nicht mehr zeitgemäß. Die Frage, die Du Dir noch nicht stellen musst, aber die Dein Lehrer berücksichtigen sollte wäre, ob die geforderte Implementierung bei paralleler Nutzung von mehreren CPU-Kernen noch funktionsfähig ist. Statische Variablen sind nicht global sichtbar, agieren aber wie globale Variablen, wenn die Funktion gleichzeitig mehrfach ausgeführt wird. Sie sind daher genauso zu vermeiden, wie globale Variablen.

Löse die Aufgabe erstmal wie gefordert mit statischen Variablen, für eine gute Implementierung empfehle ich Dir jedoch die Signatur der Funktion zu ändern und zum Beispiel einen C++Vector mit allen Primzahlen auszugeben.
Das musst Du jetzt noch nicht verstehen, aber das sind die Schlüsselwörter, mit denen Du Dich auf kurz oder lang beschäftigen solltest. Wir können uns das angucken, wenn Du das Problem der Aufgabe gelöst hast.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten