├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── README.md ├── darwin12.supp ├── demo_graph.png ├── donate_alg.png ├── include ├── .goutputstream-UUQE8X ├── 2darray.h ├── 8queen.h ├── LRU_cache.h ├── astar.h ├── avl.h ├── base64.h ├── bellman_ford.h ├── binary_search_tree.h ├── bitset.h ├── bloom_filter.h ├── btree.h ├── bubble_sort.h ├── dictionary.h ├── dijkstra.h ├── directed_graph.h ├── disjoint-set.h ├── dos_tree.h ├── double_linked_list.h ├── edmonds_karp.h ├── fenwick_tree.h ├── fib-heap.h ├── generic.h ├── graph_defs.h ├── graph_search.h ├── hash_code.h ├── hash_multi.h ├── hash_string.h ├── hash_table.h ├── heap.h ├── huffman.h ├── imath.h ├── insertion_sort.h ├── integer.h ├── interval_tree.h ├── k-means.h ├── kmp.h ├── kruskal_mst.h ├── lcs.h ├── max_subarray.h ├── md5.h ├── merge_sort.h ├── palindrome.h ├── perfect_hash.h ├── prim_mst.h ├── prime.h ├── priority_queue.h ├── queue.h ├── quick_sort.h ├── radix_sort.h ├── random.h ├── random_select.h ├── rbtree.h ├── rbtree_defs.h ├── relabel_to_front.h ├── scc.h ├── selection_sort.h ├── sha1.h ├── shell_sort.h ├── shuffle.h ├── simhash.h ├── skiplist.h ├── sol.h ├── sort.h ├── stack.h ├── suffix_array.h ├── suffix_tree.h ├── trie.h ├── undirected_graph.h ├── universal_hash.h └── word_seg.h ├── msvc ├── alg_vs.h └── stdbool.h ├── src ├── 8queue_demo.cpp ├── LRU_cache_demo.cpp ├── astar_demo.cpp ├── avl_demo.cpp ├── base64_demo.cpp ├── bellman_ford_demo.cpp ├── binary_search_tree_demo.cpp ├── bitset_demo.cpp ├── bloom_filter_demo.cpp ├── btree_demo.cpp ├── bubble_sort_demo.cpp ├── dict.txt ├── dict.txt.sogou ├── dictionary_demo.cpp ├── dijkstra_demo.cpp ├── directed_graph_demo.cpp ├── disjoint-set_demo.cpp ├── dos_tree_demo.cpp ├── double_linked_list_demo.cpp ├── edmonds_karp_demo.cpp ├── fenwick_tree_demo.cpp ├── fib-heap_demo.cpp ├── graph_demo.cpp ├── graph_search_demo.cpp ├── hash_multi_demo.cpp ├── hash_string_demo.cpp ├── hash_table_demo.cpp ├── heap_demo.cpp ├── huffman_demo.cpp ├── imath_demo.cpp ├── insertion_sort_demo.cpp ├── integer_demo.cpp ├── interval_tree_demo.cpp ├── k-means_demo.cpp ├── kmp_demo.cpp ├── kruskal_mst_demo.cpp ├── lcs_demo.cpp ├── m_based_demo.cpp ├── max_subarray_demo.cpp ├── md5_demo.cpp ├── merge_sort_demo.cpp ├── palindrome_demo.cpp ├── perfect_hash_demo.cpp ├── prim_mst_demo.cpp ├── prime_decompose.c ├── prime_demo.cpp ├── priority_queue_demo.cpp ├── queue_demo.cpp ├── quick_sort_demo.cpp ├── radix_sort_demo.cpp ├── random_demo.cpp ├── random_select_demo.cpp ├── rbtree_demo.cpp ├── relabel_to_front_demo.cpp ├── scc_demo.cpp ├── selection_sort_demo.cpp ├── sha1_demo.cpp ├── shell_sort_demo.cpp ├── shuffle_demo.cpp ├── simhash_demo.cpp ├── skiplist_demo.cpp ├── sort_demo.cpp ├── stack_demo.cpp ├── suffix_array_demo.cpp ├── suffix_tree_demo.cpp ├── trie_demo.cpp ├── undirected_graph_demo.cpp ├── universal_hash_demo.cpp └── word_seg_demo.cpp └── utils ├── byteorder.h └── gb18030.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.dSYM 2 | *_demo 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | compiler: 4 | - gcc 5 | - clang 6 | 7 | script: 8 | - make 9 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 2.6 ) 2 | project( algorithm ) 3 | 4 | include_directories( "include" ) 5 | include_directories( "." ) 6 | if( MSVC ) 7 | include_directories( "msvc" ) 8 | endif() 9 | 10 | #add_executable(word_seg "src/word_seg_demo.cpp") 11 | #add_executable(astar "src/astar_demo.cpp") 12 | 13 | file( GLOB APP_SOURCES src/*.cpp ) 14 | SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /FI\"msvc/alg_vs.h\"" ) 15 | message( ${CMAKE_CXX_FLAGS} ) 16 | foreach( appsourcefile ${APP_SOURCES} ) 17 | get_filename_component( demo_name ${appsourcefile} NAME_WE ) 18 | add_executable( ${demo_name} ${appsourcefile} ) 19 | endforeach( appsourcefile ${APP_SOURCES} ) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 xtaci. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ###Algorithms & Data Structures in C++ 2 | [![Build Status][1]][2] 3 | [1]: https://travis-ci.org/xtaci/algorithms.svg?branch=master 4 | [2]: https://travis-ci.org/xtaci/algorithms 5 | 6 | ####目标 ( goal ) : 7 | 8 | 1. 经典的算法实现 9 | (classical algorithms implementations) 10 | 2. 服务器端 11 | (based on linux/gcc) 12 | 3. 正确,易于使用和改造, 一个头文件一个算法,并附带一个demo. 13 | (correct! and ease of use, one .header file per algorithm) 14 | 15 | ####约定 ( Convention ): 16 | 17 | 1. 一个算法用一个.h文件表示放到include下. ( one .header file per algorithm. ) 18 | 2. 算法演示的demo程序放到src下. ( one demo per algorithm. ) 19 | 3. 程序正确通过后,请发起Pull Requests,代码被验证后入库,并在README中发布新算法实现。 20 | (Please Use Fork+Pull Requests !!! Correctness is the most important!) 21 | 4. TAB = 4 space. set ts=4 in vim 22 | 5. Graph的输出格式为 [Graphviz](http://www.graphviz.org/) Dot格式. 23 | (the output format of the graph is in dot of graphviz.) 24 | eg: 25 | ![demograph](demo_graph.png) 26 | 27 | ####已实现 ( Implemented ): 28 | 29 | Array shuffle 30 | Prime test(trial division) 31 | Prime test(Miller-Rabin's method) 32 | 2D Array 33 | Arbitrary Integer 34 | Linear congruential generator 35 | Maximum subarray problem 36 | 37 | Bit-Set 38 | Queue 39 | Stack 40 | Binary Heap 41 | Fibonacci Heap 42 | Priority Queue (list based) 43 | 44 | Bubble sort 45 | Selection sort 46 | Insertion sort 47 | Shell sort 48 | Radix sort 49 | Quick sort 50 | Merge sort 51 | Double linked list 52 | Skip list 53 | Self-organized linked-list ops (move-to-front, move-ahead-one) 54 | Largest common sequence 55 | 56 | Binary search tree 57 | AVL tree 58 | Dynamic order statistics 59 | Red-black tree 60 | Interval tree 61 | Prefix Tree(Trie) 62 | Suffix Tree 63 | B-Tree 64 | Suffix Array 65 | 66 | Hash by multiplication 67 | Hash table 68 | Universal hash function 69 | Perfect hash 70 | Java's string hash 71 | FNV-1a string hash 72 | SimHash 73 | Bloom Filter 74 | SHA-1 Message Digest Algorithm 75 | MD5 76 | Base64 77 | 78 | Graph data structure 79 | Strongly Connected Components(SCC) 80 | Prim's minimum spanning tree 81 | Kruskal MST 82 | Directed/Undirected graph ops 83 | Breadth First Search 84 | Depth First Search 85 | Dijkstra's algorithm 86 | Bellman-Ford algorithm 87 | Edmonds-Karp Maximal Flow 88 | Push–Relabel algorithm 89 | 90 | Huffman Coding 91 | Word segementation(CHN/GB18030) using HMM and viterbi algorithm. 92 | A* algorithm 93 | K-Means 94 | Knuth–Morris–Pratt algorithm 95 | Disjoint-Set 96 | 8-Queue Problem 97 | Palindrome 98 | 99 | ####贡献者 ( Contributors ) : 100 | Samana: for heavy work of MSVC compatability 101 | wycg1984: for K-Means 102 | xmuliang: for HeapSort, Kruskal MST 103 | wyh267: for base64, LRU, bubble sort, selection sort 104 | ZhangYou0122: Push-Relabel algorithm, Suffix Tree 105 | UsingtcNower: Suffix Array 106 | afernandez90: AVL trees 107 | 108 | ####支持此项目 ( Donations ) : 109 | ![donate](donate_alg.png) 110 | 欢迎使用支付宝扫描上面的二维码,对该项目进行捐赠。捐赠款项将用于持续优化补全及完善。 111 | -------------------------------------------------------------------------------- /demo_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollon282/-Algorithm-/6e89ffd2197a151b8c790b74d5b34996ff57b6a1/demo_graph.png -------------------------------------------------------------------------------- /donate_alg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollon282/-Algorithm-/6e89ffd2197a151b8c790b74d5b34996ff57b6a1/donate_alg.png -------------------------------------------------------------------------------- /include/.goutputstream-UUQE8X: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Fenwick Tree 3 | * 4 | * Data structure providing prefix sums and modify the table in O(log n) - n is the size o the table. 5 | * 6 | * In this algorithm we use two functions: 7 | * - RSQ - This function calculates the range sum query in O(log n) 8 | * - Update - This function adjusts the values in the given range in O(log n) 9 | * 10 | * https://en.wikipedia.org/wiki/Fenwick_tree 11 | * 12 | * @author Gabriel Duarte (gabriellagoa10@yahoo.com.br) 13 | * @github Gabriel123Duarte 14 | * 15 | ******************************************************************************/ 16 | 17 | #ifndef __FENWICK_H__ 18 | #define __FENWICK_H__ 19 | 20 | #include 21 | 22 | #define LSONE(x) (x & (-x)) 23 | 24 | class Fenwick 25 | { 26 | private: 27 | // Vector representing the table 28 | std::vector fen; 29 | public: 30 | Fenwick() {} 31 | 32 | // We don't use the index 0, because it is the base case 33 | Fenwick(int n) 34 | { 35 | fen.assign(n + 1, 0); 36 | } 37 | 38 | // Calculate the 39 | int rsq(int a) 40 | { 41 | int ans = 0; 42 | for(; a; a -= LSONE(a)) 43 | ans += fen[a]; 44 | return ans; 45 | } 46 | 47 | // RSQ a..b 48 | inline int rsq(int a, int b) 49 | { 50 | return rsq(b) - (a == 1 ? 0 : rsq(a - 1)); 51 | } 52 | 53 | // Update the value of the k-th element by x 54 | void update(int k, int x) 55 | { 56 | for(; k < (int)fen.size(); k += LSONE(k)) 57 | fen[k] += x; 58 | } 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /include/2darray.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * 2-DIMENSIONAL ARRAY 9 | * 10 | * Simulated by 1-dimension array. 11 | ******************************************************************************/ 12 | 13 | #ifndef ALGO_2D_ARRAY_H__ 14 | #define ALGO_2D_ARRAY_H__ 15 | #include 16 | #include 17 | 18 | namespace alg { 19 | /** 20 | * 2D Array definition 21 | */ 22 | template 23 | class Array2D { 24 | private: 25 | uint32_t NR; // num of rows 26 | uint32_t NC; // num of columns 27 | T * m_data; // the place where the array resides. 28 | 29 | public: 30 | /** 31 | * construct an array of size [nrow,col] 32 | */ 33 | Array2D(uint32_t nrow, uint32_t ncol) { 34 | NR = nrow; 35 | NC = ncol; 36 | m_data = new T[nrow*ncol]; 37 | } 38 | 39 | /** 40 | * destructor 41 | */ 42 | ~Array2D() { 43 | delete [] m_data; 44 | } 45 | 46 | private: 47 | Array2D(const Array2D&); 48 | Array2D& operator=(const Array2D&); 49 | 50 | public: 51 | 52 | /** 53 | * return number of rows of this array 54 | */ 55 | inline const uint32_t row() const { return NR; } 56 | /** 57 | * return number of columns of this array 58 | */ 59 | inline const uint32_t col() const { return NC; } 60 | 61 | /** 62 | * return the value by the given (row, col); 63 | */ 64 | inline T& operator() (int row, int col) { return this->m_data[row*NC + col]; } 65 | const inline T& operator() (int row, int col) const { return this->m_data[row*NC + col]; } 66 | 67 | inline T* operator[] (int row) { return &(m_data[row * NC]); } 68 | inline const T* operator[] (int row) const { return &(m_data[row * NC]); } 69 | 70 | /** 71 | * clear the array by a given value 72 | */ 73 | void clear(const T & value) { 74 | for(uint32_t i=0; i 6 | * _| 7 | * 8-Queue 8 | * 9 | * http://en.wikipedia.org/wiki/Eight_queens_puzzle 10 | ******************************************************************************/ 11 | 12 | #ifndef ALGO_8QUEEN_H__ 13 | #define ALGO_8QUEEN_H__ 14 | 15 | #include 16 | #include 17 | 18 | namespace alg { 19 | class Queen8 { 20 | private: 21 | char board[8][8]; 22 | int cnt; 23 | public: 24 | void solve() { 25 | memset(board, '0', sizeof(board)); 26 | cnt = 0; 27 | _solve(0); 28 | } 29 | private: 30 | void _solve(int row) { // start from 0 31 | int i; 32 | for (i=0;i<8;i++) { 33 | board[row][i] = '1'; 34 | if (check(row, i)) { 35 | if (row == 7) print(); 36 | else _solve(row+1); 37 | } 38 | board[row][i] = '0'; // rollback 39 | } 40 | } 41 | 42 | void print() { 43 | printf("chessboard: %d\n",++cnt); 44 | int i,j; 45 | for (i=0;i<8;i++) { 46 | for (j=0;j<8;j++) { 47 | printf("%c ", board[i][j]); 48 | } 49 | printf("\n"); 50 | } 51 | } 52 | 53 | bool check(int row, int col) { 54 | int i,j; 55 | 56 | // cannot be same column 57 | for (i=0;i=0 && j >=0) { 66 | if (board[i][j] == '1') { 67 | return false; 68 | } 69 | i--; 70 | j--; 71 | } 72 | 73 | i = row-1, j = col+1; 74 | while (i>=0 && j <8) { 75 | if (board[i][j] == '1') { 76 | return false; 77 | } 78 | i--; 79 | j++; 80 | } 81 | 82 | return true; 83 | } 84 | }; 85 | } 86 | 87 | #endif //ALGO_8QUEEN_H__ 88 | -------------------------------------------------------------------------------- /include/LRU_cache.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 4 | * /--\ | (_| (_) | | |_ | | | | | _> 5 | * _| 6 | * 7 | * Least Recently Used (LRU): 8 | * discards the least recently used items first. This algorithm requires 9 | * keeping track of what was used when, which is expensive if one wants to make 10 | * sure the algorithm always discards the least recently used item. General 11 | * implementations of this technique require keeping "age bits" for cache-lines 12 | * and track the "Least Recently Used" cache-line based on age-bits. In such an 13 | * implementation, every time a cache-line is used, 14 | * the age of all other cache-lines changes 15 | * 16 | * We use this double list to store the cache like this: 17 | * 18 | * NodeHead <==> Node1 <==> Node2 <==> ... ... <==> NodeN <==>NodeNear 19 | * 20 | * the "NodeHead" and "NodeNear" have no data , them just for head and near. 21 | * 22 | * Two Interface: 23 | * getValue : get the value by key ,and put the Node to first 24 | * putValue : add or update the Node's Key and Value, and then, 25 | * put the Node to first 26 | * 27 | * http://en.wikipedia.org/wiki/LRU_cache#Least_Recently_Used 28 | * 29 | ******************************************************************************/ 30 | 31 | #ifndef _LRUCACHE_ 32 | #define _LRUCACHE_ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | using namespace std; 42 | 43 | namespace alg { 44 | template 45 | class LRUCache { 46 | typedef struct _Node_{ 47 | K key; 48 | V value; 49 | 50 | struct _Node_ *next; 51 | struct _Node_ *pre; 52 | } CacheNode; 53 | 54 | public: 55 | LRUCache(int cache_size=10) { 56 | cache_size_ = cache_size; 57 | p_cache_list_head = new CacheNode(); 58 | p_cache_list_near = new CacheNode(); 59 | p_cache_list_head->next = p_cache_list_near; 60 | p_cache_list_head->pre = NULL; 61 | p_cache_list_near->pre = p_cache_list_head; 62 | p_cache_list_near->next = NULL; 63 | } 64 | 65 | ~LRUCache() { 66 | CacheNode *p; 67 | p = p_cache_list_head->next; 68 | while(p!=NULL) { 69 | delete p->pre; 70 | p=p->next; 71 | } 72 | 73 | delete p_cache_list_near; 74 | cache_hash.clear(); 75 | } 76 | 77 | V getValue(K key) { 78 | //put the value in front of the list if find the key 79 | if(cache_hash.find(key) != cache_hash.end()){ 80 | CacheNode *p=cache_hash[key]; 81 | detachNode(p); 82 | addFristNode(p); 83 | return (cache_hash[key]->value); 84 | }else{ 85 | 86 | cout << "[ERROR]No key with name ::" << key << endl; 87 | return V(); 88 | } 89 | 90 | } 91 | 92 | bool putValue(K key,V value) { 93 | if (cache_hash.find(key) != cache_hash.end()) { 94 | cache_hash[key]->value=value; 95 | detachNode((CacheNode *)cache_hash[key]); 96 | addFristNode((CacheNode *)cache_hash[key]); 97 | if (cache_hash.size()>cache_size_) { 98 | delEndNode(); 99 | } 100 | } else { 101 | CacheNode *p=new CacheNode(); 102 | p->key=key; 103 | p->value=value; 104 | addFristNode(p); 105 | cache_hash[key]=p; 106 | if(cache_hash.size()>cache_size_){ 107 | cout << "[INFO]LRU Cache is full ... Delete Last One..." << endl; 108 | delEndNode(); 109 | } 110 | } 111 | 112 | return true; 113 | } 114 | 115 | void display(){ 116 | CacheNode *p=p_cache_list_head->next; 117 | while(p->next!=NULL) { 118 | std::cout << " KEY[" << p->key << "]<==>VALUE[" << p->value <<"]" << std::endl; 119 | p=p->next; 120 | } 121 | std::cout << std::endl; 122 | } 123 | 124 | private: 125 | int cache_size_; 126 | CacheNode *p_cache_list_head; 127 | CacheNode *p_cache_list_near; 128 | mapcache_hash; 129 | 130 | 131 | void detachNode(CacheNode *node){ 132 | node->pre->next=node->next; 133 | node->next->pre=node->pre; 134 | } 135 | 136 | void addFristNode(CacheNode *node){ 137 | node->pre=p_cache_list_head; 138 | if(cache_hash.empty()) { 139 | node->next=p_cache_list_near; 140 | p_cache_list_near->pre=node; 141 | p_cache_list_head->next=node; 142 | } else { 143 | node->next=p_cache_list_head->next; 144 | p_cache_list_head->next->pre=node; 145 | p_cache_list_head->next=node; 146 | } 147 | } 148 | 149 | void delEndNode(){ 150 | CacheNode *p=p_cache_list_near->pre; 151 | detachNode(p); 152 | cout << "[INFO]Delete key ::: " << p->key <key); 154 | free(p); 155 | } 156 | }; 157 | } 158 | 159 | #endif 160 | -------------------------------------------------------------------------------- /include/base64.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 4 | * /--\ | (_| (_) | | |_ | | | | | _> 5 | * _| 6 | * 7 | * Base64 8 | * Base64 is a group of similar binary-to-text encoding schemes that represent 9 | * binary data in an ASCII string format by translating it into a radix-64 10 | * representation. The term Base64 originates from a specific MIME content 11 | * transfer encoding. 12 | * 13 | * http://en.wikipedia.org/wiki/Base64 14 | ******************************************************************************/ 15 | 16 | #ifndef _CBASE64_H_ 17 | #define _CBASE64_H_ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace alg { 25 | class CBase64 { 26 | public: 27 | static std::string encodeBase64(unsigned char *input , int input_len) { 28 | const char * code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 29 | unsigned char input_char[3]; 30 | char output_char[5]; 31 | int output_num; 32 | std::string output_str=""; 33 | int near=input_len%3; 34 | 35 | for (int i=0;i>18) & 0xff)]; 46 | output_char[1]=code[((output_num>>12) & 0x3f)]; 47 | output_char[2]='='; 48 | output_char[3]='='; 49 | output_char[4]='\0'; 50 | } 51 | 52 | if (near==2) { 53 | output_char[0]=code[((output_num>>18) & 0xff)]; 54 | output_char[1]=code[((output_num>>12) & 0x3f)]; 55 | output_char[2]=code[((output_num>>6) & 0x3f)];; 56 | output_char[3]='='; 57 | output_char[4]='\0'; 58 | } 59 | 60 | output_str.append(output_char); 61 | break; 62 | } 63 | 64 | output_num=((int)input_char[0]<<16)+((int)input_char[1]<<8)+(int)input_char[2]; 65 | output_char[0]=code[((output_num>>18) & 0xff)]; 66 | output_char[1]=code[((output_num>>12) & 0x3f)]; 67 | output_char[2]=code[((output_num>>6) & 0x3f)]; 68 | output_char[3]=code[((output_num) & 0x3f)]; 69 | output_char[4]='\0'; 70 | output_str.append(output_char); 71 | } 72 | 73 | return output_str; 74 | } 75 | 76 | static std::string decodeBase64(std::string input) { 77 | unsigned char input_char[4]; 78 | unsigned char output_char[4]; 79 | int output_num=0; 80 | int k=0; 81 | std::string output_str=""; 82 | 83 | for (unsigned int i=0;i> 16) ; 89 | output_char[1]=(unsigned char)((output_num & 0x0000FF00 ) >> 8) ; 90 | output_char[2]=(unsigned char)(output_num & 0x000000FF) ; 91 | output_char[3]='\0'; 92 | output_str.append((char *)output_char); 93 | k=0; 94 | } 95 | } 96 | 97 | return output_str; 98 | } 99 | 100 | static int indexOfCode(const char c) { 101 | const char * code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 102 | for (unsigned int i=0;i<64;i++) { 103 | if (code[i]==c) 104 | return i; 105 | } 106 | return 0; 107 | } 108 | }; 109 | } 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /include/bellman_ford.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * BELLMAN-FORD ALGORITHM 9 | * 10 | * The Bellman–Ford algorithm computes single-source shortest paths in a 11 | * weighted digraph. For graphs with only non-negative edge weights, the faster 12 | * Dijkstra's algorithm also solves the problem. Thus, Bellman–Ford is used 13 | * primarily for graphs with negative edge weights. The algorithm is named after 14 | * its developers, Richard Bellman and Lester Ford, Jr. 15 | * 16 | * procedure BellmanFord(list vertices, list edges, vertex source) 17 | * // This implementation takes in a graph, represented as lists of vertices 18 | * // and edges, and modifies the vertices so that their distance and 19 | * // predecessor attributes store the shortest paths. 20 | * 21 | * // Step 1: initialize graph 22 | * for each vertex v in vertices: 23 | * if v is source then v.distance := 0 24 | * else v.distance := infinity 25 | * v.predecessor := null 26 | * 27 | * // Step 2: relax edges repeatedly 28 | * for i from 1 to size(vertices)-1: 29 | * for each edge uv in edges: // uv is the edge from u to v 30 | * u := uv.source 31 | * v := uv.destination 32 | * if u.distance + uv.weight < v.distance: 33 | * v.distance := u.distance + uv.weight 34 | * v.predecessor := u 35 | * 36 | * // Step 3: check for negative-weight cycles 37 | * for each edge uv in edges: 38 | * u := uv.source 39 | * v := uv.destination 40 | * if u.distance + uv.weight < v.distance: 41 | * error "Graph contains a negative-weight cycle" 42 | * 43 | * http://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm 44 | * 45 | ******************************************************************************/ 46 | 47 | #ifndef ALGO_BELLMAN_FORD_H__ 48 | #define ALGO_BELLMAN_FORD_H__ 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include "directed_graph.h" 57 | #include "hash_table.h" 58 | 59 | // define UNDEFINED previous vertex. 60 | #define UNDEFINED -1 61 | 62 | namespace alg { 63 | class BellmanFord { 64 | private: 65 | HashTable dist; // hash table for distance. 66 | bool has_neg_cycle; // negative weighted cycle mark. 67 | const Graph & g; 68 | public: 69 | BellmanFord(const Graph & graph): 70 | dist(graph.vertex_count()),g(graph) { } 71 | 72 | /** 73 | * Bellman-Ford algorithm 74 | */ 75 | HashTable * run(uint32_t source) { 76 | // hash table for previous vertex 77 | HashTable * previous = new HashTable(g.vertex_count()); 78 | // source vertex 79 | dist[source] = 0; 80 | 81 | // other vertices 82 | Graph::Adjacent * a; 83 | list_for_each_entry(a, &g.list(), a_node){ 84 | if (source != a->v.id) { 85 | dist[a->v.id] = INT_MAX; 86 | } 87 | (*previous)[a->v.id] = UNDEFINED; 88 | } 89 | 90 | has_neg_cycle = false; // negative cycle mark set to 'false'. 91 | 92 | // relax edges repeatedly 93 | Graph::Adjacent * u; 94 | for (uint32_t i=0;iv.id]; 97 | 98 | Graph::Vertex * v; 99 | list_for_each_entry(v, &u->v_head, v_node){ 100 | int32_t dist_v = dist[v->id]; 101 | 102 | if (dist_u + v->weight < dist_v) { 103 | dist[v->id] = dist_u + v->weight; 104 | (*previous)[v->id] = u->v.id; 105 | } 106 | } 107 | } 108 | } 109 | 110 | // check for negative-weight cycles 111 | list_for_each_entry(u, &g.list(), a_node) { 112 | int32_t dist_u = dist[u->v.id]; 113 | 114 | Graph::Vertex * v; 115 | list_for_each_entry(v, &u->v_head, v_node){ 116 | int32_t dist_v = dist[v->id]; 117 | 118 | if (dist_u + v->weight < dist_v) { 119 | has_neg_cycle = true; // graph contains a negative-weight cycle 120 | return previous; 121 | } 122 | } 123 | } 124 | 125 | return previous; 126 | } 127 | 128 | inline bool has_negative_cycle() { return has_neg_cycle; } 129 | }; 130 | } 131 | 132 | #endif // 133 | -------------------------------------------------------------------------------- /include/binary_search_tree.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * BINARY SEARCH TREE 9 | * 10 | * Features: 11 | * 1. Expected search time is O(log(n)), with worst case O(n). 12 | * 2. Data should be !!!SHUFFLED!!! first before tree creation. 13 | * 3. First initialize the value of the root (pointer to the 14 | * structure treeNode) with NULL. eg: 15 | * treeNode *root = NULL 16 | * 17 | * http://en.wikipedia.org/wiki/Binary_search_tree 18 | * 19 | ******************************************************************************/ 20 | 21 | #ifndef ALGO_BINARY_SEARCH_TREE_H__ 22 | #define ALGO_BINARY_SEARCH_TREE_H__ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | namespace alg { 30 | template 31 | class BST { 32 | private: 33 | /** 34 | * binary search tree definition. 35 | */ 36 | struct treeNode { 37 | KeyT key; // key 38 | ValueT value; // data 39 | treeNode *parent; // parent 40 | treeNode *left; // left child 41 | treeNode *right; // right child 42 | }; 43 | 44 | class BSTException: public std::exception { 45 | public: 46 | virtual const char * what() const throw() { 47 | return "key does not exist"; 48 | } 49 | } excp_key; 50 | 51 | private: 52 | treeNode * m_root; // the root 53 | private: 54 | BST(const BST&); 55 | BST& operator=(const BST&); 56 | public: 57 | BST():m_root(NULL){}; 58 | 59 | ~BST() { 60 | destruct_(m_root); 61 | } 62 | 63 | /** 64 | * find key 65 | */ 66 | treeNode * find(const KeyT & key) { 67 | treeNode * n= m_root; 68 | while (n!=NULL && key != n->key) { 69 | if (key < n->key) { 70 | n = n->left; 71 | } else { 72 | n = n->right; 73 | } 74 | } 75 | 76 | return n; 77 | } 78 | 79 | /** 80 | * insert a new data into the binary search tree. 81 | */ 82 | void insert(const KeyT & key, const ValueT & value) { 83 | treeNode *z= new treeNode; 84 | z->key = key; 85 | z->value = value; 86 | z->left = z->right = z->parent = NULL; 87 | 88 | treeNode * n = m_root; 89 | treeNode * y = NULL; 90 | while(n!=NULL) { 91 | y = n; 92 | if(key < n->key) { 93 | n = n->left; 94 | } else { 95 | n = n->right; 96 | } 97 | } 98 | 99 | z->parent = y; 100 | if (y==NULL) { 101 | m_root = z; 102 | } else if (key < y->key) { 103 | y->left = z; 104 | } else { 105 | y->right = z; 106 | } 107 | } 108 | 109 | /** 110 | * delete a key from the binary search tree. 111 | */ 112 | bool deleteKey(const KeyT & key) { 113 | treeNode *z = find(key); 114 | if (z == NULL) { 115 | return false; 116 | } 117 | 118 | if (z->left == NULL) { 119 | transplant(z, z->right); 120 | } else if (z->right == NULL) { 121 | transplant(z, z->left); 122 | } else { 123 | // find the minimum element of the right subtree 124 | treeNode *y = minimum(z->right); 125 | if (y->parent != z) { 126 | // replace y with right-child 127 | transplant(y, y->right); 128 | // replace right-child of y with the right-child of z 129 | y->right = z->right; 130 | // make y the parent of the right-child 131 | y->right->parent = y; 132 | } 133 | 134 | // replace z with y 135 | transplant(z,y); 136 | y->left = z->left; 137 | y->left->parent = y; 138 | } 139 | 140 | delete z; 141 | return true; 142 | } 143 | 144 | void print_tree(treeNode * n, int indent) { 145 | if (n == NULL) { 146 | return; 147 | } 148 | print_tree(n->right, indent+1); 149 | int i; 150 | for (i=0;ikey << "," << n->value << "]" << std::endl; 154 | print_tree(n->left, indent+1); 155 | } 156 | 157 | void print_helper() { 158 | print_tree(m_root, 0); 159 | } 160 | 161 | private: 162 | void destruct_(treeNode *n) { 163 | if (n==NULL) return; 164 | destruct_(n->left); 165 | destruct_(n->right); 166 | delete n; 167 | } 168 | 169 | /** 170 | * replace node u with v. 171 | */ 172 | void transplant(treeNode *u, treeNode *v) { 173 | if (u->parent == NULL) { 174 | m_root = v; 175 | } else if (u == u->parent->left) { 176 | u->parent->left = v; 177 | } else { 178 | u->parent->right = v; 179 | } 180 | 181 | if (v!=NULL) { 182 | v->parent = u->parent; 183 | } 184 | } 185 | 186 | /** 187 | * find the minimum element of the subtree 188 | */ 189 | treeNode * minimum(treeNode *x) { 190 | while (x->left != NULL) { 191 | x = x->left; 192 | } 193 | 194 | return x; 195 | } 196 | }; 197 | } 198 | 199 | #endif // 200 | -------------------------------------------------------------------------------- /include/bitset.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * BIT-SET 9 | * 10 | * a bit-set data structure 11 | * 12 | ******************************************************************************/ 13 | 14 | #ifndef ALGO_BIT_SET_H__ 15 | #define ALGO_BIT_SET_H__ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace alg { 23 | /** 24 | * definition of bitset class 25 | */ 26 | class BitSet { 27 | private: 28 | uint32_t m_size; //size in bits 29 | uint32_t m_bytes; // size in bytes 30 | unsigned char * m_bits; // the bits 31 | 32 | public: 33 | /** 34 | * construct BitSet by a give number of bits 35 | */ 36 | BitSet(uint32_t num_bits) { 37 | // round up 38 | m_bytes = num_bits/8+1; 39 | m_size = m_bytes * 8; 40 | m_bits = new unsigned char[m_bytes]; 41 | memset(m_bits, 0, m_bytes); 42 | } 43 | 44 | /** 45 | * safely free 46 | */ 47 | ~BitSet() { 48 | delete [] m_bits; 49 | } 50 | 51 | private: 52 | BitSet(const BitSet&); 53 | BitSet& operator=(const BitSet&); 54 | 55 | public: 56 | 57 | /** 58 | * set 1 to position [bit] 59 | */ 60 | inline void set(uint32_t bit) { 61 | if (bit>=m_size) return; 62 | 63 | uint32_t n = bit/8; 64 | uint32_t off = bit%8; 65 | 66 | m_bits[n] |= 128U>>off; 67 | } 68 | 69 | /** 70 | * set 0 to position [bit] 71 | */ 72 | inline void unset(uint32_t bit) { 73 | if (bit>=m_size) return; 74 | 75 | uint32_t n = bit/8; 76 | uint32_t off = bit%8; 77 | 78 | m_bits[n] &= ~(128U>>off); 79 | } 80 | 81 | /** 82 | * test a bit , true if set, false if not. 83 | */ 84 | inline bool test(uint32_t bit) { 85 | if (bit>=m_size) return false; 86 | 87 | uint32_t n = bit/8; 88 | uint32_t off = bit%8; 89 | 90 | if (m_bits[n] & (128U>>off))return true; 91 | return false; 92 | } 93 | }; 94 | } 95 | 96 | #endif // 97 | -------------------------------------------------------------------------------- /include/bloom_filter.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * BLOOM FILTER 9 | * 10 | * Features: 11 | * A Bloom filter with 1% error and an optimal value of k, in contrast, 12 | * requires only about 9.6 bits per element — regardless of the size of the 13 | * elements. This advantage comes partly from its compactness, inherited from 14 | * arrays, and partly from its probabilistic nature. If a 1% false-positive rate 15 | * seems too high, adding about 4.8 bits per element decreases it by ten times. 16 | * 17 | * http://en.wikipedia.org/wiki/Bloom_filter 18 | * 19 | ******************************************************************************/ 20 | 21 | #ifndef ALGO_BLOOM_FILTER_H__ 22 | #define ALGO_BLOOM_FILTER_H__ 23 | 24 | #include 25 | #include 26 | #include 27 | #include "hash_string.h" 28 | #include "bitset.h" 29 | #include "universal_hash.h" 30 | 31 | namespace alg 32 | { 33 | /** 34 | * definiton of bloom filter structure 35 | */ 36 | template 37 | class BloomFilter { 38 | private: 39 | uint32_t m_bits; // num of bits 40 | uint32_t m_probset; // total elements 41 | BitSet m_bitset; // the bit set structure. 42 | struct UHash m_hash[K]; // universal hash parameters 43 | public: 44 | /** 45 | * check false positive rate here, for setting up: 46 | * http://pages.cs.wisc.edu/~cao/papers/summary-cache/node8.html 47 | * Examples: 48 | * Table 3: False positive rate under various m/n and k combinations. 49 | m/n k(opt) k=1 k=2 k=3 k=4 k=5 k=6 k=7 k=8 50 | 2 1.39 0.393 0.400 51 | 3 2.08 0.283 0.237 0.253 52 | 4 2.77 0.221 0.155 0.147 0.160 53 | 5 3.46 0.181 0.109 0.092 0.092 0.101 54 | 6 4.16 0.154 0.0804 0.0609 0.0561 0.0578 0.0638 55 | 7 4.85 0.133 0.0618 0.0423 0.0359 0.0347 0.0364 56 | 8 5.55 0.118 0.0489 0.0306 0.024 0.0217 0.0216 0.0229 57 | 9 6.24 0.105 0.0397 0.0228 0.0166 0.0141 0.0133 0.0135 0.0145 58 | 10 6.93 0.0952 0.0329 0.0174 0.0118 0.00943 0.00844 0.00819 0.00846 59 | 11 7.62 0.0869 0.0276 0.0136 0.00864 0.0065 0.00552 0.00513 0.00509 60 | 12 8.32 0.08 0.0236 0.0108 0.00646 0.00459 0.00371 0.00329 0.00314 61 | 13 9.01 0.074 0.0203 0.00875 0.00492 0.00332 0.00255 0.00217 0.00199 62 | 14 9.7 0.0689 0.0177 0.00718 0.00381 0.00244 0.00179 0.00146 0.00129 63 | 15 10.4 0.0645 0.0156 0.00596 0.003 0.00183 0.00128 0.001 0.000852 64 | 16 11.1 0.0606 0.0138 0.005 0.00239 0.00139 0.000935 0.000702 0.000574 65 | 17 11.8 0.0571 0.0123 0.00423 0.00193 0.00107 0.000692 0.000499 0.000394 66 | 18 12.5 0.054 0.0111 0.00362 0.00158 0.000839 0.000519 0.00036 0.000275 67 | 19 13.2 0.0513 0.00998 0.00312 0.0013 0.000663 0.000394 0.000264 0.000194 68 | 20 13.9 0.0488 0.00906 0.0027 0.00108 0.00053 0.000303 0.000196 0.00014 69 | 21 14.6 0.0465 0.00825 0.00236 0.000905 0.000427 0.000236 0.000147 0.000101 70 | 71 | * as we can see: 72 | * to reach 1% positive rate, you can set k=8, m 10 times larger than n. 73 | * to reach 0.1% positive rate, set k=8, m 15 times larger than n. 74 | * 75 | * k-->num of hash functions 76 | * m--> bit set size 77 | * n--> problem set size 78 | */ 79 | BloomFilter(uint32_t m, uint32_t n):m_bitset(m) 80 | { 81 | assert(m>n); 82 | m_bits=m; 83 | m_probset=n; 84 | 85 | for(uint32_t i=0;i 6 | * _| 7 | * 8 | * BUBBLE SORT 9 | * 10 | * Bubble sort, sometimes incorrectly referred to as sinking sort, is a simple 11 | * sorting algorithm that works by repeatedly stepping through the list to be 12 | * sorted, comparing each pair of adjacent items and swapping them if they are 13 | * in the wrong order. The pass through the list is repeated until no swaps are 14 | * needed, which indicates that the list is sorted. The algorithm gets its name 15 | * from the way smaller elements "bubble" to the top of the list. Because it 16 | * only uses comparisons to operate on elements, it is a comparison sort. 17 | * Although the algorithm is simple, most of the other sorting algorithms are 18 | * more efficient for large lists. 19 | * 20 | * http://en.wikipedia.org/wiki/Bubble_sort 21 | ******************************************************************************/ 22 | 23 | #ifndef _BUBBLE_SORT_H_ 24 | #define _BUBBLE_SORT_H_ 25 | 26 | #include 27 | #include 28 | 29 | namespace alg { 30 | template 31 | static void BubbleSort(T list[], int start, int end){ 32 | int i; 33 | bool swapped; 34 | 35 | assert(start < end); 36 | 37 | do { 38 | swapped = false; 39 | for(i = start+1; i <= end; i++) { 40 | if(list[i-1] > list[i]) { 41 | // swap them and remember something changed 42 | swap(list[i-1], list[i]); 43 | swapped = true; 44 | } 45 | } 46 | } while(swapped); 47 | } 48 | } 49 | 50 | 51 | #endif // _BUBBLE_SORT_H_ 52 | -------------------------------------------------------------------------------- /include/dijkstra.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * DIJKSTRA ALGORITHM 9 | * 10 | * Features: 11 | * 12 | * Dijkstra's algorithm, conceived by Dutch computer scientist Edsger Dijkstra 13 | * in 1956 and published in 1959,[1][2] is a graph search algorithm that 14 | * solves the single-source shortest path problem for a graph with nonnegative 15 | * edge path costs, producing a shortest path tree. This algorithm is often 16 | * used in routing and as a subroutine in other graph algorithms. 17 | * 18 | * http://en.wikipedia.org/wiki/Dijkstra's_algorithm 19 | * 20 | ******************************************************************************/ 21 | 22 | #ifndef ALGO_DIJKSTRA_H__ 23 | #define ALGO_DIJKSTRA_H__ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "heap.h" 32 | #include "directed_graph.h" 33 | #include "stack.h" 34 | #include "hash_table.h" 35 | 36 | namespace alg { 37 | class Dijkstra { 38 | public: 39 | static const int UNDEFINED = -1; 40 | static const int LARGE_NUMBER = 999999; 41 | // run dijkstra algorithm, and return the previous table 42 | static HashTable * run(const Graph & g, uint32_t src_id) { 43 | // a binary heap 44 | Heap Q(g.vertex_count() + g.edge_count()); 45 | // distance hash table 46 | HashTable dist(g.vertex_count()); 47 | // previous vertex hash table 48 | HashTable * previous = new HashTable(g.vertex_count()); 49 | // record whether the vertex is visited 50 | HashTable visited(g.vertex_count()); 51 | 52 | // all vertices 53 | Graph::Adjacent * a; 54 | list_for_each_entry(a, &g.list(), a_node){ 55 | dist[a->v.id] = LARGE_NUMBER; // set initial distance to each vertex to a large number 56 | (*previous)[a->v.id] = UNDEFINED; // clear path to UNDEFINED 57 | visited[a->v.id] = false; // all vertices are not visited 58 | Q.push(LARGE_NUMBER, a->v.id); // push all vertices to heap 59 | } 60 | 61 | // source vertex, the first vertex in Heap-Q 62 | dist[src_id] = 0; 63 | // decrease-key the source vertex to 0 64 | Q.decrease_key(src_id,0); 65 | 66 | while(!Q.is_empty()) { // for every un-visited vertex, try relaxing the path 67 | Heap::elem e = Q.pop(); 68 | uint32_t id = e.data; 69 | if (visited[id]) { // ignore visited vertex 70 | continue; 71 | } 72 | 73 | Graph::Adjacent * u = g[id]; // the vertex to process 74 | int dist_u = dist[id]; // current known shortest distance to u 75 | visited[id] = true; // mark the vertex as visited. 76 | 77 | Graph::Vertex * v; 78 | list_for_each_entry(v, &u->v_head, v_node){ 79 | uint32_t alt = dist_u + v->weight; 80 | if (alt < dist[v->id]) { 81 | dist[v->id] = alt; 82 | (*previous)[v->id] = id; 83 | Q.decrease_key(v->id, alt); // decrease-key 84 | } 85 | } 86 | } 87 | 88 | return previous; 89 | }; 90 | }; 91 | } 92 | 93 | #endif // 94 | -------------------------------------------------------------------------------- /include/directed_graph.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * DIRECTED GRAPH 9 | * 10 | * Features: 11 | * 1. Adjacency List Implementation 12 | * 13 | * http://en.wikipedia.org/wiki/Directed_graph 14 | * 15 | ******************************************************************************/ 16 | 17 | #ifndef ALGO_DIRECTED_GRAPH_H__ 18 | #define ALGO_DIRECTED_GRAPH_H__ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "graph_defs.h" 27 | #include "double_linked_list.h" 28 | 29 | namespace alg { 30 | class DirectedGraph:public Graph { 31 | private: 32 | /** 33 | * delete a vertex from adjacent lists 34 | */ 35 | void delete_me(uint32_t id) { 36 | // delete every connection, iterator through every adjacent list 37 | Adjacent * adj; 38 | list_for_each_entry(adj, &a_head, a_node){ 39 | if (adj->v.id != id) { 40 | if((*adj)[id]!=NULL) { // if connected to id 41 | adj->delete_vertex(id); 42 | num_edges--; 43 | } 44 | } 45 | } 46 | } 47 | public: 48 | /** 49 | * randomly generate a graph, for test purpose 50 | */ 51 | static DirectedGraph * randgraph(int nvertex) { 52 | DirectedGraph * g = new DirectedGraph; 53 | int i; 54 | 55 | for(i=0;iadd_vertex(i); 57 | } 58 | 59 | // random connect 60 | for(i=0;iadd_edge(i, j, w); 68 | } 69 | } 70 | } 71 | return g; 72 | } 73 | 74 | public: 75 | /** 76 | * delete a vertex with specified id 77 | */ 78 | void delete_vertex(uint32_t id) { 79 | Adjacent * a = (*this)[id]; 80 | if (a==NULL) return; 81 | delete_me(id); 82 | // delete adjacent list itself. 83 | num_vertex--; 84 | num_edges -= a->num_neigh; 85 | list_del(&a->a_node); 86 | delete a; 87 | } 88 | 89 | /** 90 | * create a new vertex and add to the graph, with specified id. 91 | */ 92 | bool add_vertex(uint32_t id) { 93 | if ((*this)[id]!=NULL) return false; 94 | 95 | // new empty adjacent list 96 | Adjacent * a = new Adjacent(id); 97 | list_add_tail(&a->a_node, &a_head); 98 | num_vertex++; 99 | 100 | return true; 101 | } 102 | 103 | /** 104 | * add an edge for x -> y 105 | */ 106 | bool add_edge(uint32_t x, uint32_t y, int32_t weight) { 107 | struct Adjacent * a1 = (*this)[x]; 108 | struct Adjacent * a2 = (*this)[y]; 109 | 110 | // make sure both vertex exists & not connected from x->y 111 | if (a1==NULL || a2==NULL) return false; 112 | if (is_adjacent(a1, a2)) return false; 113 | 114 | // create new vertex & add to adjacent list 115 | Vertex * n = new Vertex(y); 116 | n->weight = weight; 117 | list_add_tail(&n->v_node, &a1->v_head); 118 | 119 | num_edges++; 120 | a1->num_neigh++; 121 | 122 | return true; 123 | } 124 | 125 | /** 126 | * delete an edge for x -> y 127 | */ 128 | void delete_edge(uint32_t x, uint32_t y) { 129 | struct Adjacent * a1 = (*this)[x]; 130 | struct Adjacent * a2 = (*this)[y]; 131 | if (a1==NULL || a2==NULL) return ; 132 | if (!is_adjacent(a1, a2)) return ; 133 | 134 | Vertex * v, *n; 135 | // find y in adjacent list of x 136 | list_for_each_entry_safe(v, n, &a1->v_head, v_node){ 137 | if (v->id == y) { 138 | list_del(&v->v_node); 139 | delete v; 140 | num_edges--; 141 | a1->num_neigh--; 142 | } 143 | } 144 | } 145 | 146 | /** 147 | * create the transpose of a directed-graph 148 | */ 149 | DirectedGraph * transpose() { 150 | DirectedGraph * trans = new DirectedGraph; 151 | Adjacent * a; 152 | list_for_each_entry(a, &a_head, a_node){ 153 | trans->add_vertex(a->v.id); 154 | Vertex * v; 155 | list_for_each_entry(v, &a->v_head, v_node){ 156 | trans->add_vertex(v->id); 157 | trans->add_edge(v->id, a->v.id, v->weight); 158 | } 159 | } 160 | 161 | return trans; 162 | } 163 | }; 164 | } 165 | 166 | #endif // 167 | -------------------------------------------------------------------------------- /include/disjoint-set.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * Disjoint-set data structure 9 | * 10 | * In computing, a disjoint-set data structure is a data structure that keeps 11 | * track of a set of elements partitioned into a number of disjoint (nonoverlapping) 12 | * subsets. A union-find algorithm is an algorithm that performs two useful 13 | * operations on such a data structure: 14 | * Find: Determine which subset a particular element is in. This can be used 15 | * for determining if two elements are in the same subset. 16 | * Union: Join two subsets into a single subset. 17 | * 18 | * http://en.wikipedia.org/wiki/Disjoint-set_data_structure 19 | ******************************************************************************/ 20 | 21 | #ifndef ALGO_DISJOINTSET_H__ 22 | #define ALGO_DISJOINTSET_H__ 23 | 24 | namespace alg { 25 | template 26 | struct Set{ 27 | Set* parent; 28 | int rank; 29 | }; 30 | 31 | template 32 | void MakeSet(T *s){ 33 | s->parent = s; 34 | s->rank = 0; 35 | } 36 | 37 | template 38 | void Union(T *x, T *y) { 39 | Link(FindSet(x), FindSet(y)); 40 | } 41 | 42 | template 43 | void Link(T *x, T *y) { 44 | if (x->rank > y->rank) { 45 | y->parent = x; 46 | } else { 47 | x->parent = y; 48 | if (x->rank == y->rank) { 49 | y->rank +=1; 50 | } 51 | } 52 | } 53 | 54 | template 55 | T* FindSet(T *x) { 56 | if (x != x->parent) { 57 | x->parent = FindSet(x->parent); 58 | } 59 | 60 | return x->parent; 61 | } 62 | } 63 | 64 | #endif // 65 | -------------------------------------------------------------------------------- /include/edmonds_karp.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * EDMONS-KARP ALGORITM 9 | * 10 | * Features: 11 | * In computer science and graph theory, the Edmonds–Karp algorithm is an 12 | * implementation of the Ford–Fulkerson method for computing the maximum flow in 13 | * a flow network in O(V E2) time. It is asymptotically slower than the 14 | * relabel-to-front algorithm, which runs in O(V3) time, but it is often faster 15 | * in practice for sparse graphs. The algorithm was first published by Yefim 16 | * (Chaim) Dinic in 1970[1] and independently published by Jack Edmonds and 17 | * Richard Karp in 1972.[2] Dinic's algorithm includes additional techniques 18 | * that reduce the running time to O(V2E). 19 | * 20 | * http://en.wikipedia.org/wiki/Edmonds–Karp_algorithm 21 | * 22 | ******************************************************************************/ 23 | 24 | #ifndef ALGO_EDMONDS_KARP_H__ 25 | #define ALGO_EDMONDS_KARP_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "directed_graph.h" 32 | #include "hash_table.h" 33 | #include "queue.h" 34 | #include "2darray.h" 35 | 36 | namespace alg { 37 | /** 38 | * Edmonds Karp maximal flow class 39 | */ 40 | class EdmondsKarp { 41 | private: 42 | const Graph & g; 43 | Array2D m_residual; // residual network , 2d array 44 | HashTable m_pre; // pre node of current node 45 | bool * m_visits; // mark whether current node is visited 46 | 47 | HashTable m_map; // vertex id to ordinary row/col number mapping 48 | HashTable m_rmap; // reverse mapping of map. 49 | 50 | public: 51 | EdmondsKarp(const Graph & graph): g(graph), 52 | m_residual(g.vertex_count(), g.vertex_count()), 53 | m_pre(g.vertex_count()), 54 | m_map(g.vertex_count()), m_rmap(g.vertex_count()) { 55 | m_visits = new bool[g.vertex_count()]; 56 | // map vertex ids to ordinal row/col number, and reverse mapping. 57 | // for residual network, using sequential order 58 | Graph::Adjacent * a; 59 | int id=0; 60 | list_for_each_entry(a, &g.list(), a_node){ 61 | m_map[a->v.id] = id; 62 | m_rmap[id] = a->v.id; 63 | id++; 64 | } 65 | 66 | // init residual network 67 | m_residual.clear(0); 68 | 69 | list_for_each_entry(a, &g.list(), a_node){ 70 | Graph::Vertex * v; 71 | list_for_each_entry(v, &a->v_head, v_node){ 72 | int from = m_map[a->v.id]; 73 | int to = m_map[v->id]; 74 | m_residual(from, to) = v->weight; 75 | } 76 | } 77 | } 78 | 79 | ~EdmondsKarp() { 80 | delete [] m_visits; 81 | } 82 | 83 | /** 84 | * edmonds karp algorithm for maximal flow 85 | * returns the maxflow from src to sink 86 | */ 87 | uint32_t run(int32_t src, int32_t sink) { 88 | // find augument path repeatedly. 89 | int32_t _src = m_map[src]; 90 | int32_t _sink = m_map[sink]; 91 | 92 | uint32_t maxflow = 0; 93 | 94 | while(find_path(_src, _sink)) { 95 | int delta = INT_MAX; 96 | 97 | // find minimal delta 98 | int i; 99 | for (i=_sink;i!=_src;i= m_pre[i]) { 100 | delta = Min(delta, m_residual(m_pre[i],i)); 101 | } 102 | 103 | // for each edge, change residual network 104 | for (i=_sink; i!=_src;i= m_pre[i]) { 105 | m_residual(m_pre[i],i) -= delta; 106 | m_residual(i,m_pre[i]) += delta; 107 | } 108 | 109 | maxflow += delta; 110 | } 111 | 112 | return maxflow; 113 | } 114 | 115 | inline const Array2D & residual() const { return m_residual;} 116 | inline const HashTable & map() const { return m_map;} 117 | inline const HashTable & rmap() const { return m_rmap;} 118 | 119 | private: 120 | /** 121 | * find a augument path. using breadth first search 122 | */ 123 | bool find_path(int32_t _src, int32_t _sink) { 124 | Queue Q(g.vertex_count()); 125 | 126 | // clear visit flag & path 127 | memset(m_visits, false, sizeof(bool) * g.vertex_count()); 128 | 129 | // src setting 130 | m_pre[_src] = _src; 131 | m_visits[_src] = true; 132 | Q.enqueue(_src); 133 | 134 | while(!Q.is_empty()) { 135 | int p = Q.front(); 136 | Q.dequeue(); 137 | 138 | for (uint32_t i=0;i< g.vertex_count();i++) { 139 | if (m_residual(p,i) >0 && !m_visits[i]) { 140 | m_pre[i] = p; 141 | m_visits[i] = true; 142 | 143 | if (i==uint32_t(_sink)) { // nice, we've got to sink point. 144 | return true; 145 | } 146 | Q.enqueue(i); 147 | } 148 | } 149 | } 150 | 151 | return false; 152 | } 153 | }; 154 | } 155 | 156 | #endif // 157 | -------------------------------------------------------------------------------- /include/fenwick_tree.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Fenwick Tree 3 | * 4 | * Data structure providing prefix sums and modify the table in O(log n) - n is the size o the table. 5 | * 6 | * In this algorithm we use two functions: 7 | * - RSQ - This function calculates the range sum query in O(log n) 8 | * - Update - This function adjusts the values in the given range in O(log n) 9 | * 10 | * https://en.wikipedia.org/wiki/Fenwick_tree 11 | * 12 | * @author Gabriel Duarte (gabriellagoa10@yahoo.com.br) 13 | * @github Gabriel123Duarte 14 | * 15 | ******************************************************************************/ 16 | 17 | #ifndef ALGO_FENWICK_H__ 18 | #define ALGO_FENWICK_H__ 19 | 20 | #include 21 | 22 | #define LSONE(x) (x & (-x)) 23 | 24 | class Fenwick 25 | { 26 | private: 27 | // Vector representing the table 28 | std::vector fen; 29 | public: 30 | Fenwick() {} 31 | 32 | // We don't use the index 0, because it is the base case 33 | Fenwick(int n) 34 | { 35 | fen.assign(n + 1, 0); 36 | } 37 | 38 | // Calculate the 39 | int rsq(int a) 40 | { 41 | int ans = 0; 42 | for(; a; a -= LSONE(a)) 43 | ans += fen[a]; 44 | return ans; 45 | } 46 | 47 | // RSQ a..b 48 | inline int rsq(int a, int b) 49 | { 50 | return rsq(b) - (a == 1 ? 0 : rsq(a - 1)); 51 | } 52 | 53 | // Update the value of the k-th element by x 54 | void update(int k, int x) 55 | { 56 | for(; k < (int)fen.size(); k += LSONE(k)) 57 | fen[k] += x; 58 | } 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /include/generic.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * GENERIC METHODS FOR ALGORITHMS 9 | * 10 | ******************************************************************************/ 11 | 12 | #ifndef ALGO_ALG_INC_H__ 13 | #define ALGO_ALG_INC_H__ 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "utils/gb18030.h" 20 | #include "utils/byteorder.h" 21 | 22 | 23 | #define Max(a, b) ( (a > b) ? a : b ) 24 | #define Min(a, b) ( (a < b) ? a : b ) 25 | 26 | #define RANDOM_INIT() srand(time(NULL)) 27 | #define RANDOM(L, R) (L + rand() % ((R) - (L) + 1)) // gen a random integer in [L, R] 28 | 29 | namespace alg { 30 | /** 31 | * swap 2-element, orignal value 32 | */ 33 | template 34 | static inline void swap(T &x, T &y) 35 | { 36 | T _t(x); 37 | x = y; 38 | y = _t; 39 | } 40 | 41 | /** 42 | * print all of the elements in `list` with size `n` 43 | */ 44 | template 45 | static void printlist(T & list,int count) { 46 | int i; 47 | for(i=0;i 57 | static uint32_t remove_dup(T a[], uint32_t len) { 58 | uint32_t i; 59 | uint32_t newlen = len; 60 | for (i=0; iv_node); 49 | delete v; 50 | } 51 | } 52 | 53 | const Vertex & vertex() const { return v;} 54 | 55 | void delete_vertex(uint32_t id) { 56 | Vertex * v, *vn; 57 | list_for_each_entry_safe(v, vn, &v_head, v_node){ 58 | if (v->id == id ) { 59 | list_del(&v->v_node); 60 | num_neigh--; 61 | delete v; 62 | break; 63 | } 64 | } 65 | } 66 | 67 | /** 68 | * get the Vertex from an adjacent list, according to vertex id 69 | */ 70 | Vertex * operator[] (uint32_t id) const { 71 | Vertex * v; 72 | list_for_each_entry(v, &v_head, v_node){ 73 | if (v->id == id) { 74 | return v; 75 | } 76 | } 77 | return NULL; 78 | } 79 | }; 80 | 81 | protected: 82 | uint32_t num_vertex; 83 | uint32_t num_edges; 84 | struct list_head a_head; // list header 85 | public: 86 | int32_t graph_tick; // for counting discover & finish time 87 | 88 | Graph() { 89 | num_vertex = 0; 90 | num_edges = 0; 91 | INIT_LIST_HEAD(&a_head); 92 | } 93 | 94 | virtual ~Graph() { 95 | Adjacent * a, *an; 96 | list_for_each_entry_safe(a, an, &a_head, a_node){ 97 | list_del(&a->a_node); 98 | delete a; 99 | } 100 | } 101 | private: 102 | Graph(const Graph &); 103 | Graph& operator=(const Graph &); 104 | public: 105 | uint32_t vertex_count() const { return num_vertex; } 106 | uint32_t edge_count() const { return num_edges; } 107 | /** 108 | * find an adjacent list with vertex id == id 109 | */ 110 | Adjacent * operator[] (uint32_t id) const { 111 | Adjacent * a; 112 | list_for_each_entry(a, &a_head, a_node){ 113 | if (a->v.id == id) { return a;} 114 | } 115 | 116 | return NULL; 117 | } 118 | 119 | /** 120 | * print a graph 121 | */ 122 | void print() const { 123 | Adjacent * a; 124 | printf("Graph : %d vertex, %d edges\n", num_vertex,num_edges); 125 | list_for_each_entry(a, &a_head, a_node){ 126 | printf("%d(neigh:%d)->{", a->v.id, a->num_neigh); 127 | Vertex * v; 128 | list_for_each_entry(v, &a->v_head, v_node){ 129 | printf("%d(w:%d)\t", v->id, v->weight); 130 | } 131 | printf("}\n"); 132 | } 133 | } 134 | 135 | /** 136 | * print a graph as graphviz '.dot' format 137 | */ 138 | void printdot() const { 139 | Adjacent * a; 140 | printf("==== BEGIN OF DOT ====\n"); 141 | printf("digraph G {\n"); 142 | printf("\tnode [shape = circle];\n"); 143 | list_for_each_entry(a, &a_head, a_node){ 144 | Vertex * v; 145 | switch (a->color) { 146 | case GRAY: 147 | printf("\t%d [style=filled fillcolor=gray];\n", a->v.id); 148 | break; 149 | case BLACK: 150 | printf("\t%d [style=filled fillcolor=black fontcolor=white];\n", a->v.id); 151 | break; 152 | default: 153 | printf("\t%d;\n", a->v.id); 154 | } 155 | 156 | list_for_each_entry(v, &a->v_head, v_node){ 157 | printf("\t%d -> %d [label = \"%d\"];\n", a->v.id, v->id, v->weight); 158 | } 159 | } 160 | printf("}\n"); 161 | printf("==== END OF DOT ====\n"); 162 | } 163 | 164 | const list_head & list() const {return a_head; } 165 | 166 | // Interface 167 | virtual bool add_vertex(uint32_t id) = 0; 168 | virtual void delete_vertex(uint32_t id) = 0; 169 | virtual bool add_edge(uint32_t x, uint32_t y, int32_t weight) = 0; 170 | virtual void delete_edge(uint32_t x, uint32_t y) = 0; 171 | 172 | protected: 173 | /** 174 | * test if an edge exists 175 | */ 176 | bool is_adjacent(const struct Adjacent * from, const struct Adjacent * to) { 177 | struct Vertex * v; 178 | list_for_each_entry(v, &from->v_head, v_node){ 179 | if (v->id == to->v.id ) { return true; } 180 | } 181 | return false; 182 | } 183 | }; 184 | } 185 | 186 | #endif // 187 | -------------------------------------------------------------------------------- /include/graph_search.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * BREADTH FIRST SEARCH 9 | * 10 | * Features: 11 | * In graph theory, breadth-first search (BFS) is a strategy for searching in 12 | * a graph when search is limited to essentially two operations: 13 | * (a) visit and inspect a node of a graph; 14 | * (b) gain access to visit the nodes that neighbor the currently visited node. 15 | * The BFS begins at a root node and inspects all the neighboring nodes. Then 16 | * for each of those neighbor nodes in turn, it inspects their neighbor nodes 17 | * which were unvisited, and so on. Compare it with the depth-first search. 18 | * 19 | * http://en.wikipedia.org/wiki/Breadth-first_search 20 | * 21 | ******************************************************************************/ 22 | 23 | #ifndef ALGO_BREADTH_FIRST_SEARCH_H__ 24 | #define ALGO_BREADTH_FIRST_SEARCH_H__ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include "queue.h" 31 | #include "stack.h" 32 | #include "directed_graph.h" 33 | #include "hash_table.h" 34 | 35 | namespace alg { 36 | /** 37 | * BREADTH FIRST SEARCH 38 | */ 39 | static void BFS(const Graph & g, int32_t src_id) { 40 | // mark all vertex color to WHITE 41 | Graph::Adjacent * a; 42 | list_for_each_entry(a, &g.list(), a_node) { 43 | a->color = Graph::WHITE; 44 | a->d = INT_MAX; 45 | } 46 | 47 | Graph::Adjacent * s = g[src_id]; 48 | s->d = 0; 49 | Queue Q(g.vertex_count()); 50 | Q.enqueue(s->v.id); 51 | 52 | while(!Q.is_empty()) { 53 | uint32_t id = Q.front(); 54 | printf("%d->", id); // output discovered id 55 | Q.dequeue(); 56 | Graph::Vertex * _v; 57 | Graph::Adjacent * u = g[id]; 58 | list_for_each_entry(_v, &u->v_head, v_node) { 59 | Graph::Adjacent * v = g[_v->id]; // retrive the original adjacent list 60 | if (v->color == Graph::WHITE) { // to change node color 61 | v->color = Graph::GRAY; 62 | v->d = u->d + 1; 63 | Q.enqueue(v->v.id); 64 | } 65 | } 66 | u->color = Graph::BLACK; 67 | } 68 | printf("\n"); 69 | } 70 | 71 | static void _DFS_VISIT(Graph &g, Graph::Adjacent * u); 72 | /** 73 | * DEPTH FIRST SEARCH 74 | */ 75 | static void DFS(Graph & g) { 76 | // mark all vertex color to WHITE 77 | Graph::Adjacent * a; 78 | list_for_each_entry(a, &g.list(), a_node) { 79 | a->color = Graph::WHITE; 80 | } 81 | 82 | // for each vertex 83 | g.graph_tick = 0; 84 | list_for_each_entry(a, &g.list(), a_node) { 85 | if (a->color == Graph::WHITE) { 86 | printf("DFS from : %d\t",a->v.id); 87 | _DFS_VISIT(g, a); 88 | printf("\n"); 89 | } 90 | } 91 | printf("\n"); 92 | } 93 | 94 | /** 95 | * recursivly visit (Call Stack) 96 | */ 97 | static void _DFS_VISIT(Graph &g, Graph::Adjacent * u) { 98 | // white vertex u has just benn discovered 99 | u->d = ++g.graph_tick; 100 | u->color = Graph::GRAY; 101 | 102 | Graph::Vertex * _v; 103 | list_for_each_entry(_v, &u->v_head, v_node) { // explore edge (u, v) 104 | Graph::Adjacent * v = g[_v->id]; // retrive the original adjacent list 105 | if (v->color == Graph::WHITE) { 106 | _DFS_VISIT(g, v); 107 | } 108 | } 109 | u->color = Graph::BLACK; 110 | u->f = ++g.graph_tick; 111 | printf("%d(d:%d, f:%d) -> ", u->v.id, u->d, u->f); 112 | } 113 | } 114 | 115 | #endif // 116 | -------------------------------------------------------------------------------- /include/hash_code.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGO_HASH_CODE_H__ 2 | #define ALGO_HASH_CODE_H__ 3 | #include 4 | #include "hash_string.h" 5 | namespace alg { 6 | /** 7 | * default compare funcs 8 | */ 9 | template 10 | struct hash_code { 11 | uint32_t operator()(T) { 12 | printf("must provide a hash function for _Key\n"); 13 | return 0; 14 | } 15 | }; 16 | 17 | template<> 18 | struct hash_code { 19 | uint32_t operator()(const char* value) { 20 | return hash_fnv1a(value, strlen(value)); 21 | } 22 | }; 23 | 24 | template<> 25 | struct hash_code { 26 | uint32_t operator()(uint32_t value) { 27 | return value; 28 | } 29 | }; 30 | 31 | template<> 32 | struct hash_code { 33 | uint32_t operator()(int32_t value) { 34 | return (uint32_t)value; 35 | } 36 | }; 37 | } 38 | #endif // 39 | -------------------------------------------------------------------------------- /include/hash_multi.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * HASH BY MULTIPLICATION 9 | * 10 | * Features: 11 | * 1. h(k) = (A*k mod 2^w) >> (w-r) 12 | * 2. bucket size(m): 2^r, eg, m = 8 = 2^3 13 | * 3. w: word size (usually 32-bit) 14 | * 4. the value of A is chosen between 2^(w-r) and 2^w odd number. 15 | * 16 | ******************************************************************************/ 17 | 18 | #ifndef ALGO_HASH_MULTIPLICATION_H__ 19 | #define ALGO_HASH_MULTIPLICATION_H__ 20 | 21 | #include 22 | #include 23 | #include "generic.h" 24 | #include "prime.h" 25 | 26 | namespace alg { 27 | struct MultiHash { 28 | uint64_t A; 29 | uint32_t r; // prime, init your hash table with size -> r 30 | }; 31 | 32 | static const short BITWIDTH = 32; 33 | static inline uint32_t multi_hash_table_size(const struct MultiHash * ht) { return 1<<(ht->r); } 34 | 35 | /** 36 | * multi_hash. 37 | */ 38 | static inline uint32_t multi_hash(const struct MultiHash * ht, uint32_t key) { 39 | uint32_t hash; 40 | hash = ((ht->A * key)&0xFFFFFFFF)>>(BITWIDTH-ht->r); //mod 2^w equals logic bitmask ops 41 | return hash; 42 | } 43 | 44 | #ifdef _MSC_VER 45 | #define log2(x) (log(x) / log(2.0)) 46 | #endif 47 | 48 | /** 49 | * init a hash table with size specified. 50 | */ 51 | static MultiHash * multi_hash_init(uint32_t size) { 52 | // find prime larger than log2(size) 53 | uint32_t r = ceil(log2((double)size)); 54 | int i; 55 | for (i = r; ;i++) { 56 | if (is_prime(i)) { 57 | r = i; 58 | break; 59 | } 60 | } 61 | 62 | MultiHash * ht = new MultiHash; 63 | uint32_t a = 1 << (BITWIDTH-r); 64 | ht->A = a+1; 65 | ht->r = r; 66 | 67 | return ht; 68 | } 69 | } 70 | #endif // 71 | -------------------------------------------------------------------------------- /include/hash_string.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * STRING HASH FUNCTIONS 9 | * 10 | * 1. http://en.wikipedia.org/wiki/Java_hashCode() 11 | * 2. http://www.isthe.com/chongo/tech/comp/fnv/ 12 | * 13 | ******************************************************************************/ 14 | 15 | #ifndef ALGO_STRING_HASH_H__ 16 | #define ALGO_STRING_HASH_H__ 17 | 18 | #include 19 | 20 | namespace alg { 21 | /** 22 | * hash a string into integer 23 | * using java's hashCode() implementation 24 | */ 25 | static uint32_t hash_string(const char * str, uint32_t len) { 26 | uint32_t hash=0; 27 | uint32_t i; 28 | for (i=0;i 6 | * _| 7 | * 8 | * GENERIC HASH TABLE 9 | * 10 | * Features: 11 | * 1. separate chaining for resolving collisions 12 | * 13 | * http://en.wikipedia.org/wiki/Hash_table 14 | * 15 | ******************************************************************************/ 16 | 17 | #ifndef ALGO_HASH_TABLE_H__ 18 | #define ALGO_HASH_TABLE_H__ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "double_linked_list.h" 25 | #include "hash_code.h" 26 | #include "hash_multi.h" 27 | 28 | namespace alg { 29 | /** 30 | * definition of a hash table. 31 | */ 32 | template > 33 | class HashTable { 34 | typedef _Key key_type; 35 | typedef _Value value_type; 36 | typedef _HashCode hash_code_fn; 37 | private: 38 | /** 39 | * definition of Key-Value pair. 40 | */ 41 | struct HashKV { 42 | key_type key; // 32-bit key 43 | value_type value; // value 44 | struct list_head node; // KV is a list element. 45 | }; 46 | 47 | private: 48 | uint32_t m_size; // the size of the hash table. 49 | struct list_head * m_slots; // all of the slots, each slot is an linked-list 50 | struct MultiHash * m_multi; // the hash function parameter. 51 | 52 | public: 53 | /** 54 | * create a hash table with max size . 55 | */ 56 | HashTable(uint32_t max) { 57 | // init multiplication hash function 58 | m_multi = multi_hash_init(max); 59 | m_size = multi_hash_table_size(m_multi); 60 | m_slots = new list_head[m_size]; 61 | 62 | for (uint32_t i=0; inode); 72 | delete kv; 73 | } 74 | } 75 | 76 | delete m_multi; 77 | delete [] m_slots; 78 | } 79 | private: 80 | HashTable(const HashTable &); 81 | HashTable& operator=(const HashTable &); 82 | public: 83 | 84 | /** 85 | * test if the hash table has the key 86 | */ 87 | bool contains(key_type key) const { 88 | // hash the key using a hash function. 89 | uint32_t hash = multi_hash(m_multi, hash_code_fn()(key)); 90 | 91 | // we iterate through the list. 92 | HashKV * kv; 93 | list_for_each_entry(kv, &m_slots[hash], node){ 94 | if (kv->key == key) { // ok, found in the list. 95 | return true; 96 | } 97 | } 98 | return false; 99 | } 100 | 101 | /** 102 | * delete by key 103 | */ 104 | bool delete_key(key_type key) { 105 | // hash the key using a hash function. 106 | uint32_t hash = multi_hash(m_multi, hash_code_fn()(key)); 107 | 108 | HashKV * kv, *nkv; 109 | list_for_each_entry_safe(kv,nkv,&m_slots[hash], node) { 110 | if (kv->key == key) { 111 | list_del(&kv->node); 112 | delete kv; 113 | return true; 114 | } 115 | } 116 | 117 | return false; 118 | } 119 | 120 | // const version of operator [] 121 | const value_type& operator[] (key_type key) const { 122 | // hash the key using a hash function. 123 | uint32_t hash = multi_hash(m_multi, hash_code_fn()(key)); 124 | 125 | // we iterate through the list. 126 | HashKV * kv; 127 | list_for_each_entry(kv, &m_slots[hash], node){ 128 | if (kv->key == key) { // ok, found in the list. 129 | return kv->value; 130 | } 131 | } 132 | 133 | // reaching here means a new key is given, 134 | // create a new HashKV struct for it. 135 | kv = new HashKV; 136 | kv->key = key; 137 | list_add(&kv->node, &m_slots[hash]); 138 | return kv->value; 139 | } 140 | 141 | /** 142 | * operator [] 143 | */ 144 | value_type& operator[] (key_type key) { 145 | return const_cast(static_cast(*this)[key]); 146 | } 147 | 148 | void clear() { 149 | HashKV * kv, *nkv; 150 | for (uint32_t i=0;inode); 153 | delete kv; 154 | } 155 | } 156 | } 157 | }; 158 | } 159 | 160 | #endif // 161 | -------------------------------------------------------------------------------- /include/imath.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * COMMON MATH OPS 9 | * 10 | ******************************************************************************/ 11 | 12 | #ifndef ALGO_IMATH_H__ 13 | #define ALGO_IMATH_H__ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | namespace alg { 20 | /** 21 | * dot product of given arrays K and A of len, saved in SUM 22 | */ 23 | static uint32_t dot_product(const uint32_t * K, const uint32_t * A, uint32_t len) { 24 | uint32_t i; 25 | uint32_t sum = 0; 26 | for (i=0; i0) { 60 | if (exponent%2 == 1) { 61 | result = (uint64_t(result)*base)%modulus; 62 | } 63 | exponent = exponent >> 1 ; 64 | base = (uint64_t(base)*base) % modulus; 65 | } 66 | return result; 67 | } 68 | 69 | /** 70 | * Count the consecutive zero bits (trailing) on the right linearly 71 | */ 72 | static inline int ZerosR(unsigned int v) { 73 | int c; // output: c will count v's trailing zero bits, 74 | // so if v is 1101000 (base 2), then c will be 3 75 | if (v) 76 | { 77 | v = (v ^ (v - 1)) >> 1; // Set v's trailing 0s to 1s and zero rest 78 | for (c = 0; v; c++) { 79 | v >>= 1; 80 | } 81 | } 82 | else 83 | { 84 | c = CHAR_BIT * sizeof(v); 85 | } 86 | 87 | return c; 88 | } 89 | } 90 | 91 | #endif // 92 | -------------------------------------------------------------------------------- /include/insertion_sort.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * INSERTION SORT 9 | * 10 | * 1. sort array in O(n^2) time. 11 | * 12 | * http://en.wikipedia.org/wiki/Insertion_sort 13 | * 14 | ******************************************************************************/ 15 | 16 | #ifndef ALGO_INSERTION_SORT_H__ 17 | #define ALGO_INSERTION_SORT_H__ 18 | 19 | namespace alg { 20 | /** 21 | * insertion sort an array 22 | */ 23 | template 24 | static void insertion_sort(T *array , int number_of_elements) { 25 | int iter,jter; 26 | for(iter=1;iter=0 && array[jter] > current_element) { 30 | array[jter+1] = array[jter]; 31 | jter--; 32 | } 33 | array[jter+1] = current_element; 34 | } 35 | } 36 | } 37 | 38 | #endif // 39 | -------------------------------------------------------------------------------- /include/kmp.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * KNUTH-MORRIS-PRATT ALGORITHMS 9 | * 10 | * Features: 11 | * Complexity is O(n + k), where n is the target string length, 12 | * and k is the pattern length 13 | * 14 | * http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm 15 | * 16 | ******************************************************************************/ 17 | 18 | #ifndef ALGO_KMP_H__ 19 | #define ALGO_KMP_H__ 20 | #include 21 | 22 | namespace alg { 23 | static void kmp_table(const char *W, int * T, int len); 24 | /** 25 | * S -> the text to be searched 26 | * W -> the word to search 27 | * return the position where W is found S 28 | */ 29 | static int kmp_search(const char * S, const char * W) { 30 | int LEN_S = strlen(S); 31 | int LEN_W = strlen(W); 32 | 33 | int m = 0; 34 | int i = 0; 35 | int T[LEN_W]; 36 | 37 | kmp_table(W,T, LEN_W); 38 | 39 | while (m+i < LEN_S) { 40 | if (W[i] == S[m+i]) { 41 | if (i == LEN_W -1) { 42 | return m; 43 | } 44 | i++; 45 | } else { 46 | m = m+i-T[i]; 47 | if (T[i] > -1) { 48 | i = T[i]; 49 | } else { 50 | i = 0; 51 | } 52 | } 53 | } 54 | return -1; 55 | } 56 | 57 | /** 58 | * build a table for the word to be searched 59 | * eg: 60 | * i 0 1 2 3 4 5 6 61 | * W[i] A B C D A B D 62 | * T[i] -1 0 0 0 0 1 2 63 | */ 64 | static void kmp_table(const char *W, int * T, int len) { 65 | int pos = 2; // the current position we are computing in T 66 | int cnd = 0; // the next character of the current candidate substring 67 | T[0] = -1; 68 | T[1] = 0; 69 | 70 | while (pos < len) { 71 | // first case: the substring continues 72 | if (W[pos-1] == W[cnd]) { 73 | cnd++; 74 | T[pos] = cnd; 75 | pos++; 76 | } else if (cnd >0) { // second case: it doesn't, but we can fall back 77 | cnd = T[cnd]; 78 | } else { // third case: we have run out of candidates. Note cnd = 0 79 | T[pos] = 0; 80 | pos++; 81 | } 82 | } 83 | } 84 | } 85 | 86 | #endif // 87 | -------------------------------------------------------------------------------- /include/lcs.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * LARGEST COMMON SEQUENCE 9 | * 10 | * http://en.wikipedia.org/wiki/Longest_common_subsequence_problem 11 | * 12 | ******************************************************************************/ 13 | 14 | #ifndef ALGO_LCS_H__ 15 | #define ALGO_LCS_H__ 16 | 17 | #include "generic.h" 18 | #include "2darray.h" 19 | #include "stack.h" 20 | 21 | namespace alg { 22 | /** 23 | * calculate Length matrix 24 | * X -- array of size m 25 | * Y -- array of size n 26 | * eg: 27 | 0 1 2 3 4 5 6 7 28 | Ø M Z J A W X U 29 | 0 Ø 0 0 0 0 0 0 0 0 30 | 1 X 0 0 0 0 0 0 1 1 31 | 2 M 0 1 1 1 1 1 1 1 32 | 3 J 0 1 1 2 2 2 2 2 33 | 4 Y 0 1 1 2 2 2 2 2 34 | 5 A 0 1 1 2 3 3 3 3 35 | 6 U 0 1 1 2 3 3 3 4 36 | 7 Z 0 1 2 2 3 3 3 4 37 | */ 38 | template 39 | static Array2D * lcs_length(const T X[], uint32_t m, const T Y[], uint32_t n) { 40 | Array2D & A = *new Array2D(m+1,n+1); 41 | 42 | uint32_t i,j; 43 | 44 | // set initial state 45 | for(i=0; i<=m; i++) { 46 | A(i,0) = 0; 47 | } 48 | 49 | for(j=0; j<=n; j++) { 50 | A(0,j) = 0; 51 | } 52 | 53 | for(i=1;i<=m;i++) { 54 | for(j=1;j<=n;j++) { 55 | if(X[i-1]==Y[j-1]) A(i,j) = A(i-1,j-1) + 1; 56 | else A(i,j) = Max(A(i,j-1), A(i-1,j)); 57 | } 58 | } 59 | 60 | return &A; 61 | }; 62 | 63 | /** 64 | * pass an empty stack, pop out the result in sequential order. 65 | */ 66 | template 67 | static void lcs_backtrack(Stack & S, Array2D & A, 68 | const T X[], const T Y[], 69 | const uint32_t i, uint32_t j) { 70 | if (i==0 || j==0) return; 71 | else if (X[i-1] == Y[j-1]) { 72 | S.push(X[i-1]); 73 | lcs_backtrack(S, A, X, Y, i-1, j-1); 74 | } 75 | else { 76 | if (A(i, j-1) > A(i-1, j)) 77 | lcs_backtrack(S, A, X, Y, i, j-1); 78 | else 79 | lcs_backtrack(S, A, X, Y, i-1, j); 80 | } 81 | } 82 | } 83 | 84 | #endif // 85 | -------------------------------------------------------------------------------- /include/max_subarray.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * MAXIMUM SUBARRAY 9 | * 10 | * In computer science, the maximum subarray problem is the task of finding the 11 | * contiguous subarray within a one-dimensional array of numbers (containing at 12 | * least one positive number) which has the largest sum. For example, for the 13 | * sequence of values −2, 1, −3, 4, −1, 2, 1, −5, 4; the contiguous subarray 14 | * with the largest sum is 4, −1, 2, 1, with sum 6. 15 | * 16 | * The problem was first posed by Ulf Grenander of Brown University in 1977, as 17 | * a simplified model for maximum likelihood estimation of patterns in digitized 18 | * images. A linear time algorithm was found soon afterwards by Jay Kadane of 19 | * Carnegie-Mellon University (Bentley 1984). 20 | * 21 | * http://en.wikipedia.org/wiki/Maximum_subarray_problem 22 | ******************************************************************************/ 23 | 24 | #ifndef MAX_SUBARRAY__ 25 | #define MAX_SUBARRAY__ 26 | 27 | namespace alg { 28 | /** 29 | * To calc the maximum subarray, and return the range. 30 | */ 31 | static void max_subarray(int arr[], int len, int *begin, int *end) { 32 | int i; 33 | int subvalue = arr[0]; 34 | int maxvalue = arr[0]; 35 | *begin = 0; 36 | *end = 0; 37 | int new_begin; 38 | 39 | for (i = 1;i < len;i++) { 40 | if (subvalue > 0) { // positive contribute to the following element 41 | subvalue += arr[i]; 42 | } else { 43 | subvalue = arr[i]; // negative contribute, drop it! 44 | new_begin = i; // then set the new beginning. 45 | } 46 | 47 | if (maxvalue < subvalue) { // if a larger subarray appears, record the range 48 | maxvalue = subvalue; 49 | *begin = new_begin; 50 | *end = i; 51 | } 52 | } 53 | } 54 | } 55 | 56 | #endif // 57 | -------------------------------------------------------------------------------- /include/merge_sort.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * MERGE SORT 9 | * 10 | * Features: 11 | * This is divide and conquer algorithm. This works as follows. 12 | * (1) Divide the input which we have to sort into two parts in the middle. Call it the left part 13 | * and right part. 14 | * Example: Say the input is -10 32 45 -78 91 1 0 -16 then the left part will be 15 | * -10 32 45 -78 and the right part will be 91 1 0 6. 16 | * (2) Sort Each of them separately. Note that here sort does not mean to sort it using some other 17 | * method. We already wrote function to sort it. Use the same. 18 | * (3) Then merge the two sorted parts. 19 | * 20 | * ------------ 21 | * Worst case performance O(n log n) 22 | * Best case performance 23 | * O(n log n) typical, 24 | * O(n) natural variant 25 | * Average case performance O(n log n) 26 | * Worst case space complexity O(n) auxiliary 27 | * ------------ 28 | * 29 | * Merge sort can easily be optmized for parallized computing. 30 | * 31 | * http://en.wikipedia.org/wiki/Merge_sort 32 | * 33 | ******************************************************************************/ 34 | 35 | #ifndef ALGO_MERGE_SORT_H__ 36 | #define ALGO_MERGE_SORT_H__ 37 | 38 | namespace alg { 39 | /** 40 | * Merge functions merges the two sorted parts. Sorted parts will be from [left, mid] and [mid+1, right]. 41 | */ 42 | template 43 | static void merge_(T *array, int left, int mid, int right) { 44 | /*We need a Temporary array to store the new sorted part*/ 45 | T tempArray[right-left+1]; 46 | int pos=0,lpos = left,rpos = mid + 1; 47 | while(lpos <= mid && rpos <= right) { 48 | if(array[lpos] < array[rpos]) { 49 | tempArray[pos++] = array[lpos++]; 50 | } 51 | else { 52 | tempArray[pos++] = array[rpos++]; 53 | } 54 | } 55 | while(lpos <= mid) tempArray[pos++] = array[lpos++]; 56 | while(rpos <= right)tempArray[pos++] = array[rpos++]; 57 | int iter; 58 | /* Copy back the sorted array to the original array */ 59 | for(iter = 0;iter < pos; iter++) { 60 | array[iter+left] = tempArray[iter]; 61 | } 62 | return; 63 | } 64 | 65 | /** 66 | * sort an array from left->right 67 | */ 68 | template 69 | static void merge_sort(T *array, int left, int right) { 70 | int mid = (left+right)/2; 71 | /* We have to sort only when left 6 | * _| 7 | * 8 | * PALINDROMES 9 | * 10 | * WORDS LIKE: 11 | * RACECAR DEED LEVEL PIP 12 | * ROTOR CIVIC POP MADAM 13 | * EYE NUN RADAR TOOT 14 | * 15 | * This program will find the longest part of mirror. 16 | * 17 | * http://en.wikipedia.org/wiki/Palindrome 18 | ******************************************************************************/ 19 | 20 | #ifndef _PALINDROME_H_ 21 | #define _PALINDROME_H_ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | namespace alg { 28 | static void palindrome(const char * S) { 29 | char *R= strdup(S); 30 | int len = strlen(S); 31 | // reverse 32 | for(int i=0;i= 0 && len-i-1-offset >= 0) { 45 | if (S[i-offset] == R[len-i-1-offset]) { 46 | curlen++; 47 | } else { 48 | break; 49 | } 50 | offset++; 51 | } 52 | 53 | if (curlen > maxlen) { 54 | maxlen = curlen; 55 | middle = i; 56 | } 57 | 58 | // try even 59 | while (i-offset>= 0 && len-i-2-offset >= 0) { 60 | if (S[i-offset] == R[len-i-2-offset]) { 61 | curlen++; 62 | } else { 63 | break; 64 | } 65 | offset++; 66 | } 67 | 68 | if (curlen > maxlen) { 69 | maxlen = curlen; 70 | middle = i; 71 | } 72 | } 73 | 74 | printf("str:%s len:%d middle:%d\n",S, maxlen, middle); 75 | free(R); 76 | } 77 | } 78 | 79 | #endif // 80 | -------------------------------------------------------------------------------- /include/perfect_hash.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * PERFECT HASH 9 | * 10 | * http://en.wikipedia.org/wiki/Perfect_hash 11 | * 12 | ******************************************************************************/ 13 | #ifndef ALGO_PERFECT_HASH_H__ 14 | #define ALGO_PERFECT_HASH_H__ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "generic.h" 20 | #include "universal_hash.h" 21 | #include "stack.h" 22 | 23 | namespace alg { 24 | template 25 | class PerfHT { 26 | private: 27 | class PerfHTException: public std::exception { 28 | public: 29 | virtual const char * what() const throw() { 30 | return "key does not exist"; 31 | } 32 | } excp_key; 33 | 34 | // Level-2 Slot definition 35 | struct SlotL2 { 36 | public: 37 | uint32_t cnt; // collison count 38 | uint32_t key; //key 39 | T value; // value 40 | }; 41 | 42 | // Level-1 Slot definition 43 | struct SlotL1 { 44 | public: 45 | uint32_t cnt; // collison count 46 | struct UHash params; // 2nd level 47 | struct SlotL2 * lv2_slots; // level 2 slots 48 | 49 | uint32_t key; // key 50 | T value; // value 51 | 52 | ~SlotL1() { 53 | if (cnt>1) delete [] lv2_slots; 54 | } 55 | }; 56 | 57 | struct SlotL1 * slots; // level 1 slots 58 | struct UHash params; // 1st level 59 | uint32_t num_slots; 60 | public: 61 | PerfHT(uint32_t keys[], uint32_t len) { 62 | // remove duplicate keys 63 | uint32_t newlen = remove_dup(keys, len); 64 | 65 | // 1-level hashing 66 | uhash_init(&this->params, newlen); 67 | 68 | this->slots = new SlotL1[this->params.prime]; 69 | for(uint32_t i=0;iparams.prime;i++) { 70 | this->slots[i].cnt = 0; 71 | } 72 | 73 | for (uint32_t i = 0; i < newlen; i++) { 74 | uint32_t hash = uhash_integer(&this->params, keys[i]); 75 | slots[hash].cnt++; 76 | slots[hash].key = keys[i]; 77 | } 78 | 79 | // 2-level processing 80 | lv2_init(keys, newlen); 81 | }; 82 | 83 | ~PerfHT() { 84 | delete [] slots; 85 | } 86 | private: 87 | PerfHT(const PerfHT&); 88 | PerfHT& operator=(const PerfHT&); 89 | 90 | public: 91 | const T& operator[] (uint32_t key) const throw (PerfHTException) { 92 | uint32_t hash; 93 | hash = uhash_integer(¶ms, key); 94 | if (slots[hash].key == key) { 95 | return slots[hash].value; 96 | } else if (slots[hash].cnt > 1) { // maybe in the 2nd level slot 97 | SlotL1 & slot = slots[hash]; 98 | uint32_t hash2 = uhash_integer(&slot.params, key); 99 | 100 | // 2nd-level available 101 | if (slot.lv2_slots[hash2].key == key) { 102 | return slot.lv2_slots[hash2].value; 103 | } 104 | } 105 | 106 | throw excp_key; 107 | } 108 | 109 | /** 110 | * operator [] 111 | */ 112 | T& operator[] (uint32_t key) throw (PerfHTException) { 113 | return const_cast(static_cast(*this)[key]); 114 | } 115 | 116 | private: 117 | /** 118 | * level-2 hash pre-work 119 | * collect collides for each level-1 slots 120 | */ 121 | void lv2_init(uint32_t keys[], uint32_t len) { 122 | for (uint32_t i = 0; i < params.prime; i++) { 123 | if (slots[i].cnt > 1) { 124 | // stacks for temporary storing keys 125 | Stack collides(len); 126 | 127 | // find collide keys 128 | for(uint32_t j=0;j & collides) { 144 | // init another hash function & 2nd level 145 | uhash_init(&lv1_slot->params, lv1_slot->cnt * lv1_slot->cnt); 146 | SlotL2 * lv2_slots = new SlotL2[lv1_slot->params.prime]; 147 | lv1_slot->lv2_slots = lv2_slots; 148 | 149 | retry: 150 | for(uint32_t i=0;iparams.prime;i++) { 151 | lv2_slots[i].cnt = 0; 152 | } 153 | 154 | // try another hash function 155 | uhash_init(&lv1_slot->params, lv1_slot->cnt * lv1_slot->cnt); 156 | 157 | // check collide 158 | for(uint32_t i=0; iparams, key); 161 | lv2_slots[hash].key = key; 162 | if (++lv2_slots[hash].cnt > 1) { goto retry; } 163 | } 164 | } 165 | }; 166 | } 167 | 168 | #endif // 169 | -------------------------------------------------------------------------------- /include/prim_mst.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * PRIM'S ALGORITHM -- MINIMUM SPANNING TREE 9 | * 10 | * Features: 11 | * 12 | * Prim's algorithm is a greedy algorithm that finds a minimum spanning tree 13 | * for a connected weighted undirected graph. This means it finds a subset of 14 | * the edges that forms a tree that includes every vertex, where the total 15 | * weight of all the edges in the tree is minimized. The algorithm was 16 | * developed in 1930 by Czech mathematician Vojtěch Jarník and later 17 | * independently by computer scientist Robert C. Prim in 1957 and rediscovered 18 | * by Edsger Dijkstra in 1959. Therefore it is also sometimes called the DJP 19 | * algorithm, the Jarník algorithm, or the Prim–Jarník algorithm. 20 | * 21 | * http://en.wikipedia.org/wiki/Prim%27s_algorithm 22 | * 23 | ******************************************************************************/ 24 | 25 | #ifndef ALGO_PRIM_MST_H__ 26 | #define ALGO_PRIM_MST_H__ 27 | 28 | #include 29 | #include 30 | #include "undirected_graph.h" 31 | #include "double_linked_list.h" 32 | #include "heap.h" 33 | #include "hash_table.h" 34 | 35 | namespace alg { 36 | class Prim { 37 | public: 38 | static const int LARGE_NUMBER = 999999; 39 | /** 40 | * Prim's Algorithm. 41 | * 42 | * Input: A non-empty connected weighted graph with vertices V and edges E 43 | * (the weights can be negative). 44 | * 45 | * Initialize: Vnew = {x}, where x is an arbitrary node (starting point) from V, Enew = {} 46 | * 47 | * Repeat until Vnew = V: 48 | * 1. Choose an edge {u, v} with minimal weight such that u is in Vnew and v 49 | * is not (if there are multiple edges with the same weight, any of them may be picked) 50 | * 2. Add v to Vnew, and {u, v} to Enew 51 | * 52 | * Output: Vnew and Enew describe a minimal spanning tree 53 | */ 54 | static Graph * run(const Graph & g, int32_t src_id) { 55 | UndirectedGraph * mst = new UndirectedGraph(); // empty set == Vnew 56 | // weight hash table 57 | HashTable keys(g.vertex_count()); 58 | // previous vertex hash table 59 | HashTable pi(g.vertex_count()); 60 | 61 | // a binary heap 62 | Heap Q(g.vertex_count()); 63 | 64 | // all vertices 65 | Graph::Adjacent * a; 66 | list_for_each_entry(a, &g.list(), a_node){ 67 | Q.push(LARGE_NUMBER, a->v.id); 68 | keys[a->v.id] = LARGE_NUMBER; 69 | } 70 | 71 | Q.decrease_key(src_id, 0); 72 | keys[src_id] = 0; 73 | 74 | while (!Q.is_empty()) { 75 | Heap::elem e = Q.pop(); 76 | uint32_t id = e.data; 77 | Graph::Adjacent * u = g[id]; // the vertex to process 78 | Graph::Vertex * v; 79 | list_for_each_entry(v, &u->v_head, v_node) { 80 | if (Q.contains(v->id) && v->weight < keys[v->id]) { 81 | pi[v->id] = id; 82 | Q.decrease_key(v->id, v->weight); 83 | keys[v->id] = v->weight; 84 | } 85 | } 86 | } 87 | 88 | // create graph 89 | list_for_each_entry(a, &g.list(), a_node){ 90 | mst->add_vertex(a->v.id); 91 | if (pi[a->v.id] != 0) { 92 | mst->add_vertex(pi[a->v.id]); 93 | mst->add_edge(pi[a->v.id], a->v.id, (*a)[pi[a->v.id]]->weight); 94 | } 95 | } 96 | 97 | return mst; 98 | }; 99 | }; 100 | } 101 | 102 | #endif // 103 | -------------------------------------------------------------------------------- /include/prime.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * PRIME TEST FUNCTION 9 | * 10 | * http://en.wikipedia.org/wiki/Primality_test 11 | * http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test 12 | * 13 | ******************************************************************************/ 14 | #ifndef ALGO_PRIME_H__ 15 | #define ALGO_PRIME_H__ 16 | 17 | #include 18 | #include 19 | #include "imath.h" 20 | 21 | namespace alg { 22 | /** 23 | * check whether a given number is a prime number. 24 | * using naive method. 25 | */ 26 | static bool test_prime(unsigned int n) { 27 | switch (n) { 28 | case 0: 29 | case 1: 30 | return false; 31 | case 2: 32 | return true; 33 | } 34 | 35 | if (n%2 == 0) return false; 36 | 37 | unsigned sqrtn = sqrt((double)n); 38 | for (unsigned int i = 3; i <= sqrtn; i+=2) { 39 | if (n % i == 0) { 40 | return false; 41 | } 42 | } 43 | return true; 44 | } 45 | 46 | /** 47 | * http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test 48 | */ 49 | static inline bool miller_rabin_test(unsigned int n) { 50 | switch (n) { 51 | case 0: 52 | case 1: 53 | return false; 54 | case 2: 55 | case 3: 56 | return true; 57 | } 58 | 59 | if (n%2 == 0) return false; 60 | 61 | unsigned s = ZerosR(n-1); 62 | unsigned d = (n-1) >> s; 63 | 64 | // test 3-times 65 | for (int k=0;k<3;k++){ 66 | unsigned a = rand()%(n-4) + 2; 67 | 68 | unsigned x = Exp(a, d, n); 69 | //printf("%u %u %u %u\n", a,d, n,x); 70 | if (x == 1 || x == n - 1) { 71 | continue; 72 | } 73 | 74 | for (unsigned i=1;i<=s-1;i++) { 75 | x = Exp(x, 2, n); 76 | if (x == 1) return false; 77 | if (x == n-1) continue; 78 | } 79 | 80 | return false; 81 | } 82 | 83 | return true; 84 | } 85 | 86 | /** 87 | * mixed implementation 88 | */ 89 | static inline bool is_prime(unsigned int n) { 90 | if (miller_rabin_test(n)) { 91 | return test_prime(n); 92 | } 93 | return false; 94 | } 95 | } 96 | 97 | #endif // 98 | -------------------------------------------------------------------------------- /include/priority_queue.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * PRIORITY QUEUE 9 | * 10 | * Features: 11 | * 1. A queue with prioity implemented in double linked list. 12 | * 2. The queue is in ascending order of priority. 13 | * 14 | * http://en.wikipedia.org/wiki/Priority_queue 15 | * 16 | ******************************************************************************/ 17 | 18 | #ifndef ALGO_PRIORITY_QUEUE_H__ 19 | #define ALGO_PRIORITY_QUEUE_H__ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "double_linked_list.h" 26 | 27 | namespace alg { 28 | /** 29 | * definition of a Priority Queue. 30 | */ 31 | template 32 | class PQ { 33 | /** 34 | * definition of a node of priority queue. 35 | */ 36 | struct PQNode { 37 | int priority; 38 | T value; 39 | struct list_head node; 40 | }; 41 | 42 | private: 43 | uint32_t m_count; 44 | struct list_head m_head; 45 | public: 46 | /** 47 | * create an empty priority queue. 48 | */ 49 | PQ() { 50 | m_count = 0; 51 | INIT_LIST_HEAD(&m_head); 52 | } 53 | 54 | ~PQ() { 55 | PQNode * pos, * n; 56 | list_for_each_entry_safe(pos,n, &m_head, node) { 57 | list_del(&pos->node); 58 | delete pos; 59 | } 60 | } 61 | private: 62 | PQ(const PQ&); 63 | PQ& operator=(const PQ&); 64 | public: 65 | 66 | /** 67 | * queue a value with priority into the priority queue. 68 | */ 69 | void queue(const T &value, uint32_t priority) { 70 | PQNode * n = new PQNode; 71 | n->priority = priority; 72 | n->value = value; 73 | 74 | if (list_empty(&m_head)) { // empty list, just add in. 75 | list_add(&n->node, &m_head); 76 | m_count++; 77 | } else { 78 | // sequentially find the appropriate position 79 | PQNode * pos; 80 | bool found = false; 81 | list_for_each_entry(pos, &m_head, node) { 82 | if (n->priority <= pos->priority) { 83 | list_add_(&n->node, pos->node.prev, &pos->node); 84 | m_count++; 85 | found = true; 86 | break; 87 | } 88 | } 89 | 90 | if (!found) { // we reach the end of the list. 91 | list_add_tail(&n->node, &m_head); 92 | m_count++; 93 | } 94 | } 95 | } 96 | 97 | /** 98 | * return top element 99 | * check is_empty() before top(). 100 | */ 101 | inline const T & top(int * prio) const { 102 | PQNode * n; 103 | n = list_entry(m_head.next, PQNode, node); 104 | *prio = n->priority; 105 | return n->value; 106 | } 107 | 108 | /** 109 | * dequeue the most priority element, i.e. the first element. 110 | */ 111 | inline void dequeue() { 112 | if (list_empty(&m_head)) return; 113 | 114 | PQNode * n; 115 | n = list_entry(m_head.next, PQNode, node); 116 | list_del(&n->node); 117 | m_count--; 118 | delete n; 119 | } 120 | 121 | /** 122 | * test whether the priority queue is empty 123 | */ 124 | inline bool is_empty() const { 125 | if (list_empty(&m_head)) return true; 126 | return false; 127 | } 128 | 129 | /** 130 | * get the exact number of data 131 | */ 132 | inline uint32_t count() const { return m_count; } 133 | }; 134 | } 135 | 136 | #endif // 137 | -------------------------------------------------------------------------------- /include/queue.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * QUEUE 8 | * 9 | * Features: 10 | * 1. Queue with capcity 11 | * 12 | * http://en.wikipedia.org/wiki/Queue_(data_structure) 13 | * 14 | ******************************************************************************/ 15 | 16 | #ifndef ALGO_QUEUE_H__ 17 | #define ALGO_QUEUE_H__ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace alg { 24 | /** 25 | * Queue Definition 26 | */ 27 | template 28 | class Queue { 29 | private: 30 | class QueueEmptyException: public std::exception { 31 | public: 32 | virtual const char * what() const throw() { 33 | return "Queue is empty."; 34 | } 35 | } excp_empty; 36 | 37 | private: 38 | uint32_t m_capacity; // queue capacity 39 | uint32_t m_size; // current queue size 40 | uint32_t m_front; // index of the first element 41 | uint32_t m_rear; // index of the last element 42 | T * m_elements; // the elements 43 | 44 | public: 45 | /** 46 | * constructor takes argument the maximum number of elements the Queue 47 | * can hold, creates a Queue according to it and returns a pointer to the 48 | * Queue. 49 | */ 50 | Queue(uint32_t max) { 51 | this->m_elements = new T[max]; 52 | this->m_size = 0; 53 | this->m_capacity = max; 54 | this->m_front =0; 55 | this->m_rear = -1; 56 | }; 57 | 58 | ~Queue() { 59 | delete [] m_elements; 60 | }; 61 | private: 62 | Queue(const Queue &); 63 | Queue& operator=(const Queue &); 64 | public: 65 | /** 66 | * Dequeue 67 | */ 68 | inline void dequeue() { 69 | /* If Queue size is zero then it is empty. So we cannot pop */ 70 | if(m_size==0) { 71 | return; 72 | } 73 | /* Removing an element is equivalent to incrementing index of front by one */ 74 | else { 75 | m_size--; 76 | m_front++; 77 | /* As we fill elements in circular fashion */ 78 | if(m_front==m_capacity) { 79 | m_front=0; 80 | } 81 | } 82 | return; 83 | }; 84 | 85 | /** 86 | * return the front element. 87 | */ 88 | inline const T& front() const { 89 | if (m_size==0) throw excp_empty; 90 | return m_elements[m_front]; 91 | }; 92 | 93 | /** 94 | * test weather the queue is empty 95 | */ 96 | inline bool is_empty() const { 97 | if (m_size ==0) return true; 98 | return false; 99 | }; 100 | 101 | /** 102 | * enqueue an element 103 | * returns false when queue is full 104 | */ 105 | bool enqueue(const T & element) { 106 | // If the Queue is full, we cannot push an element into it 107 | // as there is no space for it.*/ 108 | if(m_size == m_capacity) { 109 | return false; 110 | } 111 | else { 112 | m_size++; 113 | m_rear++; 114 | /* As we fill the queue in circular fashion */ 115 | if(m_rear == m_capacity) { 116 | m_rear = 0; 117 | } 118 | /* Insert the element in its rear side */ 119 | m_elements[m_rear] = element; 120 | 121 | return true; 122 | } 123 | }; 124 | 125 | /** 126 | * return the queue count. 127 | */ 128 | inline uint32_t count() const { return m_size; }; 129 | 130 | /** 131 | * return the queue capacity. 132 | */ 133 | inline uint32_t capcity() const { return m_capacity; }; 134 | }; 135 | } 136 | #endif // 137 | -------------------------------------------------------------------------------- /include/quick_sort.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * QUICKSORT 9 | * 10 | * Features: 11 | * 1. sort array in O(nlogn) time. 12 | * 2. most generic fast sorting algorithm 13 | * 14 | * http://en.wikipedia.org/wiki/Quick_sort 15 | * 16 | ******************************************************************************/ 17 | 18 | #ifndef ALGO_QUICKSORT_H__ 19 | #define ALGO_QUICKSORT_H__ 20 | 21 | #include 22 | 23 | namespace alg { 24 | /** 25 | * the quick-sort partition routine 26 | */ 27 | template 28 | static int partition_(T list[],int begin, int end) { 29 | int pivot_idx = RANDOM(begin,end); 30 | T pivot = list[pivot_idx]; 31 | swap(list[begin], list[pivot_idx]); 32 | 33 | int i = begin + 1; 34 | int j = end; 35 | 36 | while(i <= j) { 37 | while((i <= end) && (list[i] <= pivot)) 38 | i++; 39 | while((j >= begin) && (list[j] > pivot)) 40 | j--; 41 | if(i < j) 42 | swap(list[i],list[j]); 43 | } 44 | 45 | swap(list[begin],list[j]); 46 | return j; // final pivot position 47 | } 48 | 49 | /** 50 | * quick sort an array of range [begin, end] 51 | */ 52 | template 53 | static void quicksort(T list[],int begin,int end) { 54 | if( begin < end) { 55 | int pivot_idx = partition_(list, begin, end); 56 | quicksort(list, begin, pivot_idx-1); 57 | quicksort(list, pivot_idx+1, end); 58 | } 59 | } 60 | } 61 | 62 | #endif // 63 | -------------------------------------------------------------------------------- /include/radix_sort.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * RADIX SORT 9 | * 10 | * Features: 11 | * 1. sort unsigned 32-bit array in O(n) time 12 | * 2. subset sorted with couting sort. 13 | * 14 | * http://en.wikipedia.org/wiki/Radix_sort 15 | * 16 | ******************************************************************************/ 17 | 18 | #ifndef ALGO_RADIX_SORT_H__ 19 | #define ALGO_RADIX_SORT_H__ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace alg { 29 | /** 30 | * couting sort 31 | */ 32 | static void radix_(int byte, const unsigned N, const uint32_t *source, uint32_t *dest) { 33 | unsigned count[256]; 34 | unsigned index[256]; 35 | memset(count, 0, sizeof (count)); 36 | 37 | unsigned i; 38 | for(i=0; i>(byte*8))&0xff]++; 40 | 41 | index[0]=0; 42 | for(i=1; i<256; ++i) 43 | index[i] = index[i-1] + count[i-1]; 44 | 45 | for(i=0; i>(byte*8))&0xff]++] = source[i]; 47 | } 48 | 49 | /** 50 | * radix sort a given unsigned 32-bit integer array of size N 51 | */ 52 | static void radix_sort(uint32_t *source, const unsigned N) { 53 | uint32_t * temp = new uint32_t[N]; 54 | radix_(0, N, source, temp); 55 | radix_(1, N, temp, source); 56 | radix_(2, N, source, temp); 57 | radix_(3, N, temp, source); 58 | 59 | delete [] temp; 60 | } 61 | 62 | /** 63 | * check whether the array is in order 64 | */ 65 | static void check_order(const uint32_t *data, unsigned N) { 66 | for(--N ; N > 0; --N, ++data) 67 | assert(data[0] <= data[1]); 68 | } 69 | } 70 | 71 | #endif // 72 | -------------------------------------------------------------------------------- /include/random.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * RANDOM NUMBER GENERATOR 9 | * 10 | * http://en.wikipedia.org/wiki/Pseudorandom_number_generator 11 | * 12 | ******************************************************************************/ 13 | 14 | #ifndef ALGO_RANDOM_H__ 15 | #define ALGO_RANDOM_H__ 16 | 17 | #include 18 | #include 19 | 20 | namespace alg { 21 | /** 22 | * Linear congruential generator 23 | * [0, 4294967295] 24 | */ 25 | static uint32_t LCG() { 26 | static uint32_t a = 1664525U; 27 | static uint32_t c = 1013904223U; 28 | static uint32_t X0 = 0; 29 | 30 | X0 = a*X0+c; 31 | return X0; 32 | } 33 | } 34 | 35 | #endif // 36 | -------------------------------------------------------------------------------- /include/random_select.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * Quickselect 9 | * In computer science, a quickselect is a selection algorithm related to the 10 | * quicksort sorting algorithm. Like quicksort, it was developed by Tony Hoare, 11 | * and thus is also known as Hoare's selection algorithm. Like quicksort, it is 12 | * efficient in practice and has good average-case performance, but has poor 13 | * worst-case performance. Quickselect and variants is the selection algorithm 14 | * most often used in efficient real-world implementations. 15 | * 16 | * http://en.wikipedia.org/wiki/Quickselect 17 | * 18 | ******************************************************************************/ 19 | 20 | #ifndef ALGO_RANDOM_SELECT_H__ 21 | #define ALGO_RANDOM_SELECT_H__ 22 | 23 | #include 24 | 25 | namespace alg { 26 | /** 27 | * the random_select partition routine 28 | */ 29 | template 30 | static int partition_(T list[],int begin, int end) { 31 | int pivot_idx = RANDOM(begin,end); 32 | T pivot = list[pivot_idx]; 33 | swap(list[begin],list[pivot_idx]); 34 | 35 | int i = begin + 1; 36 | int j = end; 37 | 38 | while(i <= j) { 39 | while((i <= end) && (list[i] <= pivot)) 40 | i++; 41 | while((j >= begin) && (list[j] > pivot)) 42 | j--; 43 | if(i < j) 44 | swap(list[i],list[j]); 45 | } 46 | 47 | swap(list[begin],list[j]); 48 | return j; // final pivot position 49 | } 50 | 51 | /** 52 | * select the k-th smallest number in 'list' of range [begin, end] 53 | */ 54 | template 55 | static int random_select(T list[], int begin, int end, int k) { 56 | if(begin == end) 57 | return begin; 58 | 59 | int pivot_idx = partition_(list, begin, end); 60 | int human_idx = pivot_idx - begin + 1; 61 | 62 | if(k < human_idx) 63 | return random_select(list, begin, pivot_idx - 1, k); 64 | else if(k > human_idx) 65 | return random_select(list, pivot_idx+1, end, k - human_idx); 66 | 67 | return pivot_idx; 68 | } 69 | } 70 | 71 | #endif // 72 | -------------------------------------------------------------------------------- /include/scc.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * STRONGLY CONNECTED COMPONENT 9 | * 10 | * In the mathematical theory of directed graphs, a graph is said to be strongly 11 | * connected if every vertex is reachable from every other vertex. The strongly 12 | * connected components of an arbitrary directed graph form a partition into 13 | * subgraphs that are themselves strongly connected. It is possible to test the 14 | * strong connectivity of a graph, or to find its strongly connected components, 15 | * in linear time. 16 | * 17 | * http://en.wikipedia.org/wiki/Strongly_connected_component 18 | ******************************************************************************/ 19 | 20 | #ifndef ALGO_SCC_H__ 21 | #define ALGO_SCC_H__ 22 | #include 23 | #include 24 | #include 25 | #include "graph_defs.h" 26 | #include "graph_search.h" 27 | #include "heap.h" 28 | 29 | namespace alg { 30 | /** 31 | * Output Strongly Connected Component of a Graph 32 | */ 33 | static void SCC(DirectedGraph &g) { 34 | // call DFS(G) to compute finishing times u.f for each vertex u 35 | DFS(g); 36 | // the transpose of the graph 37 | DirectedGraph * GT = g.transpose(); 38 | // step 1. discover vertices of G in decreasing of u.f 39 | Heap Q(g.vertex_count()) ; 40 | Graph::Adjacent * a; 41 | list_for_each_entry(a, &g.list(), a_node) { 42 | Q.push(INT_MAX - a->f, a->v.id); // descending order of a->f 43 | } 44 | 45 | // step 2. discover 46 | // mark all vertex color to WHITE 47 | list_for_each_entry(a, >->list(), a_node) { 48 | a->color = Graph::WHITE; 49 | } 50 | 51 | // step 3. call DFS(GT), but in the main loop of DFS, consider the vertices 52 | // in order of decreasing u.f (as computed in line 1) 53 | while(!Q.is_empty()) { 54 | Heap::elem e = Q.pop(); 55 | int32_t key = e.key; 56 | int32_t id = e.data; 57 | if ((*GT)[id]->color == Graph::WHITE) { 58 | printf("component:%d %d\n",id, INT_MAX - key); 59 | _DFS_VISIT(*GT, (*GT)[id]); 60 | printf("\n"); 61 | } 62 | } 63 | delete GT; 64 | } 65 | } 66 | 67 | #endif // 68 | -------------------------------------------------------------------------------- /include/selection_sort.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * SELECTION SORT 9 | * 10 | * In computer science, selection sort is a sorting algorithm, specifically an 11 | * in-place comparison sort. It has O(n2) time complexity, making it inefficient 12 | * on large lists, and generally performs worse than the similar insertion sort. 13 | * Selection sort is noted for its simplicity, and it has performance advantages 14 | * over more complicated algorithms in certain situations, particularly where 15 | * auxiliary memory is limited. 16 | * 17 | * http://en.wikipedia.org/wiki/Selection_sort 18 | ******************************************************************************/ 19 | 20 | #ifndef ALGO_SELECTION_SORT_H__ 21 | #define ALGO_SELECTION_SORT_H__ 22 | 23 | #include 24 | #include 25 | 26 | namespace alg { 27 | template 28 | static void SelectionSort(T list[], int start, int end) { 29 | int i,j; 30 | int iMin; 31 | 32 | assert(start <= end); 33 | 34 | for(j = start; j <= end-1; j++) { 35 | // assume the min is the first element */ 36 | iMin = j; 37 | // test against elements after i to find the smallest 38 | for(i = j+1; i <= end; i++) { 39 | if (list[i] < list[iMin]) { 40 | iMin = i; 41 | } 42 | } 43 | 44 | // iMin is the index of the minimum element. Swap it with the current position 45 | if (iMin != j) { 46 | swap(list[j], list[iMin]); 47 | } 48 | } 49 | } 50 | } 51 | 52 | #endif //ALGO_SELECTION_SORT_H__ 53 | -------------------------------------------------------------------------------- /include/shell_sort.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * SHELL SORT 9 | * 10 | * 1. sort array in O(n^(3/2)) time. 11 | * 12 | * https://en.wikipedia.org/wiki/Shellsort 13 | * 14 | ******************************************************************************/ 15 | 16 | #ifndef ALGO_SHELL_SORT_H__ 17 | #define ALGO_SHELL_SORT_H__ 18 | 19 | namespace alg { 20 | /** 21 | * shell sort an array 22 | */ 23 | template 24 | static void shell_sort(T *array, int len) { 25 | int h = 1; 26 | while (h < len / 3) { 27 | h = 3 * h + 1; // 1, 4, 13, 40, 121, ... 28 | } 29 | while (h >= 1) { 30 | for (int i = h; i < len; i++) { 31 | int cur = array[i]; 32 | int j = i - h; 33 | while (j >= 0 && array[j] > cur) { 34 | array[j + h] = array[j]; 35 | j = j - h; 36 | } 37 | array[j + h] = cur; 38 | } 39 | h = h / 3; 40 | } 41 | } 42 | } 43 | 44 | #endif // 45 | -------------------------------------------------------------------------------- /include/shuffle.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * FISHER YATES'S SHUFFLE 9 | * 10 | * Features: 11 | * 1. shuffle list in O(n) time. 12 | * 13 | * http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle 14 | * 15 | ******************************************************************************/ 16 | 17 | #ifndef ALGO_SHUFFLE_H__ 18 | #define ALGO_SHUFFLE_H__ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace alg { 25 | /** 26 | * shuffle the 'list' of length 'len' 27 | */ 28 | template 29 | static void shuffle(T * list, int len) { 30 | srand(time(NULL)); 31 | int i = len, j; 32 | T temp; 33 | 34 | if ( i == 0 ) return; 35 | while ( --i ) { 36 | j = rand() % (i+1); 37 | temp = list[i]; 38 | list[i] = list[j]; 39 | list[j] = temp; 40 | } 41 | } 42 | } 43 | 44 | #endif // 45 | -------------------------------------------------------------------------------- /include/simhash.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * SIMHASH FUNCTIONS 9 | * 10 | * http://matpalm.com/resemblance/simhash/ 11 | * http://en.wikipedia.org/wiki/Hamming_distance 12 | * 13 | ******************************************************************************/ 14 | 15 | #ifndef ALGO_SIMHASH_H__ 16 | #define ALGO_SIMHASH_H__ 17 | 18 | #include 19 | #include 20 | #include "hash_string.h" 21 | 22 | namespace alg { 23 | class SimHash { 24 | private: 25 | int V[32]; 26 | public: 27 | SimHash() { 28 | memset(V, 0, sizeof(V)); 29 | } 30 | 31 | /** 32 | * hash a single word 33 | */ 34 | void AddWord(const char * word, uint32_t len) { 35 | uint32_t hash = hash_fnv1a(word,len); 36 | for(int i=0;i<32;i++) { 37 | if (hash&(1< 0) { 52 | hash|= (1< 6 | * _| 7 | * 8 | * SELF ORGANIZED LINKED-LIST 9 | * 10 | * Features: 11 | * 1. Implementation of MTF (move-to-front) 12 | * 2. Implementation of MAO (move-ahead-one position) 13 | * 3. Based on double linked list 14 | * 15 | * http://en.wikipedia.org/wiki/Self-organizing_list 16 | * 17 | ******************************************************************************/ 18 | 19 | #ifndef ALGO_SOL_H__ 20 | #define ALGO_SOL_H__ 21 | #include "double_linked_list.h" 22 | 23 | namespace alg { 24 | /** 25 | * Move a node to the front 26 | */ 27 | static inline void list_mtf(struct list_head *entry, struct list_head *head) { 28 | if (entry->prev == head) return; 29 | list_del_(entry->prev, entry->next); 30 | list_add_(entry, head, head->next); 31 | } 32 | 33 | 34 | /** 35 | * Move a node ahead one position 36 | */ 37 | static inline void list_mao(struct list_head *entry, struct list_head * head) { 38 | // if the entry in the 1st position 39 | if (entry->prev == head) return; 40 | struct list_head * prev = entry->prev; 41 | list_del_(entry->prev, entry->next); 42 | list_add_(entry, prev->prev, prev); 43 | } 44 | } 45 | #endif // 46 | -------------------------------------------------------------------------------- /include/stack.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * STACK 9 | * 10 | * Features: 11 | * 1. Stack with capcity 12 | * 13 | * http://en.wikipedia.org/wiki/Stack_(abstract_data_type) 14 | * 15 | ******************************************************************************/ 16 | 17 | #ifndef ALGO_STACK_H__ 18 | #define ALGO_STACK_H__ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace alg { 25 | /** 26 | * Stack has three properties. capacity stands for the maximum number of 27 | * elements stack can hold. Size stands for the current size of the stack and elements 28 | * is the array of elements 29 | */ 30 | template 31 | class Stack { 32 | private: 33 | class StackEmptyException: public std::exception { 34 | public: 35 | virtual const char * what() const throw() 36 | { 37 | return "stack is empty"; 38 | } 39 | } excp_empty; 40 | 41 | class StackIndexOutOfBoundException: public std::exception { 42 | public: 43 | virtual const char * what() const throw() 44 | { 45 | return "Index out of bound."; 46 | } 47 | } excp_ioob; 48 | 49 | uint32_t m_capacity; // the total capacity 50 | uint32_t m_size; // current stack size 51 | T * m_elements; // the elements 52 | 53 | public: 54 | /** 55 | * capcity is the maximum elements the stack can hold. 56 | */ 57 | Stack(uint32_t capacity) { 58 | this->m_capacity = capacity; 59 | this->m_size = 0; 60 | this->m_elements = new T[capacity]; 61 | } 62 | 63 | ~Stack() { 64 | delete [] m_elements; 65 | } 66 | 67 | 68 | private: 69 | Stack(const Stack&); 70 | Stack& operator=(const Stack&); 71 | 72 | 73 | public: 74 | /** 75 | * test whether the stack is empty 76 | */ 77 | inline bool is_empty() const { return m_size==0?true:false; } 78 | 79 | /** 80 | * pop stack 81 | */ 82 | inline void pop() { 83 | if(m_size!=0) m_size--; 84 | return; 85 | } 86 | 87 | /** 88 | * get the top element 89 | */ 90 | inline const T& top() const { 91 | if (m_size==0) throw excp_empty; 92 | return m_elements[m_size-1]; 93 | } 94 | 95 | /** 96 | * push an element into the stack 97 | * returns false when stack is full. 98 | */ 99 | inline bool push(const T & value) { 100 | if(m_size==m_capacity) { return false; } 101 | else { 102 | m_elements[m_size++] = value; 103 | return true; 104 | } 105 | } 106 | 107 | /** 108 | * return the stack size count. 109 | */ 110 | inline uint32_t count() const { return m_size; } 111 | 112 | /** 113 | * return value by index 114 | */ 115 | inline const T& operator[] (uint32_t idx) const { 116 | if (idx >= m_capacity) throw excp_ioob; 117 | return m_elements[m_size-1-idx]; 118 | } 119 | }; 120 | } 121 | 122 | #endif // 123 | -------------------------------------------------------------------------------- /include/suffix_array.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * SUFFIX ARRAY 9 | * 10 | * Features: 11 | * suffix array can sort all the suffixs in time complexity O(n*log^2(n)), 12 | * and use memory in O(n). And suffix array can get two suffixs' longest 13 | * common prefix(lcp) in O(log(n)) complexity. 14 | * 15 | * You can test it by running suffix_array_demo.cpp 16 | * Want to get more detailed information about suffix array? 17 | * 18 | * Please google SUFF_AR_ENG.pdf 19 | * 20 | * AUTHOR: nowerzt@gmail.com 21 | ******************************************************************************/ 22 | 23 | #ifndef ALGO_SUFFIX_ARRAY_H__ 24 | #define ALGO_SUFFIX_ARRAY_H__ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | using namespace std; 33 | 34 | namespace alg { 35 | class SuffixArray { 36 | private: 37 | vector > bucket; 38 | vector suffix; 39 | int N, L, K; 40 | const string& str; 41 | void suffix_sort(); 42 | void update_bucket(); 43 | 44 | bool less_than(int a, int b) { 45 | if(K==0) return str[a]>1)=0 && x 6 | * _| 7 | * 8 | * Trie (Prefix tree) 9 | * 10 | * http://en.wikipedia.org/wiki/Trie 11 | ******************************************************************************/ 12 | 13 | #ifndef ALGO_TRIE_H__ 14 | #define ALGO_TRIE_H__ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace alg { 22 | const int NUMWORD = 26; 23 | class Trie { 24 | private: 25 | class node { 26 | public: 27 | int words; 28 | int prefixes; 29 | node *edges[NUMWORD]; 30 | node():words(0),prefixes(0) { 31 | memset(edges, 0, sizeof(edges)); 32 | } 33 | ~node() { 34 | for (int i=0;iwords++; 86 | } else { 87 | n->prefixes++; 88 | int index=str[0]-'a'; 89 | if (n->edges[index]==NULL) { 90 | n->edges[index] = new node; 91 | } 92 | 93 | _add(n->edges[index], ++str); 94 | } 95 | } 96 | 97 | int _count(node *n, const char * str) { 98 | if (str[0] == '\0') { 99 | return n->words; 100 | } else { 101 | int index=str[0]-'a'; 102 | if (n->edges[index]==NULL) { 103 | return 0; 104 | } 105 | 106 | return _count(n->edges[index], ++str); 107 | } 108 | } 109 | 110 | int _count_prefix(node *n, char * str) { 111 | if (str[0] == '\0') { 112 | return n->prefixes; 113 | } else { 114 | int index=str[0]-'a'; 115 | if (n->edges[index]==NULL) { 116 | return 0; 117 | } 118 | 119 | return _count_prefix(n->edges[index], ++str); 120 | } 121 | } 122 | }; 123 | } 124 | 125 | #endif // 126 | -------------------------------------------------------------------------------- /include/undirected_graph.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * UNDIRECTED GRAPH 9 | * 10 | * Features: 11 | * 1. Adjacency List Implementation 12 | * 13 | * http://en.wikipedia.org/wiki/Undirected_graph 14 | * 15 | ******************************************************************************/ 16 | 17 | #ifndef ALGO_UNDIRECTED_GRAPH_H__ 18 | #define ALGO_UNDIRECTED_GRAPH_H__ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "graph_defs.h" 26 | #include "double_linked_list.h" 27 | 28 | namespace alg { 29 | class UndirectedGraph:public Graph { 30 | private: 31 | /** 32 | * delete a vertex from adjacent lists 33 | */ 34 | void delete_me(Adjacent * a) { 35 | Vertex * v,* vn; 36 | 37 | // for each connected-vertex 38 | list_for_each_entry_safe(v, vn, &a->v_head, v_node){ 39 | Adjacent * neigh = (*this)[v->id]; 40 | neigh->delete_vertex(a->v.id); 41 | num_edges--; 42 | } 43 | } 44 | public: 45 | /** 46 | * create a new vertex and add to the graph, with specified id. 47 | */ 48 | inline bool add_vertex(uint32_t id) { 49 | if ((*this)[id]!=NULL) return false; 50 | 51 | // new empty adjacent list 52 | Adjacent * a = new Adjacent(id); 53 | INIT_LIST_HEAD(&a->v_head); 54 | list_add_tail(&a->a_node, &a_head); 55 | num_vertex++; 56 | 57 | return true; 58 | } 59 | 60 | /** 61 | * delete a vertex with specified id 62 | */ 63 | void delete_vertex(uint32_t id) { 64 | Adjacent * a = (*this)[id]; 65 | if (a==NULL) return; 66 | delete_me(a); 67 | 68 | // delete adjacent list itself. 69 | num_vertex--; 70 | list_del(&a->a_node); 71 | delete a; 72 | } 73 | 74 | /** 75 | * add an edge for x<->y 76 | */ 77 | bool add_edge(uint32_t x, uint32_t y, int32_t weight) { 78 | struct Adjacent * a1 = (*this)[x]; 79 | struct Adjacent * a2 = (*this)[y]; 80 | 81 | if (a1==NULL || a2==NULL) return false; 82 | if (is_adjacent(a1, a2)) return false; 83 | 84 | // create new vertex & add to adjacent list 85 | Vertex * n = new Vertex(y); 86 | n->weight = weight; 87 | list_add_tail(&n->v_node, &a1->v_head); 88 | 89 | n = new Vertex(x); 90 | n->weight = weight; 91 | list_add_tail(&n->v_node, &a2->v_head); 92 | 93 | num_edges++; 94 | a1->num_neigh++; 95 | a2->num_neigh++; 96 | 97 | return true; 98 | } 99 | 100 | /** 101 | * delete an edge for x<->y 102 | */ 103 | void delete_edge(uint32_t x, uint32_t y) { 104 | Adjacent * a1 = (*this)[x]; 105 | Adjacent * a2 = (*this)[y]; 106 | if (a1==NULL || a2==NULL) return ; 107 | if (!is_adjacent(a1, a2)) return ; 108 | 109 | Vertex * v, *n; 110 | // find x->.....y... 111 | list_for_each_entry_safe(v, n, &a1->v_head, v_node){ 112 | if (v->id == y) { 113 | list_del(&v->v_node); 114 | delete(v); 115 | num_edges--; 116 | a1->num_neigh--; 117 | } 118 | } 119 | 120 | // find y->.....x... 121 | list_for_each_entry_safe(v, n, &a2->v_head, v_node){ 122 | if (v->id == x) { 123 | list_del(&v->v_node); 124 | delete(v); 125 | a2->num_neigh--; 126 | } 127 | } 128 | } 129 | /** 130 | * randomly generate a graph, for test purpose 131 | * start from 1 132 | */ 133 | static UndirectedGraph * randgraph(int nvertex) { 134 | UndirectedGraph * g = new UndirectedGraph; 135 | int i; 136 | 137 | for(i=1;i<=nvertex;i++) { 138 | g->add_vertex(i); 139 | } 140 | 141 | // random connect 142 | for(i=1;i<=nvertex;i++) { 143 | int j; 144 | for(j=i+1;jadd_edge(i, j, w); 149 | } 150 | } 151 | } 152 | 153 | 154 | return g; 155 | } 156 | }; 157 | } 158 | 159 | #endif // 160 | -------------------------------------------------------------------------------- /include/universal_hash.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * DANIEL'S ALGORITHM IMPLEMENTAIONS 3 | * 4 | * /\ | _ _ ._ o _|_ |_ ._ _ _ 5 | * /--\ | (_| (_) | | |_ | | | | | _> 6 | * _| 7 | * 8 | * UNIVERSAL HASH FUNCTION 9 | * 10 | * http://en.wikipedia.org/wiki/Universal_hash 11 | * 12 | ******************************************************************************/ 13 | 14 | #ifndef ALGO_UNIVERSAL_HASH_H__ 15 | #define ALGO_UNIVERSAL_HASH_H__ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "prime.h" 25 | #include "imath.h" 26 | #include "random.h" 27 | #include "integer.h" 28 | 29 | namespace alg { 30 | struct UHash { 31 | uint32_t a[KLEN]; 32 | uint32_t prime; 33 | }; 34 | 35 | /** 36 | * init an universal hash struct 37 | */ 38 | static inline void uhash_init(struct UHash * params, uint32_t max_element) { 39 | int i; 40 | // the size of the hash bucket is the prime larger than 2 * max_element 41 | for(i=max_element+1;;i++) { 42 | if (is_prime(i)) { 43 | params->prime = i; 44 | break; 45 | } 46 | } 47 | 48 | for (i = 0; i < KLEN;i++) { 49 | params->a[i] = rand()%params->prime; 50 | } 51 | } 52 | 53 | /** 54 | * hash a key 55 | */ 56 | static inline uint32_t uhash_integer(const struct UHash * params, uint64_t key) { 57 | uint32_t k[KLEN]; 58 | uint32_t sum; 59 | 60 | m_based(key, params->prime, k); 61 | sum = dot_product(k,params->a,KLEN); 62 | return sum%params->prime; 63 | } 64 | 65 | /** 66 | * hash an arbitrary length integer. 67 | * len, number of 32-bit integer, max len is 32 68 | */ 69 | static uint32_t uhash_bigint(const struct UHash * params, uint32_t * key, uint32_t len) { 70 | // TODO : need a better algorithm, or NOT? 71 | return key[0]%params->prime; 72 | } 73 | } 74 | #endif // 75 | -------------------------------------------------------------------------------- /msvc/alg_vs.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGO_ALGVS_H__ 2 | #define ALGO_ALGVS_H__ 3 | #ifdef _MSC_VER 4 | 5 | #define _CRT_SECURE_NO_WARNINGS 6 | 7 | #define __func__ __FUNCTION__ 8 | 9 | #define strtok_r strtok_s 10 | 11 | #if _MSC_VER <= 1800 12 | #define ALG_VLA_NOT_SUPPORTED 13 | #endif 14 | 15 | #define typeof decltype 16 | 17 | #endif//_MSC_VER 18 | #endif//ALGO_ALGVS_H__ -------------------------------------------------------------------------------- /msvc/stdbool.h: -------------------------------------------------------------------------------- 1 | #ifdef _MSC_VER 2 | 3 | #endif -------------------------------------------------------------------------------- /src/8queue_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include <8queen.h> 3 | 4 | int main(void) { 5 | alg::Queen8 q; 6 | q.solve(); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/LRU_cache_demo.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "LRU_cache.h" 4 | 5 | using namespace std; 6 | using namespace alg; 7 | 8 | int main() { 9 | 10 | 11 | LRUCache Cache(5); 12 | Cache.putValue("key1","value1"); 13 | Cache.putValue("key2","value2"); 14 | Cache.putValue("key3","value3"); 15 | Cache.putValue("key4","value4"); 16 | Cache.putValue("key5","value5"); 17 | Cache.putValue("key6","value6"); 18 | 19 | 20 | cout << "Display The LRU Cache...." << endl; 21 | Cache.display(); 22 | 23 | cout << "Now,Visit the LRU Cache with \"key4\"" << endl; 24 | cout << "The \"key4\" Value is : "<< Cache.getValue("key4") << endl; 25 | cout << "The New LRU Cache is ... " << endl; 26 | Cache.display(); 27 | 28 | cout << "Now, Update The LRU Cache with \"key5\" and new value is \"newValue5\" ... " << endl; 29 | Cache.putValue("key5","newValue5"); 30 | cout << "The New LRU Cache is ... " << endl; 31 | Cache.display(); 32 | Cache.getValue("aaa"); 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/astar_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "astar.h" 5 | 6 | #define N 128 7 | 8 | #define MARK 0xEE 9 | 10 | int main(void) 11 | { 12 | using namespace alg; 13 | 14 | Array2D grid(N,N); 15 | grid.clear(0); 16 | srand(time(NULL)); 17 | int i,j; 18 | 19 | for (i=N/4;i<=3*N/4;i++) { 20 | grid(3*N/4,i) = AStar::WALL; 21 | grid(i,3*N/4) = AStar::WALL; 22 | } 23 | 24 | grid(0,0) = 0; 25 | grid(N-1,N-1) = 0; 26 | 27 | printf("search a path from (0,0) to (%d,%d)\n", N-1,N-1); 28 | for (i=0;inum_nodes;i++){ 41 | printf("(%d,%d)\t",as->path[i*2], as->path[i*2+1]); 42 | grid(as->path[i*2],as->path[i*2+1]) = MARK; 43 | } 44 | 45 | printf("\n"); 46 | for (i=0;i 2 | #include "avl.h" 3 | 4 | using namespace std; 5 | using namespace alg; 6 | 7 | const unsigned N = 4096*32; 8 | const unsigned N_ELEMS_TO_REMOVE = N-128; // Must be between 0 and N-1 9 | 10 | template 11 | void printTreeStatus(const AVL &t) { 12 | cout << "----------------------------------------" << endl; 13 | if (t.isEmpty()) cout << "The tree is empty" << endl; 14 | else { 15 | cout << "Tree root is: " << t.root() << endl; 16 | cout << "Tree height is: " << t.height() << endl; 17 | cout << "Tree contains " << t.size() << " elements" << endl; 18 | } 19 | cout << "----------------------------------------" << endl; 20 | } 21 | 22 | int main() 23 | { 24 | int values[N]; 25 | 26 | AVL avl; 27 | 28 | cout << "Populating the tree with " << N << " random values... "; 29 | for (unsigned i = 0; i < N; ++i) { 30 | values[i] = rand(); 31 | avl.insert(values[i]); 32 | } 33 | cout << "Done" << endl; 34 | 35 | printTreeStatus(avl); 36 | 37 | for (unsigned i = 0; i < N; ++i) { 38 | unsigned idx = rand() % N; 39 | if (!avl.contains(values[idx])) 40 | cout << "ERROR: Value " << values[idx] << " was inserted and not found!" << endl; 41 | } 42 | 43 | cout << "Now removing a random element from the tree... "; 44 | unsigned idx = rand() % N; 45 | avl.erase(values[idx]); 46 | cout << "Done" << endl; 47 | 48 | printTreeStatus(avl); 49 | 50 | cout << "Now removing the root of the tree " << N_ELEMS_TO_REMOVE << " times... "; 51 | for (unsigned i = 0; i < N_ELEMS_TO_REMOVE; ++i) { 52 | avl.erase(avl.root()); 53 | } 54 | cout << "Done" << endl; 55 | 56 | printTreeStatus(avl); 57 | 58 | // Outputting to cerr so the output can be redirected with ./avl_demo 2> .gvz 59 | cout << "Do you want to output the GraphViz representation of the tree to the cerr stream (Y/n)? "; 60 | char usrInput; 61 | cin >> usrInput; 62 | if (usrInput == 'Y' || usrInput == 'y') avl.toGraphViz(cerr, "AVL"); 63 | 64 | return 0; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /src/base64_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "base64.h" 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() { 8 | const char *s = "Matthew 7:24-27 Therefore everyone who hears these words of mine and puts them into practice is like a wise man who built his house on the rock. 25 The rain came down, the streams rose, and the winds blew and beat against that house; yet it did not fall, because it had its foundation on the rock. 26 But everyone who hears these words of mine and does not put them into practice is like a foolish man who built his house on sand. 27 The rain came down, the streams rose, and the winds blew and beat against that house, and it fell with a great crash."; 9 | cout << " INPUT: " << endl; 10 | cout << s << endl << endl; 11 | 12 | string base=alg::CBase64::encodeBase64((unsigned char *) s, strlen(s)); 13 | cout << " encodeBase64: " << endl; 14 | cout << base << endl << endl; 15 | 16 | cout << " decodeBase64: " << endl; 17 | cout << alg::CBase64::decodeBase64(base) << endl; 18 | } 19 | -------------------------------------------------------------------------------- /src/bellman_ford_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "directed_graph.h" 8 | #include "bellman_ford.h" 9 | 10 | using namespace alg; 11 | int main(void) 12 | { 13 | srand(time(NULL)); 14 | int NVERTEX = 10; 15 | DirectedGraph * g = DirectedGraph::randgraph(NVERTEX); 16 | g->printdot(); 17 | 18 | BellmanFord bf(*g); 19 | 20 | printf("finding bellman-ford shortest path starting from 3: \n"); 21 | std::auto_ptr > previous(bf.run(3)); 22 | 23 | Graph::Adjacent * a; 24 | list_for_each_entry(a, &g->list(), a_node) { 25 | printf("previous of %u is ", a->v.id); 26 | if ((*previous)[a->v.id]==UNDEFINED) { printf("UNDEFINED\n"); } 27 | else printf("%u\n", (*previous)[a->v.id]); 28 | } 29 | printf("\nwe %s have negative weighted cycle.\n", bf.has_negative_cycle()?"DO":"DON'T"); 30 | 31 | printf("\nconstructing a negative cycle and run again\n"); 32 | 33 | // construct a negative cycle; 34 | g->add_vertex(100); 35 | g->add_vertex(101); 36 | g->add_vertex(102); 37 | g->add_edge(100,101, -1); 38 | g->add_edge(101,102, -1); 39 | g->add_edge(102,100, -1); 40 | 41 | BellmanFord bf2(*g); 42 | std::auto_ptr > previous2(bf2.run(0)); 43 | 44 | g->printdot(); 45 | printf("\nwe %s have negative weighted cycle.\n", bf2.has_negative_cycle()?"DO":"DON'T"); 46 | 47 | delete g; 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /src/binary_search_tree_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "shuffle.h" 6 | #include "binary_search_tree.h" 7 | 8 | using namespace alg; 9 | int main() 10 | { 11 | const int MAX_ELEMENTS = 10; 12 | int key[MAX_ELEMENTS]; 13 | int value[MAX_ELEMENTS]; 14 | 15 | BST t; 16 | 17 | int i = 0; 18 | srand(time(NULL)); 19 | // generate random numbers and fill them to the list 20 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 21 | key[i] = rand()%100; 22 | value[i] = rand()%1000; 23 | } 24 | 25 | for(i = 0; i < MAX_ELEMENTS; i++){ 26 | printf("insert %d->%d\n",key[i], value[i]); 27 | t.insert(key[i], value[i]); 28 | } 29 | 30 | t.print_helper(); 31 | 32 | for(i = 0; i < MAX_ELEMENTS; i++){ 33 | printf("getting %d->%d\n",key[i], t.find(key[i])->value); 34 | } 35 | 36 | for(i = 0; i < MAX_ELEMENTS; i++){ 37 | t.deleteKey(key[i]); 38 | t.print_helper(); 39 | printf("deleted %d\n\n", key[i]); 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /src/bitset_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "bitset.h" 4 | 5 | using namespace alg; 6 | int main(void) 7 | { 8 | int MAXELEMENT = 100; 9 | 10 | BitSet bs(MAXELEMENT); 11 | 12 | int i; 13 | printf("\nsetting bits: \n"); 14 | for (i=0;i < MAXELEMENT;i++) { 15 | int v = rand()%2; 16 | if (v==0) { 17 | bs.set(i); 18 | printf("1"); 19 | } 20 | else printf("0"); 21 | } 22 | 23 | printf("\ntesting bits: \n"); 24 | for (i=0;i< MAXELEMENT;i++) { 25 | printf("%d", bs.test(i)?1:0); 26 | } 27 | printf("\nunsetting bits: \n"); 28 | for (i=0;i< MAXELEMENT;i++) { 29 | int v = rand()%5; 30 | if (v==0) { 31 | bs.unset(i); 32 | printf("0"); 33 | } 34 | else printf("1"); 35 | } 36 | 37 | printf("\ntesting bits: \n"); 38 | for (i=0;i< MAXELEMENT;i++) { 39 | printf("%d", bs.test(i)?1:0); 40 | } 41 | printf("\n"); 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /src/bloom_filter_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "bloom_filter.h" 4 | 5 | int main(void) 6 | { 7 | using namespace alg; 8 | const char * strs[] = { 9 | "purple_lover_04@msn.com", 10 | "hollie.smith@yahoo.com", 11 | "hollister.susan @gmail.com", 12 | "alexptre@gmail.com", 13 | "cfo@sjtu-edp.cn", 14 | "abms@n23h22.rev.sprintdatacenter.pl", 15 | "admin@facebook.com", 16 | "xtaci@163.com" 17 | }; 18 | 19 | const char * strs2[] = { 20 | "admin@facebook.com", 21 | "xtaci@163.com" 22 | }; 23 | 24 | uint32_t len = sizeof(strs)/sizeof(char*); 25 | BloomFilter<8> bf(len*10, len); 26 | 27 | for (uint32_t i=0;i%s\n", strs2[i], bf.test(strs2[i])?"true":"false"); 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /src/btree_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "btree.h" 3 | 4 | using namespace alg; 5 | int main(void) { 6 | BTree x("./btree.dat"); 7 | int32_t i; 8 | 9 | for (i=0;i<1000;i++) { 10 | x.Insert(i); 11 | printf("insert %d\n", i); 12 | BTree::Res r = x.Search(i); 13 | if (r.idx == -1) { 14 | printf("key[%d] insert failed\n", i); 15 | } 16 | } 17 | 18 | for (i=0;i<1000;i++) { 19 | x.DeleteKey(i); 20 | BTree::Res r = x.Search(i); 21 | if (r.idx == -1) { 22 | printf("key[%d] removed\n", i); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/bubble_sort_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "generic.h" 6 | #include "bubble_sort.h" 7 | 8 | using namespace alg; 9 | int main (int argc, char const *argv[]) { 10 | const int MAX_ELEMENTS = 10; 11 | int list[MAX_ELEMENTS]; 12 | for(int i = 0; i < MAX_ELEMENTS; i++ ){ 13 | list[i] = rand()%100; 14 | } 15 | printf("The list before sorting is:\n"); 16 | printlist(list,MAX_ELEMENTS); 17 | 18 | alg::BubbleSort(list,0,MAX_ELEMENTS-1); 19 | 20 | printf("The list after sorting using bubble-sort algorithm:\n"); 21 | printlist(list,MAX_ELEMENTS); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /src/dict.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollon282/-Algorithm-/6e89ffd2197a151b8c790b74d5b34996ff57b6a1/src/dict.txt -------------------------------------------------------------------------------- /src/dict.txt.sogou: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollon282/-Algorithm-/6e89ffd2197a151b8c790b74d5b34996ff57b6a1/src/dict.txt.sogou -------------------------------------------------------------------------------- /src/dictionary_demo.cpp: -------------------------------------------------------------------------------- 1 | #include "dictionary.h" 2 | #include "hash_table.h" 3 | #include "random.h" 4 | #include 5 | 6 | using namespace alg; 7 | using namespace std::chrono; 8 | 9 | int main(void) { 10 | 11 | Dictionary dict; 12 | 13 | dict.Add(0, 1); 14 | dict.Add(1, 2); 15 | dict.Add(5, 2); 16 | dict.Add(3, 3); 17 | dict.Remove(5); 18 | dict.AddOrUpdate(3, 4); 19 | 20 | for (auto x : dict) 21 | { 22 | printf("%d - %d\n", x.Key, x.Value); 23 | } 24 | 25 | static const uint32_t TEST_LENGTH = 1000000; 26 | Dictionary d(TEST_LENGTH); 27 | HashTable h(TEST_LENGTH); 28 | 29 | auto t0 = high_resolution_clock::now(); 30 | 31 | for (uint32_t i = 0; i < TEST_LENGTH; i++) 32 | { 33 | d.AddOrUpdate(alg::LCG(), alg::LCG()); 34 | } 35 | 36 | auto t1 = high_resolution_clock::now(); 37 | 38 | for (uint32_t i = 0; i < TEST_LENGTH; i++) 39 | { 40 | h[alg::LCG()] = alg::LCG(); 41 | } 42 | 43 | auto t2 = high_resolution_clock::now(); 44 | 45 | auto dt0 = duration_cast(t1 - t0).count(); 46 | auto dt1 = duration_cast(t2 - t1).count(); 47 | 48 | printf("Dictionary: %lld ms, HashTable: %lld ms\n", dt0, dt1); 49 | } 50 | -------------------------------------------------------------------------------- /src/dijkstra_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "directed_graph.h" 8 | #include "dijkstra.h" 9 | 10 | using namespace alg; 11 | 12 | int main(void) 13 | { 14 | using namespace alg; 15 | srand(time(NULL)); 16 | int NVERTEX = 10; 17 | std::auto_ptr g(DirectedGraph::randgraph(NVERTEX)); 18 | g->printdot(); 19 | 20 | Graph::Adjacent * a; 21 | printf("finding Dijkstra shortest path starting from 1: \n"); 22 | HashTable * result = Dijkstra::run(*g, 1); 23 | 24 | list_for_each_entry(a, &g->list(), a_node){ 25 | printf("previous of %u is ", a->v.id); 26 | int32_t pre = (*result)[a->v.id]; 27 | if (pre == Dijkstra::UNDEFINED) { printf("UNDEFINED\n"); } 28 | else printf("%d\n", pre); 29 | } 30 | delete result; 31 | 32 | printf("finding Dijkstra shortest path starting from 2: \n"); 33 | 34 | result = Dijkstra::run(*g, 2); 35 | list_for_each_entry(a, &g->list(), a_node){ 36 | printf("previous of %u is ", a->v.id); 37 | int32_t pre = (*result)[a->v.id]; 38 | if (pre == Dijkstra::UNDEFINED) { printf("UNDEFINED\n"); } 39 | else printf("%d\n", pre); 40 | } 41 | delete result; 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /src/directed_graph_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "directed_graph.h" 6 | 7 | using namespace alg; 8 | int main() 9 | { 10 | srand(time(NULL)); 11 | int NVERTEX = 20; 12 | DirectedGraph * g = DirectedGraph::randgraph(NVERTEX); 13 | g->printdot(); 14 | 15 | printf("Random Delete Vertex:\n"); 16 | // random delete vertex 17 | int i; 18 | for(i=0;idelete_vertex(n); 22 | } 23 | 24 | g->printdot(); 25 | printf("Delete All Edges: \n"); 26 | 27 | for(i=0;idelete_edge(i, j); 31 | } 32 | } 33 | 34 | g->printdot(); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/disjoint-set_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) { 6 | alg::Set s1; 7 | alg::Set s2; 8 | alg::MakeSet(&s1); 9 | alg::MakeSet(&s2); 10 | 11 | printf("before:\n"); 12 | std::cout<< alg::FindSet(&s1) << std::endl; 13 | std::cout<< alg::FindSet(&s2) << std::endl; 14 | 15 | printf("after:\n"); 16 | alg::Union(&s1, &s2); 17 | std::cout<< alg::FindSet(&s1) << std::endl; 18 | std::cout<< alg::FindSet(&s2) << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /src/dos_tree_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include /* rand() */ 5 | #include "dos_tree.h" 6 | 7 | using namespace alg; 8 | int main(void) 9 | { 10 | DosTree t; 11 | t.print(); 12 | 13 | srand(time(NULL)); 14 | int MAXELEMENT = 50; 15 | int i; 16 | for(i=0; ikey); 27 | } 28 | 29 | t.print(); 30 | 31 | printf("deleteing %d smallest elements\n", MAXELEMENT/2); 32 | for(i=0; ikey); 43 | } 44 | 45 | t.print(); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /src/double_linked_list_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "double_linked_list.h" 5 | #include "sol.h" 6 | 7 | using namespace alg; 8 | 9 | struct DemoNode{ 10 | int key; 11 | struct list_head list; 12 | }; 13 | 14 | int main() 15 | { 16 | struct list_head head, head2; 17 | INIT_LIST_HEAD(&head); 18 | INIT_LIST_HEAD(&head2); 19 | 20 | printf("list_add[head#1]:\n"); 21 | int i; 22 | struct DemoNode * node; 23 | 24 | for(i = 0; i< 10; i++) { 25 | node = (struct DemoNode *)malloc(sizeof(struct DemoNode)); 26 | node->key = i; 27 | list_add(&node->list, &head); 28 | printf("%d\n", i); 29 | } 30 | 31 | 32 | printf("list_add[head#2]:\n"); 33 | for(i = 10; i< 20; i++) { 34 | node = (struct DemoNode *)malloc(sizeof(struct DemoNode)); 35 | node->key = i; 36 | list_add(&node->list, &head2); 37 | printf("%d\n", i); 38 | } 39 | 40 | // iterate 41 | printf("list_for_each:\n"); 42 | struct list_head *pos; 43 | list_for_each(pos, &head){ 44 | struct DemoNode * node = list_entry(pos, struct DemoNode, list); 45 | printf("%d\n", node->key); 46 | } 47 | 48 | printf("list_for_each_prev:\n"); 49 | list_for_each_prev(pos, &head){ 50 | struct DemoNode * node = list_entry(pos, struct DemoNode, list); 51 | printf("%d\n", node->key); 52 | } 53 | 54 | printf("list_for_each_entry:\n"); 55 | list_for_each_entry(node, &head, list){ 56 | printf("%d\n", node->key); 57 | } 58 | 59 | // mtf & mao 60 | printf("list_mtf: move the 2nd element to 1st pos:\n"); 61 | list_mtf(head.next->next, &head); // 2nd element 62 | list_for_each_entry(node, &head, list){ 63 | printf("%d\n", node->key); 64 | } 65 | 66 | printf("list_mao: move ahead the 3rd element one pos:\n"); 67 | list_mao(head.next->next->next, &head); // 3rd element 68 | list_for_each_entry(node, &head, list){ 69 | printf("%d\n", node->key); 70 | } 71 | 72 | // move 73 | printf("list_move: move an element to another list\n"); 74 | list_move(head.next, &head2); 75 | printf("head#1:\n"); 76 | list_for_each_entry(node, &head, list){ 77 | printf("%d\n", node->key); 78 | } 79 | 80 | printf("head#2:\n"); 81 | list_for_each_entry(node, &head2, list){ 82 | printf("%d\n", node->key); 83 | } 84 | 85 | //splice 86 | printf("list_splice:\n"); 87 | list_splice_init(&head, &head2); 88 | list_for_each_entry(node, &head2, list){ 89 | printf("%d\n", node->key); 90 | } 91 | 92 | // delete all nodes 93 | printf("list_for_each_entry_safe to delete everything:\n"); 94 | struct DemoNode * n; 95 | list_for_each_entry_safe(node, n, &head, list){ 96 | list_del(&node->list); 97 | printf("freeing %d\n", node->key); 98 | free(node); 99 | } 100 | 101 | list_for_each_entry_safe(node, n, &head2, list){ 102 | list_del(&node->list); 103 | printf("freeing %d\n", node->key); 104 | free(node); 105 | } 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /src/edmonds_karp_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "edmonds_karp.h" 6 | using namespace alg; 7 | int main(void) 8 | { 9 | using namespace alg; 10 | srand(time(NULL)); 11 | int NVERTEX = 6; 12 | DirectedGraph * g = DirectedGraph::randgraph(NVERTEX); 13 | g->printdot(); 14 | 15 | printf("finding Maximal Flow from 0 to 5: \n"); 16 | EdmondsKarp ek(*g); 17 | uint32_t maxflow = ek.run(0,5); 18 | 19 | printf("Max Flow is %d\n", maxflow); 20 | printf("the residual network\n"); 21 | printf("\t"); 22 | for(uint32_t i=0;ivertex_count();i++) { 23 | printf("%d\t", ek.rmap()[i]); 24 | } 25 | printf("\n"); 26 | 27 | for(uint32_t i=0;ivertex_count();i++) { 28 | printf("%d\t",ek.rmap()[i]); 29 | for(uint32_t j=0;jvertex_count();j++) { 30 | printf("%d\t", ek.residual()(i,j)); 31 | } 32 | printf("\n"); 33 | } 34 | 35 | delete g; 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /src/fenwick_tree_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fenwick_tree.h" 3 | 4 | int main() 5 | { 6 | Fenwick ft(5); 7 | 8 | ft.update(2, 1); 9 | ft.update(4, 10); 10 | 11 | printf("%d\n", ft.rsq(1)); 12 | 13 | ft.update(1, 5); 14 | printf("%d\n", ft.rsq(1)); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /src/fib-heap_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "fib-heap.h" 5 | 6 | int main(void) { 7 | srand(time(NULL)); 8 | alg::FibHeap heap; 9 | int32_t i; 10 | for (i=0;i<10;i++) { 11 | heap.Insert(rand(), i); 12 | } 13 | 14 | for (i=0;i<10;i++) { 15 | alg::FibHeap::Node n; 16 | n = heap.ExtractMin(); 17 | if (n!= NULL) { 18 | printf("%d %d\n", n->key, n->value); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/graph_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "undirected_graph.h" 6 | 7 | /** 8 | * randomly generate a graph, for test purpose 9 | */ 10 | struct Graph * undirected_graph_rand(int nvertex) 11 | { 12 | struct Graph * g = undirected_graph_create(); 13 | int i; 14 | 15 | for(i=0;i 2 | #include 3 | #include 4 | 5 | #include "graph_search.h" 6 | #include "directed_graph.h" 7 | 8 | using namespace alg; 9 | 10 | int main() 11 | { 12 | using namespace alg; 13 | srand(time(NULL)); 14 | int NVERTEX = 10; 15 | Graph * g = DirectedGraph::randgraph(NVERTEX); 16 | g->printdot(); 17 | 18 | printf("breadth first search: \n"); 19 | BFS(*g, 0); 20 | printf("depth first search: \n"); 21 | DFS(*g); 22 | 23 | delete g; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /src/hash_multi_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "hash_multi.h" 7 | using namespace alg; 8 | int main() 9 | { 10 | const int MAX_ELEMENTS = 50; 11 | srand(time(NULL)); 12 | 13 | struct MultiHash * ht = multi_hash_init(MAX_ELEMENTS); 14 | 15 | printf("required space for storage is %d\n", multi_hash_table_size(ht)); 16 | 17 | int i; 18 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 19 | uint32_t key = rand()%1000; 20 | printf("hash %d --> %d\n", key, multi_hash(ht, key) ); 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /src/hash_string_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "hash_string.h" 6 | using namespace alg; 7 | int main(void) 8 | { 9 | const char * strs[] = { 10 | "", 11 | "a", 12 | "foobar", 13 | "first string", 14 | "second string", 15 | "third string", 16 | "this is the fourth string", 17 | "and finally this is the fifth string" 18 | }; 19 | 20 | printf("using java hash\n"); 21 | for (uint32_t i=0;i %x\n", strs[i], hash_string(strs[i], strlen(strs[i]))); 23 | } 24 | 25 | printf("using FNV hash\n"); 26 | for (uint32_t i=0;i %x\n", strs[i], hash_fnv1a(strs[i], strlen(strs[i]))); 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /src/hash_table_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "hash_table.h" 7 | using namespace alg; 8 | int main() 9 | { 10 | const int MAX_ELEMENTS = 50; 11 | srand(time(NULL)); 12 | 13 | HashTable ht(MAX_ELEMENTS); 14 | 15 | printf("Hash Table Demo: \n"); 16 | int i; 17 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 18 | int32_t value = rand()%1000; 19 | ht[i] = value; 20 | printf("setting %d->%d\n", i, value); 21 | } 22 | 23 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 24 | printf("getting %d->%d\n", i, ht[i]); 25 | } 26 | 27 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 28 | printf("deleting %d\n", ht.delete_key(i)); 29 | } 30 | 31 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 32 | printf("testing %d->%s\n", i, ht.contains(i)?"true":"false"); 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/heap_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "heap.h" 5 | 6 | int main() 7 | { 8 | using namespace alg; 9 | int MAXELEMENTS=10; 10 | Heap heap(MAXELEMENTS); 11 | 12 | int i; 13 | srand(time(NULL)); 14 | for (i=0;i < MAXELEMENTS; i++) { 15 | heap.push(100-i, i); 16 | printf("push: key:%d->value:%d\n", 100-i, i); 17 | } 18 | heap.print_heap(); 19 | 20 | for (i=0;i::elem e = heap.pop(); 28 | printf("pop: key:%d->value:%d\n", e.key, e.data); 29 | } 30 | heap.print_heap(); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /src/huffman_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "huffman.h" 5 | #define STR "Huffman coding uses a specific method for choosing the representation for each symbol, resulting in a prefix code (sometimes called 'prefix-free codes', that is, the bit string representing some particular symbol is never a prefix of the bit string representing any other symbol) that expresses the most common source symbols using shorter strings of bits than are used for less common source symbols. Huffman was able to design the most efficient compression method of this type: no other mapping of individual source symbols to unique strings of bits will produce a smaller average output size when the actual symbol frequencies agree with those used to create the code." 6 | 7 | int main(void) 8 | { 9 | using namespace alg; 10 | HuffTree tree(STR); 11 | 12 | char codes[strlen(STR)]; 13 | uint32_t length; 14 | 15 | printf("encoding message: \n%s\n", STR); 16 | 17 | printf("<<< before huffman coding : length:%lu bytes\n", strlen(STR)); 18 | memset(codes, 0, sizeof(codes)); 19 | length = tree.encode(STR, codes); 20 | 21 | printf(">>> after huffman coding : length:%u bytes\n", length/8); 22 | printf("decoding messsage:\n"); 23 | tree.decode(codes, length); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/imath_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "imath.h" 4 | 5 | int main() { 6 | for (int i=10000;i<10100;i++) { 7 | for (int j=100000;j<100010;j++) { 8 | printf("%d^%d mod %d = %d\n", i,j,997, alg::Exp(i, j, 997)); 9 | } 10 | } 11 | 12 | unsigned int n = 104; 13 | printf("%x has %d zeros on the right side\n", n, alg::ZerosR(n)); 14 | } 15 | -------------------------------------------------------------------------------- /src/insertion_sort_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "generic.h" 6 | #include "insertion_sort.h" 7 | 8 | using namespace alg; 9 | 10 | int main() 11 | { 12 | const int MAX_ELEMENTS = 10; 13 | int list[MAX_ELEMENTS]; 14 | 15 | int i = 0; 16 | 17 | srand(time(NULL)); 18 | // generate random numbers and fill them to the list 19 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 20 | list[i] = rand()%100; 21 | } 22 | printf("The list before sorting is:\n"); 23 | printlist(list,MAX_ELEMENTS); 24 | 25 | // sort the list using insertion sort 26 | insertion_sort(&list[0],MAX_ELEMENTS); 27 | 28 | // print the result 29 | printf("The list after sorting using insertion sort algorithm:\n"); 30 | printlist(list,MAX_ELEMENTS); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /src/integer_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "integer.h" 4 | using namespace alg; 5 | 6 | int main(void) 7 | { 8 | Integer a = Integer::from_string("1234567890"); 9 | Integer b = Integer::from_string("9876543210"); 10 | 11 | Integer c = a+b; 12 | 13 | printf("%s + %s = %s\n", a.to_string(), b.to_string(), c.to_string()); 14 | printf("%s - %s = %s\n", a.to_string(), b.to_string(), (a-b).to_string()); 15 | printf("%s - %s = %s\n", b.to_string(), a.to_string(), (b-a).to_string()); 16 | 17 | printf("%s %% 50 = %d\n", a.to_string(), a%50); 18 | printf("%s / 10 = %s\n", a.to_string(), (a/10).to_string()); 19 | printf("%s * 50 = %s\n", a.to_string(), (a*50).to_string()); 20 | printf("%s * %s = %s\n", a.to_string(), b.to_string(), (a*b).to_string()); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /src/interval_tree_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include /* rand() */ 5 | 6 | #include "interval_tree.h" 7 | using namespace alg; 8 | int main() { 9 | int i; 10 | IntervalTree t; 11 | t.print(); 12 | 13 | srand(time(NULL)); 14 | int MAXELEMENT = 50; 15 | for(i=0; ilow, n->high); 32 | t.delete_key(n); 33 | } 34 | } 35 | t.print(); 36 | 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/k-means_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "k-means.h" 4 | using namespace alg; 5 | 6 | int main() 7 | { 8 | double data[] = { 9 | 0.0, 0.2, 0.4, 10 | 0.3, 0.2, 0.4, 11 | 0.4, 0.2, 0.4, 12 | 0.5, 0.2, 0.4, 13 | 5.0, 5.2, 8.4, 14 | 6.0, 5.2, 7.4, 15 | 4.0, 5.2, 4.4, 16 | 10.3, 10.4, 10.5, 17 | 10.1, 10.6, 10.7, 18 | 11.3, 10.2, 10.9 19 | }; 20 | 21 | const int size = 10; //Number of samples 22 | const int dim = 3; //Dimension of feature 23 | const int cluster_num = 4; //Cluster number 24 | 25 | KMeans* kmeans = new KMeans(dim,cluster_num); 26 | int* labels = new int[size]; 27 | kmeans->SetInitMode(KMeans::InitUniform); 28 | kmeans->Cluster(data,size,labels); 29 | 30 | for(int i = 0; i < size; ++i) 31 | { 32 | printf("%f, %f, %f belongs to %d cluster\n", data[i*dim+0], data[i*dim+1], data[i*dim+2], labels[i]); 33 | } 34 | 35 | delete []labels; 36 | delete kmeans; 37 | 38 | return 0; 39 | } -------------------------------------------------------------------------------- /src/kmp_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "kmp.h" 7 | using namespace alg; 8 | int main(void) 9 | { 10 | srand(time(NULL)); 11 | char * S = (char*)malloc(1001); 12 | char * W = (char*)malloc(5); 13 | 14 | memset(S,0, 1001); 15 | memset(W,0, 5); 16 | 17 | // random genrate a pattern for A, G, C,T 18 | const char P[] = {'A', 'G','C','T'}; 19 | 20 | for (int i=0;i<1000;i++) { 21 | int k = rand()%4; 22 | S[i] = P[k]; 23 | } 24 | 25 | for (int i=0;i<4;i++) { 26 | int k = rand()%4; 27 | W[i] = P[k]; 28 | } 29 | 30 | // do a search for W from S 31 | int pos = kmp_search(S, W); 32 | printf("to be searched:%s\n", W); 33 | 34 | if (pos > 0) { 35 | printf("found in pos:%d\n", pos); 36 | printf("text:\n%.*s", pos, S); 37 | printf("\033[31m%s\033[0m", W); 38 | printf("%s\n",&S[pos + strlen(W)]); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/kruskal_mst_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "undirected_graph.h" 7 | #include "kruskal_mst.h" 8 | 9 | using namespace alg; 10 | int main(void) 11 | { 12 | using namespace alg; 13 | srand(time(NULL)); 14 | int NVERTEX = 10; 15 | UndirectedGraph * g = UndirectedGraph::randgraph(NVERTEX); 16 | g->printdot(); 17 | printf("Generating Kruskal's Graph: \n"); 18 | Kruskal pg(*g); 19 | pg.print(); 20 | 21 | 22 | printf("Generating Minimal spanning tree: \n"); 23 | Graph * mst = pg.run(); 24 | mst->printdot(); 25 | delete mst; 26 | delete g; 27 | return 0; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/lcs_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "lcs.h" 5 | #include "stack.h" 6 | 7 | #define printlistC(list,n) \ 8 | do { \ 9 | int list_counter_; \ 10 | for(list_counter_=0;list_counter_A is:\n"); 30 | printlistC(X,MAXN); 31 | printf("The list->B is:\n"); 32 | printlistC(Y,MAXN); 33 | 34 | Array2D * A = lcs_length(X, MAXN, Y, MAXN); 35 | 36 | Stack S(100); 37 | lcs_backtrack(S, *A, X, Y, MAXN, MAXN); 38 | 39 | printf("the largest common sequence is : \n"); 40 | while(!S.is_empty()) { 41 | int e = S.top(); 42 | printf("%c->", (char)e); 43 | S.pop(); 44 | } 45 | 46 | delete A; 47 | 48 | printf("\n"); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /src/m_based_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "imath.h" 7 | #include "prime.h" 8 | 9 | using namespace alg; 10 | int main() 11 | { 12 | uint32_t k[KLEN]; 13 | 14 | int i; 15 | int m; 16 | 17 | for(i=9;;i+=2) 18 | { 19 | if (is_prime(i)) 20 | { 21 | m=i; 22 | break; 23 | } 24 | } 25 | srand(time(NULL)); 26 | int key = rand()%1000; 27 | m_based(key, m , k); 28 | printf("turning %d into %d-based number:\n", key, m); 29 | for (i=0;i < KLEN;i++) 30 | { 31 | printf("k[%d] = %d\n",i,k[i]); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/max_subarray_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "max_subarray.h" 3 | 4 | using namespace alg; 5 | int main() { 6 | int arr[] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7}; 7 | int arr2[] = {1,-1,-2,-3,-4}; 8 | 9 | int begin; 10 | int end; 11 | int i; 12 | 13 | printf("the array:\n"); 14 | for (i=0;i 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "md5.h" 7 | 8 | /* Prints message digest buffer in mdContext as 32 hexadecimal digits. 9 | Order is from low-order byte to high-order byte of digest. 10 | Each byte is printed with high-order hexadecimal digit first. 11 | */ 12 | static void MDPrint (MD5_CTX *mdContext) 13 | { 14 | int i; 15 | 16 | for (i = 0; i < 16; i++) 17 | printf ("%02x", mdContext->digest[i]); 18 | } 19 | 20 | /* size of test block */ 21 | #define TEST_BLOCK_SIZE 1000 22 | 23 | /* number of blocks to process */ 24 | #define TEST_BLOCKS 10000 25 | 26 | /* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */ 27 | static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS; 28 | 29 | /* A time trial routine, to measure the speed of MD5. 30 | Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE 31 | characters. 32 | */ 33 | static void MDTimeTrial () 34 | { 35 | MD5_CTX mdContext; 36 | time_t endTime, startTime; 37 | unsigned char data[TEST_BLOCK_SIZE]; 38 | unsigned int i; 39 | 40 | /* initialize test data */ 41 | for (i = 0; i < TEST_BLOCK_SIZE; i++) 42 | data[i] = (unsigned char)(i & 0xFF); 43 | 44 | /* start timer */ 45 | printf ("MD5 time trial. Processing %ld characters...\n", TEST_BYTES); 46 | time (&startTime); 47 | 48 | /* digest data in TEST_BLOCK_SIZE byte blocks */ 49 | MD5Init (&mdContext); 50 | for (i = TEST_BLOCKS; i > 0; i--) 51 | MD5Update (&mdContext, data, TEST_BLOCK_SIZE); 52 | MD5Final (&mdContext); 53 | 54 | /* stop timer, get time difference */ 55 | time (&endTime); 56 | MDPrint (&mdContext); 57 | printf (" is digest of test input.\n"); 58 | printf 59 | ("Seconds to process test input: %ld\n", (long)(endTime-startTime)); 60 | printf 61 | ("Characters processed per second: %ld\n", 62 | TEST_BYTES/(endTime-startTime)); 63 | } 64 | 65 | /* Computes the message digest for string inString. 66 | Prints out message digest, a space, the string (in quotes) and a 67 | carriage return. 68 | */ 69 | static void MDString(const char *inString) 70 | { 71 | MD5_CTX mdContext; 72 | unsigned int len = strlen (inString); 73 | 74 | MD5Init (&mdContext); 75 | MD5Update (&mdContext, (unsigned char *)inString, len); 76 | MD5Final (&mdContext); 77 | MDPrint (&mdContext); 78 | printf (" \"%s\"\n\n", inString); 79 | } 80 | 81 | /* Computes the message digest for a specified file. 82 | Prints out message digest, a space, the file name, and a carriage 83 | return. 84 | */ 85 | static void MDFile (const char *filename) 86 | { 87 | FILE *inFile = fopen (filename, "rb"); 88 | MD5_CTX mdContext; 89 | int bytes; 90 | unsigned char data[1024]; 91 | 92 | if (inFile == NULL) { 93 | printf ("%s can't be opened.\n", filename); 94 | return; 95 | } 96 | 97 | MD5Init (&mdContext); 98 | while ((bytes = fread (data, 1, 1024, inFile)) != 0) 99 | MD5Update (&mdContext, data, bytes); 100 | MD5Final (&mdContext); 101 | MDPrint (&mdContext); 102 | printf (" %s\n", filename); 103 | fclose (inFile); 104 | } 105 | 106 | /* Writes the message digest of the data from stdin onto stdout, 107 | followed by a carriage return. 108 | */ 109 | static void MDFilter () 110 | { 111 | MD5_CTX mdContext; 112 | int bytes; 113 | unsigned char data[16]; 114 | 115 | MD5Init (&mdContext); 116 | while ((bytes = fread (data, 1, 16, stdin)) != 0) 117 | MD5Update (&mdContext, data, bytes); 118 | MD5Final (&mdContext); 119 | MDPrint (&mdContext); 120 | printf ("\n"); 121 | } 122 | 123 | /* Runs a standard suite of test data. 124 | */ 125 | static void MDTestSuite () 126 | { 127 | printf ("MD5 test suite results:\n\n"); 128 | MDString (""); 129 | MDString ("a"); 130 | MDString ("abc"); 131 | MDString ("message digest"); 132 | MDString ("abcdefghijklmnopqrstuvwxyz"); 133 | MDString 134 | ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 135 | MDString 136 | ("1234567890123456789012345678901234567890\ 137 | 1234567890123456789012345678901234567890"); 138 | /* Contents of file foo are "abc" */ 139 | MDFile ("foo"); 140 | } 141 | 142 | int main (int argc, char *argv[]) 143 | { 144 | int i; 145 | 146 | /* For each command line argument in turn: 147 | ** filename -- prints message digest and name of file 148 | ** -sstring -- prints message digest and contents of string 149 | ** -t -- prints time trial statistics for 1M characters 150 | ** -x -- execute a standard suite of test data 151 | ** (no args) -- writes messages digest of stdin onto stdout 152 | */ 153 | if (argc == 1) 154 | MDFilter (); 155 | else 156 | for (i = 1; i < argc; i++) 157 | if (argv[i][0] == '-' && argv[i][1] == 's') 158 | MDString (argv[i] + 2); 159 | else if (strcmp (argv[i], "-t") == 0) 160 | MDTimeTrial (); 161 | else if (strcmp (argv[i], "-x") == 0) 162 | MDTestSuite (); 163 | else MDFile (argv[i]); 164 | 165 | exit(0); 166 | } 167 | -------------------------------------------------------------------------------- /src/merge_sort_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "generic.h" 6 | #include "merge_sort.h" 7 | 8 | using namespace alg; 9 | 10 | int main() 11 | { 12 | const int MAX_ELEMENTS = 20; 13 | int list[MAX_ELEMENTS]; 14 | 15 | int i = 0; 16 | // generate random numbers and fill them to the list 17 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 18 | list[i] = rand()%100; 19 | } 20 | 21 | printf("The list before sorting is:\n"); 22 | printlist(list,MAX_ELEMENTS); 23 | 24 | // sort the list using quicksort 25 | merge_sort(list,0,MAX_ELEMENTS-1); 26 | 27 | // print the result 28 | printf("The list after sorting using merge sort algorithm:\n"); 29 | printlist(list,MAX_ELEMENTS); 30 | return 0; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/palindrome_demo.cpp: -------------------------------------------------------------------------------- 1 | #include "palindrome.h" 2 | #include 3 | 4 | int main() { 5 | alg::palindrome("banana"); 6 | alg::palindrome("abba"); 7 | alg::palindrome("aaaaa"); 8 | } 9 | -------------------------------------------------------------------------------- /src/perfect_hash_demo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************* 2 | * DANIEL'S PRIVATE ALGORITHM IMPLEMENTAIONS 3 | * Perfect Hashing 4 | * Features: 5 | * 1. based on Universal Hashing 6 | * 2. O(1) query 7 | * 3. Some applications naturally have !!!STATIC SETS OF KEYS!!!: 8 | consider the set of reserved words in a programming language, 9 | or the set of file names on a CD-ROM. We call a hashing technique perfect 10 | hashingif the worst-case number of memory accesses required 11 | to perform a search is O(1). 12 | *******************************************/ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "generic.h" 19 | #include "perfect_hash.h" 20 | 21 | int main(void) 22 | { 23 | using namespace alg; 24 | const int MAXELEMENT = 100; 25 | 26 | uint32_t keys[MAXELEMENT]; 27 | uint32_t values[MAXELEMENT]; 28 | 29 | srand(time(NULL)); 30 | int i; 31 | for (i = 0; i < MAXELEMENT; i++) { 32 | keys[i] = rand()%1000; 33 | values[i] = rand()%10000; 34 | } 35 | 36 | PerfHT ht(keys, MAXELEMENT); 37 | 38 | for (i = 0; i < MAXELEMENT; i++) { 39 | printf("set %d --> %d\n", keys[i],values[i]); 40 | ht[keys[i]] = values[i]; 41 | } 42 | 43 | for (i = 0; i < MAXELEMENT; i++) { 44 | printf("get %d <-- %d\n", keys[i], ht[keys[i]]); 45 | } 46 | 47 | try { 48 | printf("getting illegal key %d->%d\n", 20000, ht[20000]); 49 | } catch (std::exception& e) { 50 | printf("%s\n", e.what()); 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /src/prim_mst_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "undirected_graph.h" 7 | #include "prim_mst.h" 8 | 9 | int main(void) 10 | { 11 | using namespace alg; 12 | srand(time(NULL)); 13 | int NVERTEX = 10; 14 | alg::UndirectedGraph * g = alg::UndirectedGraph::randgraph(NVERTEX); 15 | g->printdot(); 16 | printf("Generating Prim's Graph: \n"); 17 | Graph * prim = alg::Prim::run(*g, 1); 18 | prim->printdot(); 19 | delete prim; 20 | delete g; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /src/prime_decompose.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | typedef uint32_t pint; 8 | typedef uint64_t xint; 9 | typedef unsigned int uint; 10 | #define PRIuPINT PRIu32 /* printf macro for pint */ 11 | #define PRIuXINT PRIu64 /* printf macro for xint */ 12 | #define MAX_FACTORS 63 /* because 2^64 is too large for xint */ 13 | 14 | uint8_t *pbits; 15 | 16 | #define MAX_PRIME (~(pint)0) 17 | #define MAX_PRIME_SQ 65535U 18 | #define PBITS (MAX_PRIME / 30 + 1) 19 | 20 | pint next_prime(pint); 21 | int is_prime(xint); 22 | void sieve(pint); 23 | 24 | uint8_t bit_pos[30] = { 25 | 0, 1<<0, 0, 0, 0, 0, 26 | 0, 1<<1, 0, 0, 0, 1<<2, 27 | 0, 1<<3, 0, 0, 0, 1<<4, 28 | 0, 1<<5, 0, 0, 0, 1<<6, 29 | 0, 0, 0, 0, 0, 1<<7, 30 | }; 31 | 32 | uint8_t rem_num[] = { 1, 7, 11, 13, 17, 19, 23, 29 }; 33 | 34 | void init_primes() 35 | { 36 | FILE *fp; 37 | pint s, tgt = 4; 38 | 39 | if (!(pbits = malloc(PBITS))) { 40 | perror("malloc"); 41 | exit(1); 42 | } 43 | 44 | if ((fp = fopen("primebits", "r"))) { 45 | fread(pbits, 1, PBITS, fp); 46 | fclose(fp); 47 | return; 48 | } 49 | 50 | memset(pbits, 255, PBITS); 51 | for (s = 7; s <= MAX_PRIME_SQ; s = next_prime(s)) { 52 | if (s > tgt) { 53 | tgt *= 2; 54 | fprintf(stderr, "sieve %"PRIuPINT"\n", s); 55 | } 56 | sieve(s); 57 | } 58 | fp = fopen("primebits", "w"); 59 | fwrite(pbits, 1, PBITS, fp); 60 | fclose(fp); 61 | } 62 | 63 | int is_prime(xint x) 64 | { 65 | pint p; 66 | if (x > 5) { 67 | if (x < MAX_PRIME) 68 | return pbits[x/30] & bit_pos[x % 30]; 69 | 70 | for (p = 2; p && (xint)p * p <= x; p = next_prime(p)) 71 | if (x % p == 0) return 0; 72 | 73 | return 1; 74 | } 75 | return x == 2 || x == 3 || x == 5; 76 | } 77 | 78 | void sieve(pint p) 79 | { 80 | unsigned char b[8]; 81 | off_t ofs[8]; 82 | int i, q; 83 | 84 | for (i = 0; i < 8; i++) { 85 | q = rem_num[i] * p; 86 | b[i] = ~bit_pos[q % 30]; 87 | ofs[i] = q / 30; 88 | } 89 | 90 | for (q = ofs[1], i = 7; i; i--) 91 | ofs[i] -= ofs[i-1]; 92 | 93 | for (ofs[0] = p, i = 1; i < 8; i++) 94 | ofs[0] -= ofs[i]; 95 | 96 | for (i = 1; q < PBITS; q += ofs[i = (i + 1) & 7]) 97 | pbits[q] &= b[i]; 98 | } 99 | 100 | pint next_prime(pint p) 101 | { 102 | off_t addr; 103 | uint8_t bits, rem; 104 | 105 | if (p > 5) { 106 | addr = p / 30; 107 | bits = bit_pos[ p % 30 ] << 1; 108 | for (rem = 0; (1 << rem) < bits; rem++); 109 | while (pbits[addr] < bits || !bits) { 110 | if (++addr >= PBITS) return 0; 111 | bits = 1; 112 | rem = 0; 113 | } 114 | if (addr >= PBITS) return 0; 115 | while (!(pbits[addr] & bits)) { 116 | rem++; 117 | bits <<= 1; 118 | } 119 | return p = addr * 30 + rem_num[rem]; 120 | } 121 | 122 | switch(p) { 123 | case 2: return 3; 124 | case 3: return 5; 125 | case 5: return 7; 126 | } 127 | return 2; 128 | } 129 | 130 | int decompose(xint n, xint *f) 131 | { 132 | pint p = 0; 133 | int i = 0; 134 | 135 | /* check small primes: not strictly necessary */ 136 | if (n <= MAX_PRIME && is_prime(n)) { 137 | f[0] = n; 138 | return 1; 139 | } 140 | 141 | while (n >= (xint)p * p) { 142 | if (!(p = next_prime(p))) break; 143 | while (n % p == 0) { 144 | n /= p; 145 | f[i++] = p; 146 | } 147 | } 148 | if (n > 1) f[i++] = n; 149 | return i; 150 | } 151 | 152 | int main() 153 | { 154 | int i, len; 155 | pint p = 0; 156 | xint f[MAX_FACTORS], po; 157 | 158 | init_primes(); 159 | 160 | for (p = 1; p < 64; p++) { 161 | po = (1LLU << p) - 1; 162 | printf("2^%"PRIuPINT" - 1 = %"PRIuXINT, p, po); 163 | fflush(stdout); 164 | if ((len = decompose(po, f)) > 1) 165 | for (i = 0; i < len; i++) 166 | printf(" %c %"PRIuXINT, i?'x':'=', f[i]); 167 | putchar('\n'); 168 | } 169 | 170 | return 0; 171 | } 172 | -------------------------------------------------------------------------------- /src/prime_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace alg; 6 | int main() 7 | { 8 | unsigned i; 9 | int miller = 0; 10 | time_t t1 = time(NULL); 11 | int prime; 12 | for (i = 1000000000; i<1001000000; i++) { 13 | if (miller_rabin_test(i)) { 14 | miller++; 15 | prime=i; 16 | } 17 | } 18 | 19 | time_t t2 = time(NULL); 20 | printf("found %d miller-primes , cost %ld secs\n", miller,t2-t1); 21 | printf("last prime %d\n", prime); 22 | 23 | int count = 0; 24 | t1 = time(NULL); 25 | for (i = 1000000000; i<1001000000; i++) { 26 | if (test_prime(i)) count++; 27 | } 28 | t2 = time(NULL); 29 | printf("found %d primes using raw_test, cost %ld secs\n", count,t2-t1); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /src/priority_queue_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "priority_queue.h" 6 | 7 | int main(void) 8 | { 9 | using namespace alg; 10 | PQ pq; 11 | 12 | srand(time(NULL)); 13 | 14 | int MAXELEMENT = 20; 15 | int i; 16 | 17 | for (i=0;i pri: %d\n", i, pri); 21 | } 22 | 23 | printf("count# %d\n", pq.count()); 24 | while(!pq.is_empty()){ 25 | int pri; 26 | int value = pq.top(&pri); 27 | printf("dequeue: %d --> pri: %d\n", value, pri); 28 | pq.dequeue(); 29 | } 30 | printf("count# %d\n", pq.count()); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /src/queue_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "queue.h" 6 | 7 | int main() 8 | { 9 | using alg::Queue; 10 | const int MAXELEMENT = 20; 11 | Queue Q(MAXELEMENT); 12 | int i; 13 | 14 | for (i=0;i DEQUEUE\n"); 23 | while(!Q.is_empty()) { 24 | printf("dequeue %d\n",Q.front()); 25 | Q.dequeue(); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /src/quick_sort_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "generic.h" 6 | #include "quick_sort.h" 7 | 8 | int main() 9 | { 10 | RANDOM_INIT(); 11 | using namespace alg; 12 | const int MAX_ELEMENTS = 10; 13 | int list[MAX_ELEMENTS]; 14 | 15 | int i = 0; 16 | srand(time(NULL)); 17 | // generate random numbers and fill them to the list 18 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 19 | list[i] = rand()%100; 20 | } 21 | printf("The list before sorting is:\n"); 22 | printlist(list,MAX_ELEMENTS); 23 | 24 | // sort the list using quicksort 25 | quicksort(list,0,MAX_ELEMENTS-1); 26 | 27 | // print the result 28 | printf("The list after sorting using quicksort algorithm:\n"); 29 | printlist(list,MAX_ELEMENTS); 30 | return 0; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/radix_sort_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "generic.h" 6 | #include "radix_sort.h" 7 | 8 | int main() 9 | { 10 | using namespace alg; 11 | const int MAX_ELEMENTS = 10; 12 | uint32_t list[MAX_ELEMENTS]; 13 | 14 | int i = 0; 15 | srand(time(NULL)); 16 | // generate random numbers and fill them to the list 17 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 18 | list[i] = rand()%100; 19 | } 20 | 21 | printf("The list before sorting is:\n"); 22 | printlist(list,MAX_ELEMENTS); 23 | 24 | // sort the list using insertion sort 25 | radix_sort(list, MAX_ELEMENTS); 26 | check_order(list, MAX_ELEMENTS); 27 | 28 | // print the result 29 | printf("The list after sorting using radix sort algorithm:\n"); 30 | printlist(list,MAX_ELEMENTS); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /src/random_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "random.h" 3 | 4 | int main(void) { 5 | std::cout <<"generate random numbers\n"; 6 | for (int i=0;i<100;i++) { 7 | std::cout< 2 | #include 3 | #include 4 | 5 | #include "generic.h" 6 | #include "random_select.h" 7 | 8 | int main() 9 | { 10 | RANDOM_INIT(); 11 | using namespace alg; 12 | const int MAX_ELEMENTS = 10; 13 | int list[MAX_ELEMENTS]; 14 | 15 | int i = 0; 16 | 17 | // generate numbers and fill them to the list 18 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 19 | list[i] = rand()%100; 20 | } 21 | 22 | printf("The list is:\n"); 23 | printlist(list,MAX_ELEMENTS); 24 | 25 | // random-select k-th element 26 | srand(time(NULL)); 27 | int k = rand()%MAX_ELEMENTS + 1; 28 | int result = random_select(list,0,MAX_ELEMENTS-1,k); 29 | 30 | // print the result 31 | printf("random select the %dth smallest number %d:\n", k, list[result]); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/rbtree_demo.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 the authors listed at the following URL, and/or 2 | the authors of referenced articles or incorporated external code: 3 | http://en.literateprograms.org/Red-black_tree_(C)?action=history&offset=20120524204657 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | Retrieved from: http://en.literateprograms.org/Red-black_tree_(C)?oldid=18555 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include /* rand() */ 32 | 33 | #include "rbtree.h" 34 | 35 | using namespace alg; 36 | 37 | #define INDENT_STEP 4 38 | 39 | int main() { 40 | int i; 41 | RBTree t; 42 | t.print(); 43 | 44 | srand(time(NULL)); 45 | 46 | int MAXELEMENT = 50; 47 | printf("Inserting: \t"); 48 | for(i=0; i 2 | #include 3 | #include 4 | 5 | #include "edmonds_karp.h" 6 | #include "relabel_to_front.h" 7 | using namespace alg; 8 | 9 | int main(void) 10 | { 11 | using namespace alg; 12 | srand(time(NULL)); 13 | int NVERTEX = 300; 14 | 15 | clock_t ek_start, ek_end, pr_start, pr_end; 16 | 17 | DirectedGraph * g = DirectedGraph::randgraph(NVERTEX); 18 | // g->printdot(); 19 | 20 | printf("finding Maximal Flow from 0 to %d: \n", NVERTEX-1); 21 | printf("The graph containing %d edges.\n", g->edge_count()); 22 | 23 | ek_start = clock(); 24 | EdmondsKarp ek(*g); 25 | uint32_t maxflow = ek.run(0, NVERTEX-1); 26 | ek_end = clock(); 27 | 28 | printf("Max Flow calculated by edmonds-karp algorithm is %d\n", maxflow); 29 | // printf("the residual network\n"); 30 | // printf("\t"); 31 | // for(uint32_t i=0;ivertex_count();i++) { 32 | // printf("%d\t", ek2.rmap()[i]); 33 | // } 34 | // printf("\n"); 35 | 36 | // for(uint32_t i=0;ivertex_count();i++) { 37 | // printf("%d\t",ek2.rmap()[i]); 38 | // for(uint32_t j=0;jvertex_count();j++) { 39 | // printf("%d\t", ek2.residual()(i,j)); 40 | // } 41 | // printf("\n"); 42 | // } 43 | 44 | pr_start = clock(); 45 | RelabelToFront pr2(*g); 46 | uint32_t maxflow_pr = pr2.run(0, NVERTEX-1); 47 | pr_end = clock(); 48 | 49 | printf("Max Flow calculated by push-relabel is %d\n", maxflow_pr); 50 | // printf("the residual and preflow network\n"); 51 | // printf("\t"); 52 | // for(uint32_t i=0; ivertex_count(); i++) { 53 | // printf("%d\t", pr2.rmap()[i]); 54 | // } 55 | // printf("\n"); 56 | 57 | // for (uint32_t i=0; ivertex_count(); i++){ 58 | // printf("%d\t", pr2.rmap()[i]); 59 | // for (uint32_t j=0; jvertex_count(); j++){ 60 | // printf("%d\t", pr2.residual()(i,j)); 61 | // } 62 | // printf("\n"); 63 | // } 64 | // printf("\n"); 65 | 66 | long ek_time = ek_end - ek_start; 67 | long pr_time = pr_end - pr_start; 68 | 69 | printf("The number of clock tick consumed by edmonds-karp is %ld\n", ek_time); 70 | printf("--------------------------------- by push-relabel is %ld\n", pr_time); 71 | 72 | delete g; 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /src/scc_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "directed_graph.h" 6 | #include "graph_search.h" 7 | #include "scc.h" 8 | 9 | using namespace alg; 10 | 11 | int main() 12 | { 13 | using namespace alg; 14 | srand(time(NULL)); 15 | DirectedGraph * g = new DirectedGraph; 16 | // construct 3 islands 17 | int32_t i; 18 | for (i=0;i<9;i++) { 19 | g->add_vertex(i); 20 | } 21 | 22 | g->add_edge(0,1,1); 23 | g->add_edge(1,2,1); 24 | g->add_edge(2,0,1); 25 | 26 | g->add_edge(3,4,1); 27 | g->add_edge(4,5,1); 28 | g->add_edge(5,3,1); 29 | 30 | g->add_edge(6,7,1); 31 | g->add_edge(7,8,1); 32 | g->add_edge(8,6,1); 33 | 34 | // connect island 35 | g->add_edge(0,3,1); 36 | g->add_edge(3,8,1); 37 | 38 | g->printdot(); 39 | 40 | printf("find strongly connected component\n"); 41 | SCC(*g); 42 | 43 | delete g; 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /src/selection_sort_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "selection_sort.h" 4 | 5 | template 6 | static void printlist(T & list,int count) { 7 | int i; 8 | for(i=0;i 2 | #include 3 | #include 4 | #include "sha1.h" 5 | 6 | #define TESTA "abc\n" 7 | 8 | int main(void) 9 | { 10 | SHA1Context sha; 11 | 12 | sha1_reset(&sha); 13 | sha1_input(&sha, (const unsigned char *) TESTA, strlen(TESTA)); 14 | 15 | if (sha1_final(&sha)) 16 | { 17 | printf("sha %s --> ", TESTA); 18 | int i; 19 | for(i = 0; i < 5 ; i++) 20 | { 21 | printf("%x", sha.digest[i]); 22 | } 23 | printf("\n"); 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /src/shell_sort_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "generic.h" 6 | #include "shell_sort.h" 7 | 8 | using namespace alg; 9 | 10 | int main() 11 | { 12 | const int MAX_ELEMENTS = 10; 13 | int list[MAX_ELEMENTS]; 14 | 15 | int i = 0; 16 | 17 | srand(time(NULL)); 18 | // generate random numbers and fill them to the list 19 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 20 | list[i] = rand()%100; 21 | } 22 | printf("The list before sorting is:\n"); 23 | printlist(list,MAX_ELEMENTS); 24 | 25 | // sort the list using shell sort 26 | shell_sort(&list[0],MAX_ELEMENTS); 27 | 28 | // print the result 29 | printf("The list after sorting using shell sort algorithm:\n"); 30 | printlist(list,MAX_ELEMENTS); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /src/shuffle_demo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************* 2 | * DANIEL'S PRIVATE ALGORITHM IMPLEMENTAIONS 3 | * Fisher Yates's shuffle algorithm 4 | * Features: 5 | * 1. shuffle list in O(n) time. 6 | *******************************************/ 7 | 8 | #include 9 | #include 10 | 11 | #include "generic.h" 12 | #include "shuffle.h" 13 | using namespace alg; 14 | int main() 15 | { 16 | const int MAX_ELEMENTS = 10; 17 | int list[MAX_ELEMENTS]; 18 | 19 | int i = 0; 20 | 21 | // generate random numbers and fill them to the list 22 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 23 | list[i] = i; 24 | } 25 | printf("The list before Shuffle is:\n"); 26 | printlist(list,MAX_ELEMENTS); 27 | 28 | // shuffle the list 29 | shuffle(list,MAX_ELEMENTS); 30 | 31 | // print the result 32 | printf("The list after using Yates' shuffle algorithm:\n"); 33 | printlist(list,MAX_ELEMENTS); 34 | return 0; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/simhash_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "simhash.h" 4 | 5 | using namespace alg; 6 | void addsentence(char * str, SimHash &h); 7 | 8 | int main(void) { 9 | char strA[] = {"the cat sat on the mat"}; 10 | char strB[] = {"the cat sat on a mat"}; 11 | char strC[] = {"we all scream for ice cream"}; 12 | printf("%s\n", strA); 13 | printf("%s\n", strB); 14 | printf("%s\n", strC); 15 | 16 | SimHash h1, h2, h3; 17 | 18 | addsentence(strA, h1); 19 | addsentence(strB, h2); 20 | addsentence(strC, h3); 21 | 22 | printf("%u\n", h1.Hash()); 23 | printf("%u\n", h2.Hash()); 24 | printf("%u\n", h3.Hash()); 25 | 26 | printf("hamming distance:\n"); 27 | printf("h1, h2 : %d\n", SimHash::Distance(h1.Hash(), h2.Hash())); 28 | printf("h1, h3 : %d\n", SimHash::Distance(h1.Hash(), h3.Hash())); 29 | printf("h2, h3 : %d\n", SimHash::Distance(h2.Hash(), h3.Hash())); 30 | } 31 | 32 | void addsentence(char * str, SimHash &h) { 33 | char *ptr; 34 | for (ptr=str;;ptr=NULL) { 35 | char *token = strtok(ptr, " "); 36 | if (token == NULL) { 37 | break; 38 | } 39 | h.AddWord(token, strlen(token)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/skiplist_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "skiplist.h" 3 | 4 | using namespace alg; 5 | 6 | int main() 7 | { 8 | 9 | SkipList ss; 10 | 11 | const int MAX_ELEMENTS = 20; 12 | 13 | int i = 0; 14 | srand(time(NULL)); 15 | 16 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 17 | ss.insert(i, rand()%100); 18 | } 19 | 20 | printf("The skip list :\n"); 21 | ss.print(); 22 | 23 | printf("Random get keys :\n"); 24 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 25 | int r = rand()%100; 26 | try { 27 | printf("get: %d->%d\n",r, ss[r]); 28 | } catch (std::exception &e) { 29 | printf("%s\n", e.what()); 30 | } 31 | } 32 | 33 | printf("random deleteion:\n"); 34 | for(i = 0; i < MAX_ELEMENTS; i++ ){ 35 | int r = rand()%100; 36 | printf("delete key :%d\n",r); 37 | ss.delete_key(r); 38 | } 39 | 40 | printf("The skip list after deletion:\n"); 41 | 42 | ss.print(); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /src/sort_demo.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "sort.h" 5 | 6 | using namespace std; 7 | using namespace alg; 8 | 9 | 10 | ///////////////////////////// 11 | // 12 | // custom compare function 13 | // 14 | ///////////////////////////// 15 | bool comp(int a,int b){ 16 | if (a>=b) 17 | return true; 18 | 19 | return false; 20 | } 21 | 22 | ///////////////////////////// 23 | // 24 | // custom swap function 25 | // 26 | /////////////////////////////// 27 | void swap(int &a,int &b){ 28 | int tmp; 29 | tmp=a; 30 | a=b; 31 | b=tmp; 32 | } 33 | 34 | 35 | //make rand data 36 | void makeArray(vector& array,int num){ 37 | 38 | for(size_t i = 0; i < num; ++i) 39 | { 40 | array.push_back(rand()%100); 41 | /* code */ 42 | } 43 | 44 | } 45 | 46 | 47 | int main (int argc, char const *argv[]) 48 | { 49 | vector a; 50 | 51 | alg::SortClass sort(a,comp,swap); 52 | makeArray(a,10); 53 | cout << "############### quick sort ###############" << endl; 54 | cout << "before sort::: " ; 55 | sort.displaySort(); 56 | sort.quickSort(); 57 | cout << "after sort ::: "; 58 | sort.displaySort(); 59 | cout << endl; 60 | 61 | 62 | a.clear(); 63 | makeArray(a,11); 64 | cout << "############### insertion sort ###############" << endl; 65 | cout << "before sort::: " ; 66 | sort.displaySort(); 67 | sort.insertSort(); 68 | cout << "after sort ::: "; 69 | sort.displaySort(); 70 | cout << endl; 71 | 72 | 73 | a.clear(); 74 | makeArray(a,10); 75 | cout << "############### bubble sort ###############" << endl; 76 | cout << "before sort::: " ; 77 | sort.displaySort(); 78 | sort.bubbleSort(); 79 | cout << "after sort ::: "; 80 | sort.displaySort(); 81 | cout << endl; 82 | 83 | 84 | a.clear(); 85 | makeArray(a,10); 86 | cout << "############### selection sort ###############" << endl; 87 | cout << "before sort::: " ; 88 | sort.displaySort(); 89 | sort.selectionSort(); 90 | cout << "after sort ::: "; 91 | sort.displaySort(); 92 | cout << endl; 93 | 94 | 95 | a.clear(); 96 | makeArray(a,10); 97 | cout << "############### heap sort ###############" << endl; 98 | cout << "before sort::: " ; 99 | sort.displaySort(); 100 | sort.heapSort(); 101 | cout << "after sort ::: "; 102 | sort.displaySort(); 103 | cout << endl; 104 | 105 | a.clear(); 106 | makeArray(a,10); 107 | cout << "############### merge sort ###############" << endl; 108 | cout << "before sort::: " ; 109 | sort.displaySort(); 110 | sort.mergeSort(); 111 | cout << "after sort ::: "; 112 | sort.displaySort(); 113 | 114 | 115 | 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /src/stack_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | using namespace alg; 6 | int main() 7 | { 8 | Stack S(4); 9 | S.push(7); 10 | S.push(5); 11 | S.push(-1); 12 | 13 | printf("push return value when has capacity: %d\n",S.push(9)); 14 | printf("push return value when full: %d\n",S.push(10)); 15 | for (uint32_t i=0; i< S.count();i++) { 16 | printf("element %d, %d\n",i, S[i]); 17 | } 18 | 19 | while(!S.is_empty()) { 20 | printf("poping: %d\n", S.top()); 21 | S.pop(); 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /src/suffix_array_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "suffix_array.h" 6 | 7 | using namespace std; 8 | using namespace alg; 9 | 10 | void print(string::iterator b, string::iterator e) { 11 | for(auto it=b;it!=e;++it) cout<<*it; 12 | } 13 | 14 | int main() 15 | { 16 | string str; 17 | while(cin>>str) { 18 | SuffixArray sa(str); 19 | cout< 3 | 4 | int SuffixTree::search(string sub) 5 | { 6 | Node* node = &root; 7 | bool in_edge = false; // Are we searching in middle of an edge? 8 | Edge* edge = NULL; 9 | int edge_pos = 0, edge_len = 0; 10 | 11 | int result = -1; 12 | 13 | for (unsigned int i=0; ifind_edge(cur); // find an edge and search it 19 | 20 | if (edge == NULL) 21 | return -1; 22 | 23 | // record match pos 24 | if (i == 0) 25 | result = edge->begin; 26 | 27 | edge_pos = 0; 28 | edge_len = edge->length(); 29 | } 30 | 31 | 32 | if (cur != (*edge)[edge_pos]) 33 | return -1; 34 | 35 | edge_pos++; 36 | // reached the end of this edge, jump to next node 37 | if (edge_pos >= edge_len) { 38 | in_edge = false; 39 | node = edge->endpoint; 40 | edge = NULL; 41 | edge_pos = 0; 42 | } 43 | } 44 | 45 | return result; 46 | } 47 | 48 | 49 | int SuffixTree::construct(void) 50 | { 51 | // test_str shouldn't have '#' until now 52 | test_str = test_str + "#"; 53 | using std::numeric_limits; 54 | 55 | while (pos < test_str.size()) { 56 | ls.clear(); 57 | remainder++; 58 | cout << "Char: " << test_str[pos] << endl; 59 | 60 | while (remainder) { 61 | int length = get_active_length(); 62 | if (length == 0) 63 | active_e = pos; 64 | 65 | Node* node = active_point.active_node; 66 | char a_char = get_active_edge(); 67 | Edge* a_edge = node->find_edge(a_char); 68 | 69 | 70 | if (a_edge == NULL) { 71 | Edge* newedge = new Edge(pos, numeric_limits::max(), test_str); 72 | node->add_edge(newedge); 73 | ls.ins_link(node); 74 | } 75 | else { 76 | if (check_active_node()) 77 | continue; 78 | 79 | char expected_ele = (*a_edge)[get_active_length()]; 80 | if (expected_ele == get_ele(pos)) { 81 | inc_active_len(); 82 | ls.ins_link(node); 83 | break; 84 | } 85 | Node *newnode = separate_edge(node, a_edge); 86 | Edge* newedge = new Edge(pos, numeric_limits::max(), test_str); 87 | newnode->add_edge(newedge); 88 | ls.ins_link(newnode); 89 | } 90 | remainder--; 91 | if (node == &root && get_active_length() > 0) { 92 | dec_active_len(); 93 | active_e = pos - remainder + 1; 94 | } 95 | else if (node->suffix_link) { 96 | set_active_node(node->suffix_link); 97 | } 98 | else 99 | set_active_node(&root); 100 | } 101 | 102 | pos++; 103 | } 104 | return 0; 105 | } 106 | 107 | SuffixTree::Node* SuffixTree::separate_edge(Node * node, Edge* a_edge) 108 | { 109 | cout << "separate the old edge here: " << (*a_edge) << endl; 110 | int new_begin = a_edge->begin + get_active_length(); 111 | int new_end = a_edge->end; 112 | 113 | int old_begin = a_edge->begin; 114 | int old_end = new_begin - 1; 115 | 116 | cout << (*node); 117 | 118 | node->del_edge(a_edge); 119 | a_edge->change_edge(new_begin, new_end); 120 | Edge* old_edge1 = new Edge(old_begin, old_end, test_str); 121 | node->add_edge(old_edge1); 122 | 123 | old_edge1->endpoint->add_edge(a_edge); 124 | 125 | cout << "The old edge split as -- " << (*a_edge) << " and -- " << (*old_edge1) << endl; 126 | 127 | cout << "root " << (&root) << endl; 128 | cout << node << endl; 129 | Node* new_node = old_edge1->endpoint; 130 | cout << node << endl; 131 | 132 | return new_node; 133 | } 134 | 135 | int SuffixTree::print_tree() 136 | { 137 | print_node(&root, 1); 138 | 139 | return 0; 140 | } 141 | 142 | int SuffixTree::print_node(Node* node, int level) 143 | { 144 | using namespace std; 145 | if (level == 0) 146 | cout << "Root " << endl; 147 | 148 | if (node->isleaf()) { 149 | cout << "Leaf reached." << endl; 150 | return 0; 151 | } 152 | 153 | map::iterator iter; 154 | for (iter = node->edges.begin(); iter!=node->edges.end(); iter++) { 155 | int indent = level; 156 | while (indent--) 157 | cout << '\t'; 158 | 159 | int begin = iter->first->begin, end = (iter->first->end < test_str.size() - 1) ? iter->first->end : test_str.size() - 1; 160 | cout << "--> (" << begin << ", " << end << ") "; 161 | for (int i=begin; i<=end; i++) 162 | cout << test_str[i]; 163 | cout << endl; 164 | 165 | cout << "Node Add " << node << endl; 166 | cout << "Edge printed " << iter->first << endl << endl; 167 | print_node((iter->first->endpoint), level+1); 168 | } 169 | 170 | cout << endl; 171 | return 0; 172 | } 173 | 174 | using namespace std; 175 | 176 | int main() 177 | { 178 | cout << "Beginning" << endl; 179 | SuffixTree st("mississippi"); 180 | 181 | cout << "Constructing..." << endl; 182 | st.construct(); 183 | 184 | cout << "Printing..." << endl; 185 | st.print_tree(); 186 | 187 | cout << "Search ANA:" << st.search("ANA") << endl; 188 | cout << "Search NA:" << st.search("NA") << endl; 189 | cout << "Search NAN:" << st.search("NAN") << endl; 190 | cout << "Search B:" << st.search("B") << endl; 191 | 192 | cout << endl; 193 | 194 | cout << "Search BB:" << st.search("BB") << endl; 195 | cout << "Search ANN:" << st.search("ANN") << endl; 196 | cout << "Search b:" << st.search("b") << endl; 197 | 198 | return 0; 199 | } 200 | -------------------------------------------------------------------------------- /src/trie_demo.cpp: -------------------------------------------------------------------------------- 1 | #include "trie.h" 2 | 3 | int main(void) { 4 | alg::Trie trie; 5 | const char *strs[] = {"sap", "sat", "sad", "rat", "ram", "rag", "rap", "sat", "ram","rag", "nap", "Nat", "lap"}; 6 | 7 | for (uint32_t i=0;i 2 | #include 3 | #include 4 | 5 | #include "undirected_graph.h" 6 | 7 | using namespace alg; 8 | int main() 9 | { 10 | srand(time(NULL)); 11 | int NVERTEX = 20; 12 | UndirectedGraph * g = UndirectedGraph::randgraph(NVERTEX); 13 | g->printdot(); 14 | 15 | printf("Random Delete Vertex:\n"); 16 | // random delete vertex 17 | int i; 18 | for(i=0;idelete_vertex(n); 22 | } 23 | 24 | g->printdot(); 25 | printf("Delete All Edges: \n"); 26 | 27 | for(i=0;idelete_edge(i, j); 31 | } 32 | } 33 | 34 | g->printdot(); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/universal_hash_demo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************* 2 | * DANIEL'S PRIVATE ALGORITHM IMPLEMENTAIONS 3 | * Universal Hashing 4 | * Features: 5 | * 1. randomized hash function, random a1,a2.. a32 6 | * 2. alloc your storage larger than UHash->prime 7 | * 3. the collsion expectation: 8 | E[Cx] = (n - 1 ) / m (n: number of elements, m: bucket size--prime number) 9 | * 4. this set has m^(r+1) different hash functions. 10 | *******************************************/ 11 | #include 12 | #include 13 | #include 14 | 15 | #include "universal_hash.h" 16 | 17 | using namespace alg; 18 | int main(void) 19 | { 20 | int MAXELEMENT = 1000; 21 | struct UHash params; 22 | 23 | srand(time(NULL)); 24 | uhash_init(¶ms, MAXELEMENT); 25 | 26 | int i; 27 | for (i = 0; i < MAXELEMENT; i++) 28 | { 29 | printf("hashing %d --> %d\n", i, uhash_integer(¶ms, i)); 30 | } 31 | 32 | printf("prime %d\n", params.prime); 33 | } 34 | -------------------------------------------------------------------------------- /src/word_seg_demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "generic.h" 6 | #include "word_seg.h" 7 | 8 | using namespace alg; 9 | 10 | int main(void) 11 | { 12 | WordSeg ws("./src/dict.txt.sogou"); 13 | 14 | char buf[1024]; 15 | printf("input a sentence in GB18030 encoding, no more than 256 words:\n"); 16 | 17 | while(1){ 18 | scanf("%s", buf); 19 | char *part, *brkt; 20 | const char *sep=" "; 21 | 22 | for (part = strtok_r(buf, sep, &brkt); 23 | part; 24 | part = strtok_r(NULL, sep, &brkt)) 25 | { 26 | Queue * q = ws.run(part); 27 | short cursor = 0; 28 | while(!q->is_empty()) { 29 | int state = q->front(); 30 | uint32_t CH; 31 | cursor += gb18030_read(part,cursor,&CH); 32 | gb18030_putchar(CH); 33 | putchar(state); 34 | if(state=='0') printf(" "); 35 | if(state=='3') printf(" "); 36 | q->dequeue(); 37 | } 38 | printf("\n"); 39 | delete q; 40 | } 41 | } 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /utils/byteorder.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGO_BYTEORDER_H__ 2 | #define ALGO_BYTEORDER_H__ 3 | #include 4 | #include 5 | 6 | /** 7 | * test endianness of current machine 8 | * mem: 0D 0C 0B 0A //big endian 9 | * mem: 0A 0B 0C 0D //little endian 10 | * V=0x0D0C0B0A 11 | */ 12 | static inline bool 13 | is_big_endian() 14 | { 15 | int v=0x0D0C0B0A; 16 | char c = *(char*)&v; 17 | 18 | if (c == 0x0A) return false; 19 | return true; 20 | } 21 | 22 | /** 23 | * uint16_t byte swap mask 24 | */ 25 | #define BYTE_MASK_A_ 0xff00 26 | #define BYTE_MASK__B 0x00ff 27 | 28 | /** 29 | * byte swap 2-byte 30 | */ 31 | static inline uint16_t 32 | byte_swap2(uint16_t original) 33 | { 34 | uint16_t swapped; 35 | 36 | swapped = (( (original) & BYTE_MASK_A_) >> 8) 37 | | 38 | (( (original) & BYTE_MASK__B) <<8); 39 | 40 | return swapped; 41 | } 42 | 43 | /** 44 | * uint32_t byte swap mask 45 | */ 46 | #define BYTE_MASK_A_C_ 0xff00ff00 47 | #define BYTE_MASK__B_D 0x00ff00ff 48 | #define BYTE_MASK_AB__ 0xffff0000 49 | #define BYTE_MASK___CD 0x0000ffff 50 | 51 | /** 52 | * byte swap 4-byte 53 | */ 54 | static inline uint32_t 55 | byte_swap4(uint32_t original) 56 | { 57 | uint32_t swapped; 58 | 59 | // ABCD => BADC 60 | swapped = (( (original) & BYTE_MASK_A_C_ ) >> 8 ) 61 | | 62 | (( (original) & BYTE_MASK__B_D ) << 8 ); 63 | 64 | // BADC => DCBA 65 | swapped = (( swapped & BYTE_MASK_AB__ ) >> 16 ) 66 | | 67 | (( swapped & BYTE_MASK___CD ) << 16 ); 68 | 69 | return swapped; 70 | } 71 | 72 | /* 73 | * uint64_t byte swap mask 74 | */ 75 | #define BYTE_MASK_A_C_E_G_ 0xff00ff00ff00ff00ULL 76 | #define BYTE_MASK__B_D_F_H 0x00ff00ff00ff00ffULL 77 | #define BYTE_MASK_AB__EF__ 0xffff0000ffff0000ULL 78 | #define BYTE_MASK___CD__GH 0x0000ffff0000ffffULL 79 | #define BYTE_MASK_ABCD____ 0xffffffff00000000ULL 80 | #define BYTE_MASK_____EFGH 0x00000000ffffffffULL 81 | 82 | /** 83 | * byte swap 8-byte 84 | */ 85 | static inline uint64_t 86 | byte_swap8( uint64_t original ) 87 | { 88 | uint64_t swapped; 89 | 90 | // ABCDEFGH => BADCFEHG 91 | swapped = (( (original) & BYTE_MASK_A_C_E_G_ ) >> 8 ) 92 | | 93 | (( (original) & BYTE_MASK__B_D_F_H ) << 8 ); 94 | 95 | // BADCFEHG => DCBAHGFE 96 | swapped = (( swapped & BYTE_MASK_AB__EF__ ) >> 16 ) 97 | | 98 | (( swapped & BYTE_MASK___CD__GH ) << 16 ); 99 | 100 | // DCBAHGFE => HGFEDCBA 101 | swapped = (( swapped & BYTE_MASK_ABCD____ ) >> 32 ) 102 | | 103 | (( swapped & BYTE_MASK_____EFGH ) << 32 ); 104 | 105 | return swapped; 106 | } 107 | 108 | #endif // 109 | -------------------------------------------------------------------------------- /utils/gb18030.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGO_GB18030_H__ 2 | #define ALGO_GB18030_H__ 3 | 4 | /** 5 | * Read from the string encoded in GB18030 into WORD 6 | * return the length of the WORD 7 | */ 8 | static inline short 9 | gb18030_read(const char * str, int start, uint32_t * WORD) 10 | { 11 | unsigned char * w = (unsigned char *)&str[start]; 12 | 13 | if (w[0] <= 0x7F) { // 1-byte 14 | *WORD = w[0]; 15 | return 1; 16 | } else if (w[0] >= 0x81 && w[0] <=0xFE) { 17 | if (w[1] >=0x40 && w[1] <=0xFE) { // 2-byte 18 | *WORD = (w[0] << 8) | w[1]; 19 | return 2; 20 | } else { // 4-byte 21 | *WORD = (w[0]<<24)|(w[1]<< 16)|(w[2]<<8)|w[3]; 22 | return 4; 23 | } 24 | } 25 | return 0; 26 | } 27 | 28 | /** 29 | * print a gb18030 char 30 | */ 31 | static inline void 32 | gb18030_putchar(const uint32_t w) 33 | { 34 | union _decomposer{ 35 | struct{ 36 | unsigned char w3; 37 | unsigned char w2; 38 | unsigned char w1; 39 | unsigned char w0; 40 | } dtls; 41 | uint32_t word; 42 | }; 43 | _decomposer t; 44 | t.word = w; 45 | unsigned char w0 = t.dtls.w0; 46 | unsigned char w1 = t.dtls.w1; 47 | unsigned char w2 = t.dtls.w2; 48 | unsigned char w3 = t.dtls.w3; 49 | 50 | if (w0) { 51 | putchar(w0);putchar(w1);putchar(w2);putchar(w3); 52 | } else if (w2) { 53 | putchar(w2);putchar(w3); 54 | } else { 55 | putchar(w3); 56 | } 57 | } 58 | 59 | #endif // 60 | --------------------------------------------------------------------------------