算法学习笔记(一)C++排序函数、映射技巧与字典树
1.头文件algorithm中有函数sort()用于排序,参数为:排序起始地址,排序结束地址,排序规则(返回bool型)
例如,要将array[] = {5,7,1,2,9}升序排列,则使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | bool cmp( int a, int b); int main() { int array[] = {5,7,1,2,9}; sort(array,array+5,cmp); for ( int i = 0;i < 5;i++) cout << array[i] << " " ; cout << endl; return 0; } bool cmp( int a, int b) { if (a>b) return false ; else return true ; } |
注:1.在C语言中,使用qsort进行排序。
2.如果不指定排序方式,默认为升序。
2.对于有序映射关系,可以用巧妙的办法转化,例如:
ABC对应2,DEF对应3,GHI对应4,JKL对应5,MNO对应6,PRS对应7,TUV对应8,WXY对应9
要把一串字符按照这样的规则映射为数字,可以采用以下方法:
1 | (*(p+i) - 'A' - (*(p+i)> 'Q' ))/3 + 2 |
其中p为指向字符串的指针,因为每3个字母变化一次映射关系,因此只需要判断当前字符距离字符A的距离,然后除以三判断落在哪一组。需要注意的是字母Q不包含在映射关系当中,因此当字符在Q之后时,应该减去1个字符的距离再进行判断。
3.字典树是一种存放字符串的树形结构,又称为单词查找树,利用的是字符串的公共前缀来减少查询时间。需要注意的是字典树常常用于统计单词出现次数,而不是为了取出单词去存储单词。一般字典树的结构体如下:
1 2 3 4 5 | struct DirectionTree{ int count; //计数到当前节点为止的单词个数 bool terminal; //记录此节点无子节点 DirectionTree* child[26]; //该节点的子节点 }*root; //字典树的根节点,根节点不包含任何字母 |
字典树的存放方式为根连接子节点,子节点连接新的节点,一直连接到尾部。例如存储字符"abc","ad",则数据结构如下:
其中只有D3和D4两个节点的terminal值为true,count为1,其余的均为false,0。当再次添加同样的字符串时,不会创建新的节点,只会引起count加1。
完整代码如下(转):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <iostream> #include <assert.h> using namespace std; #define MAX 26 //the total number of alphabet is 26, a...z struct Dictree { bool word; int count; struct Dictree *trie[MAX]; // the 26 child } * a; int init() // init the chained list { a = new Dictree; for ( int i = 0; i < MAX; i++) { a->trie[i] = NULL; a->word = false ; } return 0; } bool searchTrie( char *str) { int len, res; Dictree *head = a; assert (head); len = strlen (str); for ( int i = 0; i < len; i++) { res = ( int )(str[i] - 'a' ); if (head->trie[res] == NULL) return false ; head = head->trie[res]; } if (head->word) return true ; return false ; } int insertTrie( char *str) { int len, res; Dictree *head = a; len = strlen (str); for ( int i = 0; i < len; i++) { res = int (str[i] - 'a' ); if (head->trie[res] == NULL) //whether the node exist? { head->trie[res] = new Dictree; head = head->trie[res]; head->count = 0; for ( int j = 0; j < MAX; j++) { head->trie[j] = NULL; head->word = false ; } } else head = head->trie[res]; } head->count++; head->word = true ; return head->count; } int main() { char str[20]; init(); for ( int i = 0; i < 10; i++) { scanf ( "%s" , str); printf ( "%d\n" , insertTrie(str)); } scanf ( "%s" , str); printf ( "%s\n" , searchTrie(str) ? ( "YES" ):( "NO" )); return 0; } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步