Skip to content

Instantly share code, notes, and snippets.

@zhezheng
Created October 11, 2013 04:47
Show Gist options
  • Save zhezheng/6929726 to your computer and use it in GitHub Desktop.
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
/* 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