Forum: PC-Programmierung Aus X Buchstaben Y Wörter bilden - Programmieren


von jonas (Gast)


Lesenswert?

Ich habe eine Datei mit sagen wir 1000 Wörtern und eine zweite Datei mit 
100 Buchstaben. Ich möchte nun aus den 100 Buchstaben prüfen welche 
Wörter man aus der ersten Datei abbilden kann. Z.b. mit den mir 100 zur 
Verfügung stehenden Wörtern kann ich aus den 1000 Wörtern 7 bilden.

Jetzt ist die Frage wie hoch der Aufwand ist bevor ich das programmiere, 
denn wenn es fast schon Richtung bruteforce geht dann kann man es 
vergessen und würde zu lange dauern. Daher die Frage ist das einfach und 
schnell lösbar und die zweite Frage wie würde man das machen vielleicht 
anhand vom Pseudocode. Ich würde C, Python oder C++ verwenden.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

sozusagen ein Scrabblespiel
Hundnase (Loriot)

Darf man die Wörter und Buchstaben alphabetisch vorsortieren?
Vielleicht sogar die Wörter selbst, also "Wörter" wird zu "eörrtw"

: Bearbeitet durch User
von jonas (Gast)


Lesenswert?

Ja es darf alles vorvearbeitet werden wie man es möchte. Am ende soll 
nur aus den möglichen Buchstaben alle möglichen Wörter gefunden werden.

Also bei deinem Beispiel muss nicht das Wort "eörrtw" gefunden werden, 
sondern "Wörter". "Wörter" ist einer dieser 1000 Wörter die in der Datei 
stehen.

von Rainer S. (enevile) Benutzerseite


Lesenswert?

Man braucht einen Wortschatz und mittels einer Abfrage des möglichs 
kurzen Wortes von vorhandenen Buchstaben.

Hier eine Python Bibliothek eines Wortschatzes:
https://github.com/lehmannro/libleipzig-python

Für C/C++ habe ich auf die Schnelle nichts gefunden.

von Willi (Gast)


Lesenswert?

Nur damit ich es richtig verstehe:
Du suchst aus der Wörter-Datei genau die Wörter,
die ausschließlich Buchstaben aus der Buchstaben-Datei enthalten ?
Willst also alle Wörter "streichen", die mindestens einen Buchstaben 
haben,
der nicht in der Buchstaben Datei enthalten ist ?

von Rolf M. (rmagnus)


Lesenswert?

jonas schrieb:
> Ich habe eine Datei mit sagen wir 1000 Wörtern und eine zweite Datei mit
> 100 Buchstaben. Ich möchte nun aus den 100 Buchstaben prüfen welche
> Wörter man aus der ersten Datei abbilden kann. Z.b. mit den mir 100 zur
> Verfügung stehenden Wörtern kann ich aus den 1000 Wörtern 7 bilden.

Geht es dir darum, alle Kombinationen dieser Wörter zu finden oder nur 
die, mit der die meisten Wörter gebildet werden? Oder die, die möglichst 
viele Buchstaben aus dem zweiten Datei nutzt?

Willi schrieb:
> Nur damit ich es richtig verstehe:
> Du suchst aus der Wörter-Datei genau die Wörter,
> die ausschließlich Buchstaben aus der Buchstaben-Datei enthalten ?

Soweit ich verstehe, darf jeder nur einmal vorkommen.

> Willst also alle Wörter "streichen", die mindestens einen Buchstaben
> haben, der nicht in der Buchstaben Datei enthalten ist ?

Das wäre zwar nötig, würde aber nicht reichen.

von Dussel (Gast)


Lesenswert?

Ganz spontan würde ich die Buchstaben in der zweiten Datei zählen. Also 
3 mal A, 1 mal B, 0 mal C, 4 mal D…
Dann würde ich für die Wörter zählen, wie oft welcher Buchstabe 
vorkommt. "Buchstabe" enthält zum Beispiel 1A,2B,1C,1E,1H,1S,1T,1U
Für jeden enthaltenen Buchstaben würde ich die Buchstabentabelle aus der 
Datei der Reihe nach durchsuchen, ob die notwendige Anzahl an Buchstaben 
vorhanden ist.
Buchstaben in der Datei zählen geht in O(Buchstaben), die Buchstaben pro 
Wort zählen geht in O(Wortlänge) und das muss O(Wörter) mal gemacht 
werden. Beim Vergleich bin ich nicht ganz sicher, sollte aber auch nicht 
zu lange dauern.

Oder meinst du, man soll aus den gegebenen Buchstaben 'Sätze' bilden mit 
vorgegebenen Wörtern?

von Dussel (Gast)


Lesenswert?

Dussel schrieb:
> die Buchstaben pro
> Wort zählen geht in O(Wortlänge)
Stimmt gar nicht. Das müsste eher sowas wie O(Wortlänge*Buchstaben im 
Alphabet) sein.

von xyz (Gast)


Lesenswert?

wenn die Buchstaben sortiert sind, dann ist es überhaupt kein Problem. 
Aber natürlich muss man alle Buchstaben einzeln prüfen.

Die Frage ist nur wie man das tut. Wenn man z.B. nur die Buchstaben 
a,A,b,B,c,C,...x,X,y,Y,z,Z nimmt, dann ist die Aufgabe einfach:
1
   const char* words[] = { "ONE",  "two", "three", "four",
2
                           "FiVe", "six", "seven", "eight",
3
                           "nine", "no1", "2no",   "n30" };
4
5
   const size_t num_words =
6
      sizeof (words) / sizeof (*words);
7
8
   for (size_t i = 0; i < num_words; i++) {
9
      bool is_valid = true;
10
11
      for (size_t j = 0; j < strlen (words[i]); j++) {
12
         if (toupper (words[i][j]) < 'A' ||
13
             toupper (words[i][j]) > 'Z') {
14
            is_valid = false;
15
            break;
16
         }
17
      }
18
19
      if (is_valid) {
20
         printf ("yes:\t%s\n", words[i]);
21
      }
22
      else {
23
         printf ("no:\t%s\n", words[i]);
24
      }
25
   }

von jonas (Gast)


Lesenswert?

Willi schrieb:
> Nur damit ich es richtig verstehe:
> Du suchst aus der Wörter-Datei genau die Wörter,
> die ausschließlich Buchstaben aus der Buchstaben-Datei enthalten ?
> Willst also alle Wörter "streichen", die mindestens einen Buchstaben
> haben,
> der nicht in der Buchstaben Datei enthalten ist

Genau so ist es! Willi hat es so verstanden wie ich es meine

 Es sollen nur die Wörter übrig bleiben, die Buchstaben aus der 
Buchstaben Datei/Array enthalten.
Wörter=[Auto, klein, Baum]; Buchstaben=[a t o k u z] würde bedeuten dass 
nur das Wort Auto übrig bleibt und ausgegeben wird.

 Ich habs jetzt mal ganz pragmatisch zwei for schleifen gedacht, eine 
für den Buchstabenden die andere für die Position im Wort.

von Rolf M. (rmagnus)


Lesenswert?

xyz schrieb:
> Die Frage ist nur wie man das tut. Wenn man z.B. nur die Buchstaben
> a,A,b,B,c,C,...x,X,y,Y,z,Z nimmt, dann ist die Aufgabe einfach:

Hier sollen aber alle 100 Buchstaben der zweiten Datei verwendet werden. 
Also wenn da 10 'A's vorkommen, dürfen die auch alle verwendet werden. 
So interpretiere ich jedenfalls die Aufgabe.

von Georg (Gast)


Lesenswert?

Wie intelligent soll denn der Algorithmus sein? Soll z.B. ein Wort 
wieder gestrichen werden, wenn sich herausstellt, dass man mit den 
verbrauchten Buchstaben auch zwei andere Wörter bilden könnte? Anders 
gesagt, muss man das Maximum an möglichen Wörtern finden?

In Deutsch mit den nahezu beliebig zusammengesetzten Wörtern wird 
dadurch der Aufwand gigantisch. Bzw. die Wortliste dürfte garkeine 
zusammengesetzten Wörter enthalten, was eine sehr massive Einschränkung 
wäre und ausserdem wahrscheinlich von Hand sichergestellt werden müsste. 
Man kann ja nicht einmal eindeutig sagen wie ein Wort zusammengesetzt 
ist, z.B. Urinstinkt oder die berühmten Blumentopferde.

Georg

von Dussel (Gast)


Lesenswert?

Georg schrieb:
> Anders
> gesagt, muss man das Maximum an möglichen Wörtern finden?
>
> In Deutsch mit den nahezu beliebig zusammengesetzten Wörtern wird
> dadurch der Aufwand gigantisch.
Das würde ich als Variante des Rucksackproblems ansehen und damit wäre 
es NP-vollständig.

von Nano (Gast)


Lesenswert?

xyz schrieb:
> wenn die Buchstaben sortiert sind, dann ist es überhaupt kein Problem.
> Aber natürlich muss man alle Buchstaben einzeln prüfen.
>
> Die Frage ist nur wie man das tut. Wenn man z.B. nur die Buchstaben
> a,A,b,B,c,C,...x,X,y,Y,z,Z nimmt, dann ist die Aufgabe einfach:
>
>
1
>    const char* words[] = { "ONE",  "two", "three", "four",
2
>                            "FiVe", "six", "seven", "eight",
3
>                            "nine", "no1", "2no",   "n30" };
4
> 
5
>    const size_t num_words =
6
>       sizeof (words) / sizeof (*words);
7
> 
8
>    for (size_t i = 0; i < num_words; i++) {
9
>       bool is_valid = true;
10
> 
11
>       for (size_t j = 0; j < strlen (words[i]); j++) {
12
>          if (toupper (words[i][j]) < 'A' ||
13
>              toupper (words[i][j]) > 'Z') {
14
>             is_valid = false;
15
>             break;
16
>          }
17
>       }
18
> 
19
>       if (is_valid) {
20
>          printf ("yes:\t%s\n", words[i]);
21
>       }
22
>       else {
23
>          printf ("no:\t%s\n", words[i]);
24
>       }
25
>    }
26
> 
27
> 
28
>

Da ist ein Fehler drin und muss korrekt lauten:
1
   const char* words[] = { "ONE",  "two", "three", "four",
2
3
                           "FiVe", "six", "seven", "eight",
4
5
                           "niner", "no1", "2no",   "n30" };
6
7
   const size_t num_words =
8
9
      sizeof (words) / sizeof (*words);
10
11
   for (size_t i = 0; i < num_words; i++) {
12
13
      bool is_valid = true;
14
15
      for (size_t j = 0; j < strlen (words[i]); j++) {
16
17
         if (toupper (words[i][j]) < 'A' ||
18
19
             toupper (words[i][j]) > 'Z') {
20
21
            is_valid = false;
22
23
            break;
24
25
         }
26
27
      }
28
29
      if (is_valid) {
30
31
         printf ("yes:\t%s\n", words[i]);
32
33
      }
34
35
      else {
36
37
         printf ("no:\t%s\n", words[i]);
38
39
      }
40
41
   }

von Operator S. (smkr)


Lesenswert?

Georg schrieb:
> Bzw. die Wortliste dürfte garkeine
> zusammengesetzten Wörter enthalten

Warum nicht? Die Wortliste ist ja schon vorgegeben.

Georg schrieb:
> Soll z.B. ein Wort
> wieder gestrichen werden, wenn sich herausstellt, dass man mit den
> verbrauchten Buchstaben auch zwei andere Wörter bilden könnte? Anders
> gesagt, muss man das Maximum an möglichen Wörtern finden?

Diese Fragen sind schon wichtiger für eine mögliche Lösungsfindung

von jonas (Gast)


Lesenswert?

Rolf M. schrieb:
> Hier sollen aber alle 100 Buchstaben der zweiten Datei verwendet werden.
> Also wenn da 10 'A's vorkommen, dürfen die auch alle verwendet werden.
> So interpretiere ich jedenfalls die Aufgabe
Ich sehe ich hatte einen Fehler. Es sind maximal 26 Buchstaben in der 
Datei. Meistens aber ein Bruchteil vom deutschen Alphabet. Also zum 
Beispiel nur die Buchstaben [a b c u f o t]. Groß- und Kleinschreibung 
soll nicht unterschieden.

Georg schrieb:
> Wie intelligent soll denn der Algorithmus sein? Soll z.B. ein Wort
> wieder gestrichen werden, wenn sich herausstellt, dass man mit den
> verbrauchten Buchstaben auch zwei andere Wörter bilden könnte? Anders
> gesagt, muss man das Maximum an möglichen Wörtern finden?

Genau die Buchstaben "verschwinden" nicht wenn sie für ein Wort schon 
gebraucht wurden. Also soll die max Anzahl an möglichen Wörtern (die in 
einer Datei stehen) aus diesen Buchstaben gebildet werden.

von Georg (Gast)


Lesenswert?

jonas schrieb:
> Genau die Buchstaben "verschwinden" nicht wenn sie für ein Wort schon
> gebraucht wurden

Das macht die Aufgabe sinnlos, bzw. es genügt wenn man alle 26 oder 29 
Buchstaben nimmt, keine 100.

Oder kommt jetzt wieder ein Salamischeibchen?

Georg

von Rolf M. (rmagnus)


Lesenswert?

jonas schrieb:
> Rolf M. schrieb:
>> Hier sollen aber alle 100 Buchstaben der zweiten Datei verwendet werden.
>> Also wenn da 10 'A's vorkommen, dürfen die auch alle verwendet werden.
>> So interpretiere ich jedenfalls die Aufgabe
> Ich sehe ich hatte einen Fehler. Es sind maximal 26 Buchstaben in der
> Datei.

Das heißt, jeder Buchstabe des Alphabets kommt darin auch nur maximal 
einmal vor?

> Genau die Buchstaben "verschwinden" nicht wenn sie für ein Wort schon
> gebraucht wurden.

Also darf ich jeden der Buchstaben beliebig oft einsetzen?

Sprich: Wenn in der zweiten Datei 26 Buchstaben stehen, wäre das immer 
der Trivialfall, weil die erste Datei dann immer komplett damit gebildet 
werden kann, sofern sie nur aus Buchstaben und Leerzeichen besteht?

> Also soll die max Anzahl an möglichen Wörtern (die in
> einer Datei stehen) aus diesen Buchstaben gebildet werden.

Georg schrieb:
> Das macht die Aufgabe sinnlos, bzw. es genügt wenn man alle 26 oder 29
> Buchstaben nimmt, keine 100.

Hat er ja auch geschrieben:

jonas schrieb:
> Ich sehe ich hatte einen Fehler. Es sind maximal 26 Buchstaben in der
> Datei.

: Bearbeitet durch User
von jonas (Gast)


Lesenswert?

Georg schrieb:
> Das macht die Aufgabe sinnlos, bzw. es genügt wenn man alle 26 oder 29
> Buchstaben nimmt, keine 100.

Habe ich ja über deinem Post geschrieben dass es immer weniger als 26 
Buchstaben sind.

von jonas (Gast)


Lesenswert?

Rolf M. schrieb:
> Das heißt, jeder Buchstabe des Alphabets kommt darin auch nur maximal
> einmal vor?

Genau, jeder Buchstabe kommt auch nur maximal einmal vor. Aber es kann 
sein das die Datei viel weniger Buchstaben hat als das Alphabet. Zm 
Beispiel nur 12 Buchstaben.

Rolf M. schrieb:
> Also darf ich jeden der Buchstaben beliebig oft einsetzen?

So ist es!

Rolf M. schrieb:
> Sprich: Wenn in der zweiten Datei 26 Buchstaben stehen, wäre das immer
> der Trivialfall, weil die erste Datei dann immer komplett damit gebildet
> werden kann, sofern sie nur aus Buchstaben und Leerzeichen besteht?

Jap, wobei das nicht vorkommen wird. Es sind meistens dann nur ein 
Bruchteil der Buchstaben aus dem Alphabet drin.

von Georg (Gast)


Lesenswert?

jonas schrieb:
> Jap, wobei das nicht vorkommen wird. Es sind meistens dann nur ein
> Bruchteil der Buchstaben aus dem Alphabet drin.

Dann ist die Aufgabe aber trivial: man streicht einfach aus Liste 1 alle 
Wörter, die einen Buchstaben enthalten, der in der Liste 2 nicht 
vorkommt, und man ist in einem Durchgang fertig.

Georg

von Dussel (Gast)


Lesenswert?

Dann ist es doch extrem einfach. Man geht jeden Buchstaben jeden Wortes 
durch und sieht nach, ob er in der Tabelle ist. Wenn alle Buchstaben 
eines Wortes in der Tabelle stehen, kann das Wort gebildet werden.
Bei sehr vielen Wörtern könnte man die auch nach dem ersten Buchstaben 
sortieren und alle Wörter rausschmeißen, deren erster Buchstabe nicht in 
der Tabelle steht. Dann das Gleiche mit jedem weiteren Buchstaben.

Und wenn wir hier von 26 Buchstaben reden, muss man da auch nicht lange 
über Optimierungen nachdenken.

von Rolf M. (rmagnus)


Lesenswert?

Dann sollte es doch recht einfach sein: Du gehst Datei 1 Wort für Wort 
durch und das jeweilige Wort wiederum Buchstabe für Buchstabe. Da 
schaust du nach, ob dieser in der Liste enthalten ist. Wenn nein, 
Abbruch und nächstes Wort. Wenn alle Buchstaben enthalten sind, merkst 
du dir das Wort.
Dazu würde ich mir die Buchstaben in einem Set merken. In Python geht 
das recht kurz: (ein Python-Profi wird's sicherlich noch schöner 
hinbekommen)
1
wörter=["hallo", "welt", "wie", "geht", "es"]
2
buchstaben=set("abcdehlotw")
3
output = list()
4
for wort in wörter:
5
    for buchstabe in wort:
6
        if not buchstabe in buchstaben:
7
            break
8
    else:
9
        output.append(wort)
10
print(output)

: Bearbeitet durch User
von A. S. (rava)


Lesenswert?

hier mal wie bei scrabble unter Berücksichtigung der Buchstabenanzahl
1
from collections import defaultdict 
2
3
words = ['Hund', 'Pfund', 'Schund', 'rund', 'bunt', 'und', 'Lund', 'Nudel', 'Nuddel']
4
letters = 'DNUHPLEX'
5
6
7
words = [word.lower() for word in sorted(words)]
8
letters = letters.lower()
9
10
11
def _count_letters(word):
12
    result = defaultdict(lambda: 0)
13
    for letter in word:
14
        result[letter] += 1
15
    return result
16
17
letters_counted = _count_letters(letters)
18
19
def _in(word_counted, letters_counted):
20
    for word_letter, letter_count in word_counted.items():
21
        if letters_counted[word_letter] < letter_count:
22
            return False
23
    return True
24
25
words_valid = [_in(_count_letters(word), letters_counted) for word in words]
26
27
for valid, word in zip(words_valid, words):
28
    if valid:
29
        print(word)

: Bearbeitet durch User
von 🐧 DPA 🐧 (Gast)


Lesenswert?

1
#!/bin/sh
2
3
if [ $# != 1 ]; then echo "usage: $0 search <wordlist.txt"; exit 1; fi
4
5
sortletters(){ printf "%s" "$1" | sed 's/./\0\x0/g' | sort -z | tr -d '\0'; }
6
7
needle="$(sortletters "$1")"
8
while read word
9
  do if [ "$needle" = "$(sortletters "$word")" ]; then echo "$word"; fi
10
done

von A. S. (Gast)


Lesenswert?

M.E. hat der TO Jonas noch keine sinnvolle Definition seines Problems 
geliefert.

Die erste Datei ist klar, Liste von Wörtern.
Großschreibung ignoriert.
Richtig?

Bei der zweiten sind es Mal Buchstaben, Mal Wörter.

Mal sind es 100, Mal darf jeder Buchstabe beliebig oft verwendet werden.

Sinn macht es nur, wenn es Wörter sind, und aus jedem Wort einzeln die 
Buchstaben genommen werden. Und dann prüfen, welche Worte der ersten 
Datei sich damit leben lassen.

von A. S. (Gast)


Lesenswert?

Falls es am Ende egal ist, wie oft ein Buchstabe verwendet wird:

Jedes Wort in eine 32bit-zahl im Array W[1000] umwandeln, wo das erste 
Bit a, das zweite b usw. ist.

Dann die erlaubten Buchstaben ebenso in eine 32bit Zahl T wandeln.

Dann über das Array testen, wo T|W[i]==W[i] ist

Da lohnt sich vermutlich keine Optimierung ohne weitere Infos

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.