Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Phil239

Frischling

  • »Phil239« ist der Autor dieses Themas

Beiträge: 79

Beruf: Student

  • Private Nachricht senden

1

08.09.2014, 18:35

Methoden-/Funktionscode verstecken

Hallo,

folgender Hintergrund: ich schreibe gerade ein Programm, das durch einen Text iteriert und die Wörter ausgeben soll, die nicht in einer (zuvor erstellten) Datenbank vorhanden sind. Dazu muss ich von jedem Wort erst einmal versuchen, die Grundform zu bilden. Es gibt eine Enumeration, die alle Wortarten enthält. Hier mal eine verkürzte Variante:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
class WordClass
{
public:
    // ...
    enum Type : unsigned char
    {
        NOUN,
        VERB,
        ADJECTIVE
    }
    // ...
}


Nun gibt's noch eine andere Klasse namens WordIdentifier, die unter anderem die Methode bool identify(const std::string&, WordClass::Type) const; enthält.
Ich übergebe also einen String, der das unveränderte Wort aus dem Text erhält, und den Typ des Wortes, mithilfe dessen die Grundform gebildet werden soll.
Rückgabewert ist dann, ob das Wort in der Datenbank ist oder nicht.
Jetzt frage ich mich, wie ich diese Methode implementieren soll.

Möglichkeit 1: Sie besteht aus einer riesigen (dadurch unübersichtlichen) switch-Anweisung, je nach WordClass::Type.

Möglichkeit 2: Sie ruft je nach WordClass::Type eine (am besten private) Methode auf, wodurch ich aber in der Header-Datei ziemlich viele Zeilen ähnlichen Aussehens (also z.B. identifyNoun(...), identifyVerb(...), ...) hätte. Finde ich genauso unschön wie Möglichkeit 1.

Möglichkeit 3: Mithilfe von Templates, ungefähr so:

C-/C++-Quelltext

1
2
template<WordClass::Type>
bool identify(const std::string&) const;

Dann könnte ich jeden WordClass::Type spezialisieren. Allerdings werden die WordClass::Type's erst zur Laufzeit bestimmt, weshalb ich nicht sowas wie

C-/C++-Quelltext

1
2
3
// ...
return identify<getWordType()>(str);
// ...

schreiben kann. Das müsste dann wohl wieder eine switch-Anweisung à la

C-/C++-Quelltext

1
2
3
4
5
6
switch(getWordType())
{
    case NOUN: return identify<NOUN>(str);
    case VERB: return identify<VERB>(str);
    // ...
}

werden.
Ist zwar schon besser (m.M.n.), aber gefällt mir immer noch nicht.

Meine Frage: welche Möglichkeit würdet ihr bevorzugen, bzw. (noch besser) kennt ihr elegantere Möglichkeiten, so etwas zu implementieren?

Gruß,
Phi239
Der Computer ist die logische Weiterentwicklung des Menschen: Intelligenz ohne Moral.

2

08.09.2014, 18:56

Du kannst in der DB doch einfach alle flektierten Formen eines Wotes speichern. Den Infinitiv eines Wortes zu bilden ist nicht so ganz einfach.

Phil239

Frischling

  • »Phil239« ist der Autor dieses Themas

Beiträge: 79

Beruf: Student

  • Private Nachricht senden

3

08.09.2014, 19:07

Hhmm. Wäre 'ne Alternative. Allerdings würde die Größe der Datenbank wahrscheinlich extrem in die Höhe schießen.
Beispiel: Für 1 Verb müsste ich allein für den Indikativ Präsens aktiv 6 Formen speichern, also 1./2./3. Person Sg./Pl.
Der Computer ist die logische Weiterentwicklung des Menschen: Intelligenz ohne Moral.

4

08.09.2014, 19:37

Wie gesagt, den Infinitiv herauszufinden ist sicher kompliziert. Naja, pro Wort ca. 10 Bytes, mal 32 Formen(ka wie viel) mal 200 Wörter (für den Anfang), da kommen wir auf gerade mal 64 KB. Selbst bei mehr Wörtern, Unicode und jedem Pipapo sollte das nicht allzu viel Speicher verbrauchen.

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

5

08.09.2014, 19:41

Ich glaube du willst virtuelle Funktionen benutzen ..
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Phil239

Frischling

  • »Phil239« ist der Autor dieses Themas

Beiträge: 79

Beruf: Student

  • Private Nachricht senden

6

08.09.2014, 21:20

Danke schonmal zu den Antworten.

@Roflo
Hast wahrscheinlich Recht. Die Wörter haben zwar noch ein paar mehr Informationen, aber selbst wenn man das so nochmal durchrechnet, braucht es nicht allzu viel Speicher.
Das mit dem Infinitiv rausfinden wird, wie du schon meintest, bestimmt schwierig werden; allerdings gibt es ja noch andere Wortarten (z. B. Artikel), deren Grundform einfacher zu bestimmen sind. Da kann ich mir die Verben bis zum Schluss aufheben 8)

@Legend
Diesen Gedanken hatte ich auch schon, allerdings ist die Klasse WordIdentifier ein Singleton. Die würde ich nur ungern vererben. Natürlich könnte die identify-Methode auch als rein virtuell in der WordClass sein, von der die einzelnen Typen erben, die die Methode dann implementieren. Das war aber an anderer Stelle in meinem Programm nicht so sinnvoll.
Der Computer ist die logische Weiterentwicklung des Menschen: Intelligenz ohne Moral.

buggypixels

Treue Seele

Beiträge: 125

Wohnort: Meerbusch

Beruf: Programmierer

  • Private Nachricht senden

7

08.09.2014, 22:10

Ein klassisches Beispiel wie durch C++ ein doch recht einfaches Problem sehr komplex wird. In C wäre das sicherlich einfacher zu lösen und auch eleganter.
Aber es bei Deiner Frage ja nicht, ob das so gut ist sondern wie es geht.
Also ein Template bietet sich dann an. Die eigentliche Logik wäre dann aber eher in einem Trait. Dieses Trait wäre dann die Spezialisierung.
Wird in std und boost ständig als Type Traits auch so verwendet. Am besten mal googlen. Ist etwas kompliziert am Anfang zu verstehen.

Phil239

Frischling

  • »Phil239« ist der Autor dieses Themas

Beiträge: 79

Beruf: Student

  • Private Nachricht senden

8

08.09.2014, 23:12

Wenn ich das richtig verstanden habe, ist ein Trait also eine komplett spezialisierte Template-Klasse, richtig (vgl. hier)?
Das wäre ja dann die von mir beschriebene Möglichkeit 3.
Stellt sich nur noch die Frage, ob ich sozusagen direkt (ohne switch-case) die Methode zur Laufzeit spezialisieren kann.
Also eben etwas wie identify<getWordType()>(str), was ja nicht funktioniert.
Der Computer ist die logische Weiterentwicklung des Menschen: Intelligenz ohne Moral.

9

09.09.2014, 00:27

Ich hab jetzt den Thread nicht 100 Prozentig gelesen, aber schau dir mal decltype an. Das ist ein mit C++ 11 eingeführtes Keyword mit dem zumindest der kleine Codefetzen aus deinem letzten Post möglich wäre.

mfg

Werbeanzeige