FileOps.h
#ifndef INC_04_BINARY_SEARCH_TREE_SEARCH_FILEOPS_H
#define INC_04_BINARY_SEARCH_TREE_SEARCH_FILEOPS_H
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
namespace FileOps{
int firstCharacterIndex(const string& s, int start){
for( int i = start ; i < s.length() ; i ++ )
if( isalpha(s[i]) )
return i;
return s.length();
}
string lowerS( const string& s){
string ret = "";
for( int i = 0 ; i < s.length() ; i ++ )
ret += tolower(s[i]);
return ret;
}
bool readFile(const string& filename, vector<string> &words){
string line;
string contents = "";
ifstream file(filename);
if( file.is_open() ){
while( getline(file, line))
contents += ( line + "\n" );
file.close();
}
else{
cout<<"Can not open "<<filename<<" !!!"<<endl;
return false;
}
int start = firstCharacterIndex(contents, 0);
for( int i = start + 1 ; i <= contents.length() ; ){
if( i == contents.length() || !isalpha(contents[i]) ){
words.push_back( lowerS( contents.substr(start,i-start) ) );
start = firstCharacterIndex(contents, i);
i = start + 1;
}
else{
i ++;
}
}
return true;
}
}
#endif
SequenceST.h
#ifndef INC_04_BINARY_SEARCH_TREE_SEARCH_SEQUENCEST_H
#define INC_04_BINARY_SEARCH_TREE_SEARCH_SEQUENCEST_H
#include <iostream>
#include <cassert>
using namespace std;
template<typename Key, typename Value>
class SequenceST{
private:
struct Node{
Key key;
Value value;
Node *next;
Node(Key key, Value value){
this->key = key;
this->value = value;
this->next = NULL;
}
};
Node* head;
int count;
public:
SequenceST(){
head = NULL;
count = 0;
}
~SequenceST(){
while( head != NULL){
Node *node = head;
head = head->next;
delete node;
count --;
}
assert( head == NULL && count == 0 );
}
int size(){
return count;
}
bool isEmpty(){
return count == 0;
};
void insert(Key key, Value value){
Node *node = head;
while( node != NULL ){
if( key == node->key ){
node->value = value;
return;
}
node = node->next;
}
Node *newNode = new Node(key, value);
newNode->next = head;
head = newNode;
count ++;
}
bool contain(Key key){
Node *node = head;
while( node != NULL ){
if( key == node->key ){
return true;
}
node = node->next;
}
return false;
}
Value* search(Key key){
Node *node = head;
while( node != NULL ){
if( key == node->key ){
return &(node->value);
}
node = node->next;
}
return NULL;
}
void remove(Key key){
if( key == head->key ){
Node* delNode = head;
head = head->next;
delete delNode;
count--;
return;
}
Node *node = head;
while( node->next != NULL && node->next->key != key )
node = node->next;
if( node->next != NULL ){
Node* delNode = node->next;
node->next = delNode->next;
delete delNode;
count --;
return;
}
}
};
#endif
main.cpp
#include <iostream>
#include <vector>
#include <string>
#include "SequenceST.h"
#include "FileOps.h"
using namespace std;
template <typename Key, typename Value>
class BST{
private:
struct Node{
Key key;
Value value;
Node *left;
Node *right;
Node(Key key, Value value){
this->key = key;
this->value = value;
this->left = this->right = NULL;
}
};
Node *root;
int count;
public:
BST(){
root = NULL;
count = 0;
}
~BST(){
// TODO: ~BST()
}
int size(){
return count;
}
bool isEmpty(){
return count == 0;
}
void insert(Key key, Value value){
root = insert(root, key, value);
}
bool contain(Key key){
return contain(root, key);
}
Value* search(Key key){
return search( root , key );
}
private:
// 向以node为根的二叉搜索树中,插入节点(key, value)
// 返回插入新节点后的二叉搜索树的根
Node* insert(Node *node, Key key, Value value){
if( node == NULL ){
count ++;
return new Node(key, value);
}
if( key == node->key )
node->value = value;
else if( key < node->key )
node->left = insert( node->left , key, value);
else // key > node->key
node->right = insert( node->right, key, value);
return node;
}
// 查看以node为根的二叉搜索树中是否包含键值为key的节点
bool contain(Node* node, Key key){
if( node == NULL )
return false;
if( key == node->key )
return true;
else if( key < node->key )
return contain( node->left , key );
else // key > node->key
return contain( node->right , key );
}
// 在以node为根的二叉搜索树中查找key所对应的value
Value* search(Node* node, Key key){
if( node == NULL )
return NULL;
if( key == node->key )
return &(node->value);
else if( key < node->key )
return search( node->left , key );
else // key > node->key
return search( node->right, key );
}
};
int main() {
string filename = "bible.txt";
vector<string> words;
if( FileOps::readFile(filename, words) ) {
cout << "There are totally " << words.size() << " words in " << filename << endl;
cout << endl;
// test BST
time_t startTime = clock();
BST<string, int> bst = BST<string, int>();
for (vector<string>::iterator iter = words.begin(); iter != words.end(); iter++) {
int *res = bst.search(*iter);
if (res == NULL)
bst.insert(*iter, 1);
else
(*res)++;
}
cout << "'god' : " << *bst.search("god") << endl;
time_t endTime = clock();
cout << "BST , time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " s." << endl;
cout << endl;
// test SST
startTime = clock();
SequenceST<string, int> sst = SequenceST<string, int>();
for (vector<string>::iterator iter = words.begin(); iter != words.end(); iter++) {
int *res = sst.search(*iter);
if (res == NULL)
sst.insert(*iter, 1);
else
(*res)++;
}
cout << "'god' : " << *sst.search("god") << endl;
endTime = clock();
cout << "SST , time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " s." << endl;
}
return 0;
}