Mirpzahl

Mirpzahl

Beitragvon Cashdogg » 08.07.2010 20:37

Hallöchen,

ich hab mich mal an einer Aufgabe aus ner alten Klausur versucht, in der man bestimmen sollte, ob eine eingegebene Zahl eine Mirpzahl ist, d.h. Zahl und gespiegelte Zahl jeweils Primzahlen sind (Bsp.: 13 und 31).
Großes Problem dabei (zumindest fand ich das) ist es die eingegebene Zahl zu spiegeln. Ich hab da jetzt mal rumgeflickt und hab eine Funktion entworfen, die die eingegeben (long) Zahl über das Zehnersystem in einen Array umwandelt, anschließend dreht, und dann den gedrehten Array wieder als (long) Zahl ausgibt. Da in der Aufgabe aber steht, dass man irgend eine Zahl eingeben kann muss ich als Übergabewert der Funktion auch die jeweilige Größe des Arrays übermitteln. Und genau da scheine ich irgendwie Fehler zu machen.

Wenn ich nämlich den Array Zehnersystem in der Funktion deklariere bekomme ich vom Kompiler drei Fehlermeldungen in einer kleinen Zeile:

- error C2057: Konstanter Ausdruck erwartet
- error C2466: Zuordnung eines Arrays der konstanten Größe 0 nicht möglich
- error C2133: 'Zehnersystem': Unbekannte Größe

Code: Alles auswählen
#include <iostream>
#include <cmath>

using namespace std;

bool Teilerzahl(long a)
{
   //Primärzahl hat nur zwei Teiler
   
   int counter=0;
   for (int i=1; i<=a; i++)
   {
      if (a%i==0)
         counter++;
   }

   if (counter >2)
      return false;
   else
      return true;
}

long Konvertiere(long a, int N)
{
   // Umwandlung in 10erSystem-Feld (10^i)

   int Zehnersystem[N];
   for (int i=N; i>=0; i--)
   {
      Zehnersystem[i]=int (a/pow(10.0,i));
      a-=Zehnersystem[i]*pow(10.0,i);
   }

   // Umkehrung des 10erSystem-Felds

   int Sortierbreite=N/2;

   for (int i=0; i<Sortierbreite; i++)
   {   
      int temp=Zehnersystem[i];
      Zehnersystem[i]=Zehnersystem[N-i];
      Zehnersystem[N-i]=temp;
   }

   // Bestimmmung der Zahl aus dem konvertierten Zehnersystem

   long convert=0;
      for (int i=N; i>=0; i--)
         convert+=(Zehnersystem[i]*int(pow(10.0,i)));

      return convert;   
}

int main()
{
   long Zahl;
   
   cout << "Zahl bitte (>9, <11.1111): ";
   cin >> Zahl;

   if (Zahl<10)
   {
      cout << "Naja, das ist ja wohl sinnlos. Die Zahl darf ruhig mehrere Stellen haben!" << endl;
      return (1);
   }

   if (Zahl>11111)
   {
      cout << "Übertreiben wollen wir es nicht. Die Zahl darf ruhig ein bisschen kleiner sein!" << endl;
      return (1);
   }

   long Convert;
   
   if (Zahl < 100)
      Convert=Konvertiere(Zahl, 2);
   if (Zahl < 1000 && Zahl >=100)
      Convert=Konvertiere(Zahl, 3);
   if (Zahl < 10000 && Zahl >=1000)
      Convert=Konvertiere(Zahl, 4);

   if (Teilerzahl(Zahl) && Teilerzahl(Convert))
      cout << endl << "Die eigegebene Zahl ist ein Mirpzahl!" << endl;
   else
      cout << endl << "Die eigegebene Zahl ist keine Mirpzahl!" << endl;
}


Vielleicht möchte sich noch jemand damit beschäftigen und weis vielleicht sogar einer einfachere (d.h. mit den in der Vorlesung vermittelten Grundlagen konstruierbare) Möglichkeit die Zahl zu drehen.

Gruß Cashdogg500
Cashdogg
 
Beiträge: 408
Registriert: 20.12.2008 15:05

Re: Mirpzahl

Beitragvon Rene » 08.07.2010 20:42

Dein Problem ist ganz einfach: Du versuchst einen Arry der Größe N zu deklarieren, wobei N kein const int ist. Für das deklarieren eines Arrays auf deine Art beötigst du als Größenangabe aber eine const int.

Ein Methode wäre die dynamische Speicheralokation mittels des new Befehls, falls bekannt.
Rene
 
Beiträge: 136
Registriert: 11.11.2008 19:59

Re: Mirpzahl

Beitragvon Cashdogg » 08.07.2010 21:02

Also ich hab auch schon probiert im Header const int N anstelle int N einszusetzen. Aber da kommen dieselben Fehler :? .

New-Befehl hat doch was mit Zeiger zu tun, oder? Das hatten wir nur relativ kurz in der Vorlesung angespochen und hatten auch keine Übung dazu, von daher denke ich dass das in der Klausur nicht Stoff sein wird.
Cashdogg
 
Beiträge: 408
Registriert: 20.12.2008 15:05

Re: Mirpzahl

Beitragvon test123 » 08.07.2010 21:56

hab hier zum zahlendrehen mal was zusammengefrimelt was mit ner einfachen modulo rechnung die zahlen dreht.
mit den paar Zahlen die ich ausprobiert hab hats funktioniert, kann aber nicht garantieren, dass es nicht doch irgendwo nicht passt.
Code: Alles auswählen
#include <iostream>

using namespace std;

int zahldrehen(int zahl)
{
  int gedrehtezahl=0;
  int temp=0;
  while(zahl>0)
  {
    temp=gedrehtezahl;
    gedrehtezahl=(zahl % 10);
    gedrehtezahl+=temp*10;
    zahl=zahl/10;
  }
  return gedrehtezahl;
}
int main()
{
  int zahl;
  cin >> zahl;
  int gedrehtezahl = zahldrehen(zahl);
  cout << gedrehtezahl << endl;
}


Edit:
Die temp Zahl war natürlich total unnötig wie mir grad so auffällt.
So gehts noch n Fetz schöner:
Code: Alles auswählen
int zahldrehen(int zahl)
{
  int gedrehtezahl=0;
  while(zahl>0)
  {
    gedrehtezahl=zahl % 10+gedrehtezahl*10;
    zahl=zahl/10;
  }
  return gedrehtezahl;
}
Zuletzt geändert von test123 am 08.07.2010 22:38, insgesamt 1-mal geändert.
test123
 
Beiträge: 10
Registriert: 28.10.2009 10:12

Re: Mirpzahl

Beitragvon Cashdogg » 08.07.2010 22:12

Kann man auf so eine Lösung in der Klausur kommen, oder ist das ein Algo den sich irgendjemand besonders kluges ausgedacht hat und den man einfach kennen muss (z.B. aus den Übungen) :D ? Weil ich kann das jetzt so auf die Schnelle (oder vielleicht auch im die Uhrzeit) nicht nachvollziehen.
Cashdogg
 
Beiträge: 408
Registriert: 20.12.2008 15:05

Re: Mirpzahl

Beitragvon test123 » 08.07.2010 22:28

also die Lösung ist mir gerade eingefallen, aber wenn man n paar mal mit modulo rumgespielt hat, denkt man da auch direkt drann,
da das für das Problem (immer die letzte Ziffer zu bekommen) recht naheliegend ist ;)

Hier mal das ganze etwas kommentiert:

gedrehtezahl=zahl % 10+gedrehtezahl*10;
Hierbei wird die letzte Ziffer der Zahl zur "alten" gedrehten Zahl addiert.
Beim ersten Durchlauf ist diese Null und somit geht hier nur die letzte Ziffer mit ein.
Beim nächsten Durchlauf ist diese letzte Ziffer die alte gedrehte Zahl
und geht somit *10 in die neue gedrehte Zahl ein und die letzte Ziffer der um eine Stelle kleineren Zahl wird wieder dazuaddiert.

zahl=zahl/10;
Da ints keine Nachkommastellen haben, fallen diese einfach beim durch 10 teilen weg
und man macht die Zahl somit um die letzte Ziffer kleiner.

Das Ganze wird dann so lange Durchlaufen bis die Zahl keine Stellen mehr hat,
da zahl/10=0 für Zahl <= 10
test123
 
Beiträge: 10
Registriert: 28.10.2009 10:12

Re: Mirpzahl

Beitragvon Cashdogg » 10.07.2010 11:33

So hier ist auch noch mein nun funktionierendes Porgramm. Wie in der Übung gestern angesprochen, war das Problem einfach, dass ich einer Funktion keinen Wert übergeben kann, der im Weiteren als Feldgröße verwendet wird, da da die Feldgröße im Voraus bekannt sein muss. Deshalb muss ich die entsprechende Pointerschreibweise für die Deklaration des Feldes in der Funktion verwenden.

Code: Alles auswählen
#include <iostream>
#include <cmath>

using namespace std;

bool Teilerzahl(long a)
{
   //Primärzahl hat nur zwei Teiler
   
   int counter=0;
   for (int i=1; i<=a; i++)
   {
      if (a%i==0)
         counter++;
   }

   if (counter >2)
      return false;
   else
      return true;
}

long Konvertiere(long a, int N)
{
   // Umwandlung in 10erSystem-Feld (10^i)

   int*Zehnersystem=new int[N];         //Hier lag der Fehler (Defintion mittels Pointer, A[N] nicht standartisiert, da N erst zu Laufzeit festseht, Speicherplatz aber vorab bekannt sein muss).
   for (int i=N-1; i>=0; i--)
   {
      Zehnersystem[i]=int (a/pow(10.0,i));
      a-=Zehnersystem[i]*pow(10.0,i);
   }

   // Umkehrung des 10erSystem-Felds

   int Sortierbreite=N/2;

   for (int i=0; i<Sortierbreite; i++)
   {   
      int temp=Zehnersystem[i];
      Zehnersystem[i]=Zehnersystem[N-1-i];
      Zehnersystem[N-1-i]=temp;
   }

   // Bestimmmung der Zahl aus dem konvertierten Zehnersystem

   long convert=0;
      for (int i=N-1; i>=0; i--)
         convert+=(Zehnersystem[i]*int(pow(10.0,i)));
   
      return convert;   
}

int main()
{
   long Zahl;
   long Convert;
   
   cout << "Zahl bitte (>9 und <10.000): ";
   cin >> Zahl;

   if (Zahl<10)
   {
      cout << "Naja, das ist ja wohl sinnlos. Die Zahl darf ruhig mehrere Stellen haben!" << endl;
      return (1);
   }
   if(Zahl>=10000)
   {
      cout << "Übertreiben wollen wir es nicht. Die Zahl darf ruhig ein bisschen kleiner sein!" << endl;
      return (1);
   }

   if (Zahl < 100 && Zahl >= 10)
      Convert=Konvertiere(Zahl, 2);
   if (Zahl < 1000 && Zahl >=100)
      Convert=Konvertiere(Zahl, 3);
   if (Zahl < 10000 && Zahl >=1000)
      Convert=Konvertiere(Zahl, 4);

   if (Teilerzahl(Zahl) && Teilerzahl(Convert))
      cout << endl << "Die eigegebene Zahl ist ein Mirpzahl!" << endl;
   else
      cout << endl << "Die eigegebene Zahl ist keine Mirpzahl!" << endl;
}
Cashdogg
 
Beiträge: 408
Registriert: 20.12.2008 15:05

Re: Mirpzahl

Beitragvon CommanderTomalak » 11.07.2010 14:46

Ach, Jungs, ganz ernst gemeinter Tipp: wenn man alle Teiler einer Zahl finden will, müsst ihr nicht alle Zahlen bis zur angegebenen Zahl durchlaufen, ihr könnt bei der Hälfte abbrechen! Ein Teiler einer Zahl kann niemals größer sein als ihre Hälfte ;)

so kann man zum Beispiel sehr bequem prüfen, ob irgendwas eine Primzahl ist:

Code: Alles auswählen
bool istPrim(long input)
{
    // Wenn irgendeine Zahl zw. 2 und der Hälfte der Zahl ein Teiler ist, ist das keine Primzahl
    for(int i = 2; i < input/2; i++)
        if(input % i == 0) return false;
       
    return true;
}
"Das Volk hat das Vertrauen der Regierung verscherzt. Wäre es da nicht doch einfacher, die Regierung löste das Volk auf und wählte ein anderes?"
- Bertolt Brecht
CommanderTomalak
 
Beiträge: 204
Registriert: 19.01.2009 00:42
Wohnort: Karlsruhe


Zurück zu Programmieren

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron