Created
October 11, 2013 04:47
-
-
Save zhezheng/6929726 to your computer and use it in GitHub Desktop.
Create a randomized text generator, which creates output based on a source text
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Please put the tao_te_ching.txt under "D:\\tao_te_ching.txt" */ | |
/* By ZHE ZHENG */ | |
#include<fstream> | |
#include<iostream> | |
#include<string> | |
#include<map> | |
#include<ctime> | |
using namespace std; | |
/* Read the txt file line by line */ | |
void read(map<int,string>& m) | |
{ | |
ifstream file("D:\\tao_te_ching.txt"); | |
if(!file) | |
{ | |
cout<<"Can't open it"<<endl; | |
return; | |
} | |
string str; | |
int i = 0; | |
while(getline(file,str)) | |
{ | |
if(str != "" && (str[0] > '9' || str[0] < '0')) //based on the txt file, the condition that it is a sentence | |
{ | |
m[i] = (str); | |
i++; | |
} | |
} | |
} | |
/* find words in per string */ | |
void find(string str,map<int,string>& tmap) | |
{ | |
string temp_str = ""; | |
int index = 0; | |
for(int i = 0;i < (int)str.length();i++) | |
{ | |
if((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || str[i] == '-' || str[i] == 39) //the condition that it's a word | |
{ | |
temp_str = temp_str + str[i]; | |
} | |
else if(str[i] == ',' || str[i] == '.' || str[i] == '!' || str[i] == '?') //treat , . ! ? as a world | |
{ | |
tmap[index++] = (temp_str); | |
temp_str = ""; | |
tmap[index++] = (str[i]); | |
} | |
else | |
{ | |
if(temp_str != "") | |
{ | |
tmap[index++] = (temp_str); | |
} | |
temp_str = ""; | |
} | |
if(i == str.length() - 1 && ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z'))) //the condition that the last position of this line is a letter | |
{ | |
tmap[index] = (temp_str); | |
} | |
} | |
} | |
/*Creat hash class*/ | |
class hash | |
{ | |
private: | |
static const int tablesize = 200; | |
struct node | |
{ | |
string first; | |
string second; | |
string third; | |
node* next; | |
}; | |
node* HashTable[tablesize]; | |
public: | |
hash(); | |
int Hash(string str); | |
void addnode(string first,string second,string third); | |
int countnode(int index); | |
void print(); | |
void printindex(int index); | |
void generating(map<int,string>& m, map<int,string> &tmap, hash& hashy); | |
}; | |
/*HashTable*/ | |
hash::hash() | |
{ | |
for(int i = 0;i < tablesize;i++) | |
{ | |
HashTable[i] = new node; | |
HashTable[i]->first = ""; | |
HashTable[i]->second = ""; | |
HashTable[i]->third = ""; | |
HashTable[i]->next = NULL; | |
} | |
} | |
/* Hash function, return the value of sum of ascii */ | |
int hash::Hash(string str) | |
{ | |
int sum = 0; | |
for(int i = 0; i < (int)str.length(); i++) | |
{ | |
sum += (int)str[i]; | |
} | |
return sum % tablesize; | |
} | |
/*Addnode*/ | |
void hash::addnode(string first,string second,string third) | |
{ | |
int index = Hash(first); | |
if(HashTable[index]->first == "") | |
{ | |
HashTable[index]->first = first; | |
HashTable[index]->second = second; | |
HashTable[index]->third = third; | |
} | |
else | |
{ | |
node* Ptr = HashTable[index]; | |
node* n = new node; | |
n->first = first; | |
n->second = second; | |
n->third = third; | |
n->next = NULL; | |
while(Ptr->next != NULL) | |
{ | |
Ptr = Ptr->next; | |
} | |
Ptr->next = n; | |
} | |
} | |
/*Count number of nodes*/ | |
int hash::countnode(int index) | |
{ | |
int count = 0; | |
if(HashTable[index]->first == "") | |
{ | |
return count; | |
} | |
else | |
{ | |
count++; | |
node* Ptr = HashTable[index]; | |
while(Ptr->next != NULL) | |
{ | |
Ptr = Ptr->next; | |
count++; | |
} | |
} | |
return count; | |
} | |
/*Creat hashtable*/ | |
void creat(hash& hashy, map<int,string>& m, map<int,string>& tmap) | |
{ | |
for(int i = 0; i < (int)m.size();i++) | |
{ | |
find(m[i],tmap); | |
string str_first = "[start]" ; | |
string str_second = tmap[0]; | |
string str_third = tmap[1]; | |
hashy.addnode(str_first,str_second,str_third); | |
for(int j=0; j<(int)tmap.size()-2;j++) | |
{ | |
str_first = tmap[j]; | |
str_second = tmap[j+1]; | |
str_third = tmap[j+2]; | |
hashy.addnode(str_first,str_second,str_third); | |
} | |
tmap.clear(); | |
} | |
} | |
/* Creat a random number between 0 and num-1 */ | |
int random(int num) | |
{ | |
int ran_num = rand() % num; | |
return ran_num; | |
} | |
/*Print table*/ | |
void hash::print() | |
{ | |
int number; | |
for(int i = 0; i < tablesize;i++) | |
{ | |
number = countnode(i); | |
cout<<"---------------------------------"<<endl; | |
cout<<"index = "<<i<<endl; | |
cout<<HashTable[i]->first<<endl; | |
cout<<HashTable[i]->second<<endl; | |
cout<<HashTable[i]->third<<endl; | |
cout<<"# of nodes "<<number<<endl; | |
} | |
} | |
void hash::printindex(int index) | |
{ | |
node* Ptr = HashTable[index]; | |
if(Ptr->first == "") | |
{ | |
cout<<"Nothing in there"<<endl; | |
} | |
else | |
{ | |
while(Ptr!= NULL) | |
{ | |
cout<<"---------------------------------"<<endl; | |
cout<<Ptr->first<<endl; | |
cout<<Ptr->second<<endl; | |
cout<<Ptr->third<<endl; | |
Ptr = Ptr->next; | |
} | |
} | |
} | |
/* Generate a new random sentence */ | |
void hash::generating(map<int,string>& m, map<int,string> &tmap, hash& hashy) | |
{ | |
int ran_num = random(m.size()); | |
find(m[ran_num],tmap); | |
string first = "[start]"; | |
string second = tmap[0]; | |
tmap.clear(); | |
string target = second + " "; | |
int j = 5000; //run 5000 times, sometime you can't generate a sentance. | |
while(j>0) | |
{ | |
int index = Hash(first); | |
int numberofnode = hashy.countnode(index); | |
int ran_nodenum = random(numberofnode); | |
// cout<<"index = "<<index<<endl; | |
// cout<<"Number of nodes "<<hashy.countnode(index)<<endl; | |
// cout<<"random number "<<ran_nodenum<<endl; | |
node* n = hashy.HashTable[index]; | |
if(numberofnode>1) | |
{ | |
for(int i = 0;i < ran_nodenum;i++) | |
{ | |
n = n->next; | |
} | |
} | |
if(n->first == first && n->second == second) | |
{ | |
if(n->third == ".") | |
{ | |
target = target + n->third; | |
// cout<<"target temp: "<<target<<endl; | |
break; | |
} | |
else | |
{ | |
target = target + n->third + " "; | |
// cout<<"target temp: "<<target<<endl; | |
first = second; | |
second = n->third; | |
} | |
} | |
j--; | |
} | |
cout<<"New sentence: "<<target<<endl; | |
cout<<"Again? <y/n>"; | |
char x; | |
cin>>x; | |
if(x == 'y') | |
{ | |
hashy.generating(m,tmap,hashy); | |
} | |
} | |
int main() | |
{ | |
srand(unsigned(time(0))); | |
map<int,string> m; | |
map<int,string> tmap; | |
read(m); | |
hash hashy; | |
creat(hashy,m,tmap); | |
// hashy.print(); | |
// hashy.printindex(199); | |
hashy.generating(m,tmap,hashy); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment