Programm zur Permutation mit Thesaurus abgleich

PapaPunk

Grünschnabel
Hallo zusammen,

habe eine Frage und hoffe das ihr mir helfen könnt...

Ich will mir ein Programm erstellen das mir über ein Kommandozeilenparameter ein Wort oder beliebige Buchstaben über eingabe einliest, dann Permutiert, dann mit einem in einer Textdatei angelegtem Thesaurus abgleicht und mir dann nur noch die übereinstimmungen und die Anzahl der übereinstimmungen ausgibt.

Ich bin soweit das er mir das ganze Permutiert allerdings komme ich gerade nicht darauf wie ich ihn dazu kriege das er den Thesaurus der zeilenweise angelegt ist in der .txt einliest und dann abgleicht.

Hoffe ihr könnt mir helfen...

Code dazu ist folgender:
C++:
#include <stdio.h>
#include <stdlib.h>

void tausch(char * p1, char * p2) {
	char c = *p1;
	*p1 = *p2, *p2 = c;
}

void perm(char * text, char * start) {
	int i = -1;
	static int nr;
	if (*start == '\0') //Rekursionsabbruch
		printf("%6d:%s\n" , ++nr , text);
	else
		while (*(start + ++i) != '\0'){
			tausch(start, start + i);
			perm(text, start + 1);
			tausch(start, start +i);
		}
}

int main()
{
	char begin [] ="Geben_Sie_hier_ein_beliebiges_Wort_zur_Permutation_ein!\n";
	printf ("%s", begin);
	char text [30];
	FILE * f ;
	f = fopen ("namen.txt", "w"); // Datei oeffnen
	fgets (text, 30, stdin);
	text [strlen (text) - 1] = 0;
	perm(text, text);
	system("PAUSE");
	return 0;
}
 
Zuletzt bearbeitet von einem Moderator:
Hi und Willkommen bei tutorials.de :)

Kannst du noch ein paar Zeile der Wörterdatei zeigen, wie die aufgebaut ist?


Allgemeine Sachen am Code:

fclose nicht vergessen.

In tausch wäre ein ; statt , nicht verkehrt

Das static int in perm macht die Funktion nur beschränkt weiterverwendbar,
weil threadmäßig problematisch. Parameter (ggf. mit Standardwert für den Grundaufruf) sinnvoller.

Das besagte static int hat keine Initialisierung.

perm könnte irgendwann Mal der Grund für einen Stackoverflow werden.
Iterativ ist es vllt. umständlicher, aber sicherer.

Die ersten zwei main-Zeilen...warum kein normales printf?
Und warum keine Leerzeichen? :confused:

system("PAUSE") ist extern.
Warum nicht selber in ein/zwei Zeilen machen?
Macht das Programm unabhängiger.

Das Abschneiden von txt im main ist ein Problem, wenn kein \n am Schluss ist.
Kann auch passieren. Zuerst mit if prüfen...

Gruß
 
Hallo sheel,

danke dir schonmal für deine Hilfe...

hier erstmal ein Auszug aus der txt...

Code:
Aaliah              
Aaron               
Abby                
Abel                
Abigail             
Abraham             
Ada                 
Adalberoedel        
Adalbert            
Adam                
Addie               
Addison             
Adela               
Adelaide            
Adelbert            
Adele               
Adelgund            
Adelheid            
Adelind             
Adeline             
Adeltrud            
Ado                 
Adolf               
Adolfo              
Adolphe             
Adrian              
Adriana             
Adrianna            
Adrien              
Adrienne            
Adula               
Aegidius            
Afra                
Agatha              
Agathe              
Agilolf             
Agnes               
Agritius            
Agustin             
Aida                
Aidan               
Aiden               
Aileen              
Aimee               
Aine                
Al                  
Alaina              
Alan                
Alana               
Alanna              
Alban               
Alberich            
Albert              
Alberta             
Albertine           
Alberto             
Albin               
Albuin              
Aldemar             
Alec                
Alejandra           
Alejandro           
Alex                
Alexa               
Alexander           
Alexandra           
Alexandre           
Alexandria          
Alexia              
Alexis              
Alexus              
Aleydis             
Alfons              
Alfonso             
Alfred              
Alfredo             
Ali                 
Alice               
Alicia              
Alisha              
Alison              
Alissa              
Aliyah              
Alkuin              
Allan               
Allen               
Allison             
Allowin             
Allyson             
Alma

und so weiter und so fort... so einen thesaurus ergeben...

leider hab ich kaum ahnung von C... ist nicht so ganz meine sprache ;)

ich hänge einfach dabei die Datei zu öffnen... die Worte einzulesen und mit den Permutierten Worten abzugleichen... und mir die treffer anzeigen zu lassen... plus anzahl...

danke schonmal
lg
papapunk
 
Hm.
Ein Thesaurus ist doch etwas, das gleichbedeutende Wörter findet? (muss mal Google befragen :D)
zB. Gewand -> Kleidung...
Wie das mit der Datei gehen soll...?

Willst du buchstabenmäßig ähnliche Wörter finden oder...?
 
Es sollen die exakten übereinstimmungen gefunden werden... sprich ich gebe "das" ein... dann soll er als permutation folgendes ergebnis haben

asd
ads
sad
sda
dsa
das

und soll das dann mit der txt abgleichen... die beinhaltet beispielsweise...

der
die
das
ADS

als ergebnis gibt er mir dann aus:

das
ADS

Anzahl: 2
 
Hallo,

schau mal hier:

PermutExample.cpp
C++:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
 
using namespace std;
 
string readWord(int argc, char* argv[]){
    string word; 
    if(argc == 2){ //extract from arguments
        word += argv[1];
    }else{ //read from console
        cout << "Word: ";
        cin >> word;
    }
    return word;
}
 
vector<string> generatePermutations(string word){
    sort(word.begin(),word.end());
    vector<string> permuts;
    do{
        permuts.push_back(string(word));
    } while(next_permutation(word.begin(), word.end()));
    return permuts;
}
 
void printPermutations(vector<string>& permutations){
    cout << "Permutations: " << permutations.size() << endl;
    for(int i = 0; i < permutations.size(); i++){
        cout << "Permutation (" << i << ") " << permutations[i] << endl;    
    }
}
 
void matchAgainstThesaurus(const string& thesaurusPath, vector<string> &permutations){
    ifstream thesaurus(thesaurusPath.c_str());
    if(thesaurus.is_open())
    {
        int numberOfMatches = 0;
        while(thesaurus.good()){
            string currentLine;
            getline(thesaurus, currentLine);
            if(find(permutations.begin(), permutations.end(), currentLine) != permutations.end()){
                numberOfMatches++;
                cout << "Found Match: " <<  currentLine << endl;
            }
        }
        cout << "Number of matches: " << numberOfMatches << endl;
        thesaurus.close();
    }
}
 
int main(int argc, char* argv[])
{
    string word = readWord(argc,argv);
 
    cout << "Got Word: " << word << endl;
 
    vector<string> permutations = generatePermutations(word);
 
    printPermutations(permutations);
 
    matchAgainstThesaurus("c:/temp/thesaurus.txt",permutations);
 
    return 0;
}

Ausgabe mit Eingabe von Stdin:
Code:
C:\Users\Tom\Documents\Visual Studio 2010\Projects\PermutExample\Debug>PermutExample.exe
Word: 123
Got Word: 123
Permutations: 6
Permutation (0) 123
Permutation (1) 132
Permutation (2) 213
Permutation (3) 231
Permutation (4) 312
Permutation (5) 321
Number of matches: 0

Ausgabe mit Eingabe über Parameter mit thesaurus:
Code:
C:\Users\Tom\Documents\Visual Studio 2010\Projects\PermutExample\Debug>type c:\temp\thesaurus.txt
BCA
ZYX
CBA

C:\Users\Tom\Documents\Visual Studio 2010\Projects\PermutExample\Debug>PermutExample.exe ABC
Got Word: ABC
Permutations: 6
Permutation (0) ABC
Permutation (1) ACB
Permutation (2) BAC
Permutation (3) BCA
Permutation (4) CAB
Permutation (5) CBA
Found Match: BCA
Found Match: CBA
Number of matches: 2

//Edit huch war mal wieder zu langsam...
//Edit2 ifstream thesaurus Deklaration gefixed

Gruß Tom
 
Hallo Tom,

danke dir auf jedenfall... sieht auch sehr gut aus ;) allerdings gibt mir der Compiler nen fehler aus... ich vermute mal das das CPP bei dir für C++ steht... ich bräuchte allerdings das ganze für C... gibt es da ne möglichkeit das ganze einfach umzusetzten?

LG
PapaPunk

@Edit: Habs gerade ma unter C++ getestet da gibt er mir ebenfalls einen Fehler in der Zeile 37 aus:

ifstream thesaurus(thesaurusPath);

Begründung:

C:\Neuer Ordner (2)\genau\main.cpp In function `void matchAgainsThesaurus(const std::string&, std::vector<std::string, std::allocator<std::string> >&)':
37 C:\Neuer Ordner (2)\genau\main.cpp no matching function for call to `std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)'
 
Zuletzt bearbeitet:
Hallo,

... hmmm
ach ja ich habs mit Visual C++ 2010 kompiliert, scheinbar sind dort noch ein paar weitere automatische Konvertierungen hinterlegt...

Ändere doch mal den Code in Zeile 37 von:
C++:
    ifstream thesaurus(thesaurusPath);
auf:
C++:
    ifstream thesaurus(thesaurusPath.c_str());
damit kompiliert das Beispiel bei mir auch mit Devcpp und mingw32 3.4.2.
Die anderen Fehlermeldungen sind Folgefehler.

Gruß Tom
 
Hallo Tom,

habs jetz probiert mit C++ hauts hin...

allerdings meldet er mir wenn ich das unter C compilieren will immer noch:

1 C:\Neuer Ordner (2)\gggg\main.c iostream: No such file or directory.

.... und so weiter für alle includes... daraus ergeben sich dann weitere folgefehler... hoffe mir kann jemand helfen...

lg
PapaPunk
 
Hallo,

hier mal noch eine "einfache" Version in C (die kompiliert unter Visual Studio 2010 C++
und DevCPP Mingw 3.4.2). Diese Version sollte der obigen CPP Version entsprechen.

C:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define MAX_WORD_LEN 32
 
char word[MAX_WORD_LEN];
 
typedef struct ListNode{
    char value[MAX_WORD_LEN];
    struct ListNode* next;
} ListNode;
 
ListNode* headListNode;
ListNode* tailListNode;

int listSize = 0;
 
void readWord(int argc, char* argv[]){
    //TODO check string bounds MAX_WORD_LEN
    if(argc == 2){ //extract from arguments
        strcpy(word,argv[1]);
    }else{ //read from console
        printf("Word: ");
        scanf("%s",&word);
    }
}
 
void permut(char* v, const int start, const int n){
    //TODO prevent generation of duplicate entries
    if (start == n-1){
        ListNode* node;
        node = (ListNode*)malloc(sizeof(ListNode));
        strcpy(node->value, v); 
        
        if(!headListNode){
            headListNode = tailListNode = node;   
        }else{
            tailListNode->next = node;
            tailListNode = node;
        }
        
        listSize++;
    } else {
        int i;
        for (i = start; i <n; i++) {
            char tmp = v[i];
            v[i]=v[start];
            v[start]=tmp;
            permut(v, start+1, n);
            v[start]=v[i];
            v[i] = tmp;
        }
    }
}
 
void generatePermutations(){
    permut(word, 0, strlen(word));
}
 
void printPermutations(){
    ListNode* cur = headListNode;
    int i =0;
    printf("Permutations: %i\n", listSize); 
    while(cur){
        printf("Permutation (%i) %s\n",i++, cur->value);
        cur = cur->next;
    }
}
 
void matchAgainstThesaurus(const char* thesaurusPath){
    FILE* thesaurus = fopen(thesaurusPath,"r");
 
    int numberOfMatches = 0;
    ListNode* cur;
    char currentLine[MAX_WORD_LEN];
 
    //TODO skip lines with only whitespaces/control characters
    while(!feof(thesaurus)) {
        fscanf(thesaurus, "%s", currentLine);
 
        cur = headListNode;
        while(cur){
            if(strcmp(currentLine,cur->value) == 0){
                numberOfMatches++;
                printf("Found Match: %s\n",currentLine); 
            }
            cur = cur->next;
        }
    }
 
    printf("Number of matches: %i\n",numberOfMatches); 
 
    if(thesaurus){
        fclose(thesaurus);
    }
}
 
void cleanup(){
    ListNode* cur = headListNode;
    ListNode* next = NULL;
    while(cur){
        next = cur->next;
        free(cur);
        cur = next;
    }
}
 
int main(int argc, char* argv[]){
    readWord(argc, argv);
    printf("Got word: %s\n",word);
 
    generatePermutations();
    printPermutations();
 
    matchAgainstThesaurus("c:/temp/thesaurus.txt");
 
    cleanup();
 
    return 0;
}

Ausgabe:
Code:
C:\development\cpp\devcpp\Examples\PEC>PermutExampleC.exe ABC
Got word: ABC
Permutations: 6
Permutation (0) ABC
Permutation (1) ACB
Permutation (2) BAC
Permutation (3) BCA
Permutation (4) CBA
Permutation (5) CAB
Found Match: ABC
Found Match: ABC
Number of matches: 2

D:\training\cpp\Dev-Cpp\projects\permut_c>type c:\temp\thesaurus.txt
CAB
ABC

Gruß Tom
 
Zurück