Kleine Schwierigkeit mit Arrays: Palindrom ja oder nein?
-
Außerdem müsste das operator== dort sein, nicht =. = bedeutet Zuweisung, == Vergleich.
-
Der Teil mit dem ==Operator ist mir bekannt. War auch nur ein Tippfehler.
cstrings benutze ich höchstwahrscheinlich wegen mangelnder Erfahrung. Ich danke für deine Antwort.string-compare (strcmp) habe ich zuvor schon versucht, gibt mir jedoch immer falsche Aussagen.
if(strcmp(arr, copy) == 0) { cout <<"\nEs handelt sich um ein Palindrom." << endl; } else { cout <<"\nKEIN Palindrom."<< endl; }Der oben stehende Code gibt mir jedoch in allen Eingabefällen "KEIN Palindrom" aus.
Ich habe natürlich sofort nachgeforscht und entdeckt, das der Vergleichswert für
strcmp(arr, copy) = -1
beträgt. Das hängt vermutlich mit meinen vorhergehenden Operationen zusammen. Wenn mir jemand Anweisungen nennen könnte, die in meinem Programm falsch sind, bzw. besser geignete Anweisungen vorschlagen könnte, wäre das eine >WIRKLICHE< Hilfe.Ich habe den Teil
cin.getline(arr,10); n = strlen(arr)-1;überpüft und herausgefunden, dass diese Anweisungen dafür verantwortlich sind, dass für strcmp(arr, copy) eine Wert ungleich 0 erscheint.
Ich habe schon einiges versucht, doch eine Lösung habe ich noch nicht gefunden.
-
Cruxi schrieb:
Der Teil mit dem ==Operator ist mir bekannt. War auch nur ein Tippfehler.
cstrings benutze ich höchstwahrscheinlich wegen mangelnder Erfahrung. Ich danke für deine Antwort.Wenn das Buch void main, string.h & Co. lehrt, dann wohl eher schlechtes Buch. Wenn es das Buch von 1999 ist, dann kann das da dran liegen, dass der erste offizielle C++-Standard von 1998 ist und das Buch sich noch auf dem Stand der "wilden Neunziger" ist.
Hier ist ein (ungetesteter) Palindromcode, wie ihn ein heutiger Anfänger nach etwas Nachdenken und Ausfeilen schreiben könnte:
#include <iostream> #include <string> using namespace std; bool ist_palindrom(const string &wort) { for(int i = 0; i < wort.size() / 2; ++i) // Für alle Buchstaben bis zur Mitte if(wort[i] != wort[wort.size() - 1 - i]) // Gucken ob der Buchstabe seinem Gegenüber entspricht (letzter Buchstabe in wort ist wort[wort.size() - 1] ) return false; // Falls nein -> Kein Palindrom return true; // Falls Schleife durchgelaufen ist -> Palindrom } int main() { cout << "Wort eingeben: "; string wort; cin >> wort; if(ist_palindrom(wort)) cout << wort << " ist ein Palindrom\n"; else cout << wort << "ist kein Palindrom\n"; }Je nach Kenntnisstand eventuell ohne Palindromprüfungsfunktion, sondern mitten im Programm. Funktionen kommen bestimmt bald im Buch, aber ich empfehle dir, zu einem anderen Buch zu greifen. Guck mal in den FAQ.
-
#include <iostream> #include <string> #include <algorithm> int main() { std::string word; while(std::cin >> word) std::cout << word << " ist " << (std::equal(word.begin(), word.end(), word.rbegin()) ? "" : "k") << "ein Palindrom.\n"; }
-
?: doch nicht.
std::cout << word << " ist " << std::equal(word.begin(), word.end(), word.rbegin()) + "kein Palindrom.\n";
-
Ups

-
volkard schrieb:
std::cout << word << " ist " << std::equal(word.begin(), word.end(), word.rbegin()) + "kein Palindrom.\n";*Den Trick in meine Obfuscation-Toolbox aufnehm*
Und wer erklärt das dem Threadersteller?

-
Vielen Dank! Genau nach solch einer Alternative habe ich gesucht.
Viel muss nicht mehr erklärt werden.Ich setze mich selbst mit euren Lösungsvorschlägen auseinander.
@ SeppJ deinen Code kann ich gut nachvollziehen.
Mein Problem war bloß, dass ich mich zuvor nur geringfügig mit dem Datentyp bool auseinandergesetzt habe. Vielen Dank!
@ 314159265358979 und volkard
Eure Lösung ist natürlich eie sehr angenehme und vorallem bequeme. Gefällt mir auch sehr. Danke.Eine weitere Frage bleibt mir doch noch. Da die Aufgaben, die mein Buch hergibt auf die jeweiligen Kapitel aufbaut, wurde hier vermutlich von mir erwartet, die Überprüfung eines Palindroms mit Hilfe von Arrays durchzuführen.
Gäbe es da auch eine Lösung? (Mir ist klar, dass diese Lösung sehr viel mehr Aufwand beschaffen kann.)
Aber wenn es einen Weg gibt selbiges Problem auch mit Arrays zu lösen, dann möchte ich das ausprobieren.!Lösungsansätze! wären sehr hilfreich. Komplette Codes sind für Übungen weniger effektiv.
Danke für eure Hilfe.
-
Du könntest einen std::reverse_iterator verwenden, der die Richtung eines beliebigen (mindestens Bidi, aber hier hast du sowieso RA) Iterators umdreht. Dann kannst du std::equal auch wieder verwenden

-
Wenn mich grad nicht alles täuscht, sollte
std::equal(word.begin(), word.begin() + word.size() / 2, word.rbegin())ausreichen; sonst prüft man im Erfolgsfall quasi doppelt.
Cruxi schrieb:
!Lösungsansätze! wären sehr hilfreich. Komplette Codes sind für Übungen weniger effektiv.
Versuch doch als Übung mal, das rekursiv umzusetzen. Eine Zeichenfolge ist ein Palindrom, wenn das erste und letzte Zeichen übereinstimmen und der Teil dazwischen ein Palindrom ist.
-
seldon schrieb:
Wenn mich grad nicht alles täuscht, sollte
std::equal(word.begin(), word.begin() + word.size() / 2, word.rbegin())ausreichen; sonst prüft man im Erfolgsfall quasi doppelt.
Ist natürlich richtig, an sowas hab ich gar nicht gedacht, als ich mich bemüht habe, möglichst C++-ischen Code zu schreiben

-
Ich habe mich noch mal mit der Aufgabe beschäfitigt.
Mir ist die Idee gekommen, dass man hier auch Pointer zur Hilfe nehmen kann.-Zunächst wird ein String eingelesen.
-Dieser wird im Array (arr) gespeichert.-Mit Hilfe eines Pointers vergleiche ich dann, ob:
-> das 1. und letzte Element des Wortes gleich sind
-> das 2. und vorletzte Element gleich sind-Sind die Bedingungen erfüllt, liegt ein Palindrom vor. Andernfalls nicht.
#include <iostream> #include <conio.h> #include <string> using namespace std; void main() { char arr[30]; int i, n; char *p = arr; cout << "Deine Eingabe: "; cin.getline(arr, 30); if (arr[0] == *(p+strlen(arr)-1) && arr[1] == *(p+strlen(arr)-2) ) { cout << "\n" << arr << " ist ein Palindrom!" << endl; } else { cout << "\n" << arr << " ist KEIN Palindrom." << endl; } getch(); }Für mich ist die Aufgabe gelöst.
Ich danke allen, die hier Tipps und Vorschläge gepostet haben!
PS: Ich weiß, dass mein Code umständlicher ist. Ziel war es aber anhand des Wissens, dass mir das Buch bisher lieferte eine Lösung zu finden.
MfG
Cruxi
-
Deine Prüfung ist aber falsch, denn du musst alle Buchstaben vergleichen, bis du bei der Hälfte bist, wie seldon erwähnt hat. Dazu benötigst du eine Schleife.
void main() ist ebenfalls falsch, es muss int main() heißen. Und getch() ist auch nicht gerade toll, nimm lieber std::cin.get();
-
Du hast Recht.
Danke für den Hinweis. Ich werde versuchen eine Lösung zu finden.
Ohne Reverse-Iteratoren scheint's ziemlich kompliziert zu sein.
-
Cruxi schrieb:
Du hast Recht.
Danke für den Hinweis. Ich werde versuchen eine Lösung zu finden.
Ohne Reverse-Iteratoren scheint's ziemlich kompliziert zu sein.Lass dich dafür mal von meinem Code inspirieren. Das gibt dir praktisch alles vor, was du wissen musst, da der Algorithmus auf Strings wie auf Arrays funktioniert.
Außerdem würde ich ganz dringend das strlen vor die Schleife ziehen, denn strlen ist, im Gegensatz zu string::size(), eine sehr teure Funktion und die Länge ändert sich hier nicht.
-
Für mich ist die Aufgabe gelöst.Für mich nicht.
Ich empfehle bei allen einfachen algorithmischen Problemen, daß man es mit den Fingern plant. Außer, man ist schon so weit, daß man es im Kopf kann.
Hier heißt das, daß man sich 20 Bit besorgt und trinkt. Es entstehen 20 Kronkorken. Die beschriftet man auf der weichen Innenseite mittels eines Kugelschreibers mit Buchstaben. Eine Auswahl davon legt man in einer Reihe vor sich als zu prüfenden String.
Wie prüft man diesen String? Wie prüft man ihn als Mensch? Wie prüft man ihn als Mensch, wenn man sich vorstellt, daß man es mit einem so großen String zu tun hat, daß man ihn nicht direkt überschauen kann. Kurzum, wenn man so blöd ist, wie ein Computer?
Man legt den linken Zeigefinder vor den ersten Buchstaben und den rechten Zeigefinger vor den letzten Buchstaben.
Schleife solange die Zeigefeiner nicht zusammen sind,
- schaut man, ob die beiden gezeigten Buchstaben gleich sind.
- Wenn nein, war es kein Palindrom.
- Wenn ja, rückt man die Finger um eine Position zusammen und macht mit der Schleife weiter.
Wenn die Schleife aughört, weil die Zeigefinger sich berühren, war es ein Palindrom.Das führt zu zum Beispiel folgendem Code (das meiste geklaut von SeppJ):
bool ist_palindrom(const string &wort) { int links=0; int rechts=wort.size()-1; while(links<rechts) { if(wort[links]!=wort[rechts]) return false; ++links; --rechts; } return true; }Oft entstehen damit saugeile Algorithmen. Welche, die offensichtlich endschnell und sehr einfach sind. Bei einfacheren Problemen nehme ich manchmal die Zifferntasten von ^ bis 9 und stelle sie mir als Array vor, lege die Finger drunter, und operiere im Geiste rum.
Und dann klappt es bald und ich freue ich mich wie ein Schneekönig.
-
314159265358979 schrieb:
Ist natürlich richtig, an sowas hab ich gar nicht gedacht, als ich mich bemüht habe, möglichst C++-ischen Code zu schreiben

Wie ein Reh vor dem Scheinwerfer.

Man muß stets die Implemetierungssprache im Auge behalten, damit es super wird. Aber superer als super muß es nicht werden.
-
Um mal den Trick von volkard zu klauen:
#include <iostream> #include <algorithm> #include <iterator> #include <cstring> int main() { const int n = 42; char str[n]; typedef std::reverse_iterator<const char*> cr_iter; while(std::cin.getline(str, n)) { const int length = std::strlen(str); std::cout << str << " ist " << std::equal(str, str + length, cr_iter(str + length)) + "kein Palindrom.\n"; } }
-
314159265358979 schrieb:
Um mal den Trick von volkard zu klauen:
std::cout << str << " ist " << std::equal(str, str + length, cr_iter(str + length)) + "kein Palindrom.\n";Was war daran besser als das schon gesehene
std::cout << word << " ist " << std::equal(word.begin(), word.end(), word.rbegin()) + "kein Palindrom.\n";?
Mir fällt nur eine weitere Definition cr_iter auf, daß ich, um den Code zu verstehen, an mehr Ecken zugleich lesen muß. Und daß die Zeilen zufällig genau gleich viele Zeichen haben.
-
Er wollte es doch mit einem Array haben. Ich dachte mir, mit der Definition kann er es besser lesen. Ich hätte das typedef ansonsten auch weggelassen.
