本文辑录了《算法之美——隐匿在数据结构背后的语言》(电子工业出版社2016年出版)一书第3章之代码(P62~P90)。全文目录、“45个算法”目录、“22个经典问题目录”,以及有奖捉虫活动详情请见如下链接:http://blog.csdn.net/baimafujinji/article/details/50484348
附录中的经典笔试、面试问题参考答案请见:
http://blog.csdn.net/baimafujinji/article/details/50484683
内容简介:探秘算法世界,求索数据结构之道;汇集经典问题,畅享编程技法之趣;点拨求职热点,敲开业界名企之门。本书围绕算法与数据结构这个话题,循序渐进、深入浅出地介绍了现代计算机技术中常用的四十余个经典算法,以及回溯法、分治法、贪婪法和动态规划等算法设计思想。在此过程中,本书也系统地讲解了链表(包括单向链表、单向循环链表和双向循环链表)、栈、队列(包括普通队列和优先级队列)、树(包括二叉树、哈夫曼树、堆、红黑树、AVL树和字典树)、图、集合(包括不相交集)与字典等常用数据结构。同时,通过对二十二个经典问题(包括约瑟夫环问题、汉诺塔问题、八皇后问题和骑士周游问题等)的讲解,逐步揭开隐匿在数据结构背后的算法原理,力图帮助读者夯实知识储备,激活思维技巧,并最终冲破阻碍编程能力提升的重重藩篱。辅有完整的C++源代码,并穿插介绍了STL中的各种容器。
网上书店:
京东链接:http://item.jd.com/10111000454.html
http://item.jd.com/10111372484.html
China-pub中国互动出版网:http://product.china-pub.com/4911922
亚马逊:http://www.amazon.cn/%E7%AE%97%E6%B3%95%E4%B9%8B%E7%BE%8E-%E9%9A%90%E5%8C%BF%E5%9C%A8%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E8%83%8C%E5%90%8E%E7%9A%84%E5%8E%9F%E7%90%86-%E5%B7%A6%E9%A3%9E/dp/B01AGNUIE8/ref=sr_1_8?ie=UTF8&qid=1453527399&sr=8-8&keywords=%E5%B7%A6%E9%A3%9E
电子工业出版社官方链接:http://www.phei.com.cn/module/goods/wssd_content.jsp?bookid=44441
如果你是该书的读者,请务必加算法学习群(495573865),内有更多资源等你,而你在读书中遇到的疑问也将得到我第一时间的解答。更多关注本博客,我将陆续发布该书全部源代码至本博客。
P64:字符串的使用示例
#include <iostream> #include <iomanip> #include <string> using namespace std; int main(int argc, char** argv) { string str = "高德纳 美国 计算机科学家 计算机程序设计艺术"; string str_temp = ""; str_temp.assign(str); string result[4]={"","","",""}; int position = 0; for(int i = 0; i < 3; i++) { position = str_temp.find(" "); result[i] = str_temp.substr(0, position); str_temp = str_temp.substr(position + 1, str_temp.length() - position); } result[3] = str_temp; cout<<"姓名:"<<setw(8)<<result[0]<<endl; cout<<"国籍:"<<setw(6)<<result[1]<<endl; cout<<"职业:"<<setw(14)<<result[2]<<endl; cout<<"代表作:"<<setw(18)<<result[3]<<endl; str_temp.swap(result[0]); for(int j = 1; j < 4; j++) { str_temp+=" "; str_temp.append(result[j]); } int equal = str.compare(str_temp); if(equal==0) { cout<<"Successful Matching!"<<endl; } else cout<<"Unsuccessful Matching!"<<endl; return 0; }
P65:字符串的抽象数据类型
const int maxLen = 128; class String { int curLen; //字符串的长度 char * c; //串的存储数组 public: //构造函数 String ( const String& ob ); String ( const char * init ); String ( ); //析够函数 String ( ) {delete [] c;} int Length ( ) const {return curLen;} //求当前串的实际长度 int Find ( String& pat ) const; //在当前串中查找目标串 //取当前字符串中从pos开始len个字符组成的子串 String &operator ( ) ( int pos, int len ); //判当前字符串与对象串ob是否相等 int operator == ( const String &ob ) const { return strcmp (ch, ob.ch) == 0; } //判当前字符串与对象串ob是否不等 int operator != ( const String &ob )const { return strcmp (ch, ob.ch) != 0; } int operator ! ( )const { return curLen == 0; } //判当前字符串是否为空串 String &operator = (String &ob); //将串ob赋给当前字符串 String &operator += (String &ob); //将串ob连接到当前字符串之后 char &operator [ ] ( int i ); //取当前字符串的第i个字符 }; String :: String ( const String& ob ) { c = new char[maxLen+1]; //创建串数组 if ( c == NULL ) { cerr << “存储空间分配错误! \n”; exit(1); } curLen = ob.curLen; //复制串长度 strcpy ( c, ob.c ); //复制串值 } String :: String ( const char *init ) { c = new char[maxLen+1]; //创建串数组 if ( c == NULL ){ cerr << “存储空间分配错误! \n”; exit(1); } curLen = strlen ( init ); //复制串长度 strcpy ( c, init ); //复制串值 } String :: String () { c = new char[maxLen+1]; //创建串数组 if ( ch == NULL ) { cerr << “存储空间分配错误!\n”; exit(1); } curLen = 0; c[0] = ‘\0’; }
P71:MP算法
void preMp(const char *x, int m, int mpNext[]) { int i, j; i = 0; j = mpNext[0] = -1; while (i < m) { while (j > -1 && x[i] != x[j]) j = mpNext[j]; mpNext[++i] = ++j; } } void MP(string p, string t) { int m = p.length(); int n = t.length(); if (m > n){ cerr<<"Unsuccessful match!"<<endl; return; } const char * x = p.c_str(); const char * y = t.c_str(); int i = 0, j = 0, result = -1, mpNext[m+1]; preMp(x, m, mpNext); while (j < n) { while (i > -1 && x[i] != y[j]) i = mpNext[i]; i++; j++; if (i >= m) { cout<<"Matching index found at: "<<j - i<<endl; i = mpNext[i]; } } }
int main(int argc, char** argv) { string p1 = "abcabcad"; string p2 = "adcadcad"; string p3 = "ababcaabc"; string t = "ctcabcabcadtcaabcabcadat"; cout<<"MP : "<<endl; MP(p1, t); cout<<endl; // cout<<"MP : "<<endl; // MP(p2, t); // cout<<endl; // cout<<"MP : "<<endl; // MP(p3, t); return 0; }
void preKmp(const char *x, int m, int kmpNext[]) { int i, j; i = 0; j = kmpNext[0] = -1; while (i < m) { while (j > -1 && x[i] != x[j]) j = kmpNext[j]; i++; j++; if (x[i] == x[j]) kmpNext[i] = kmpNext[j]; else kmpNext[i] = j; } } void KMP(string p, string t) { int m = p.length(); int n = t.length(); if (m > n) return ; const char * x = p.c_str(); const char * y = t.c_str(); int i = 0, j = 0, kmpNext[m+1]; preKmp(x, m, kmpNext); for(int k =0; k<=m; k++) cout<<setw(3)<<kmpNext[k]<<" "; cout<<endl; i = j = 0; while (j < n) { while (i > -1 && x[i] != y[j]) i = kmpNext[i]; i++; j++; if (i >= m) { cout<<"Matching index found at: "<<j - i<<endl; i = kmpNext[i]; } } }
int main(int argc, char** argv) { string p1 = "abcabcad"; string p2 = "adcadcad"; string p3 = "ababcaabc"; string t = "ctcabcabcadtcaabcabcadat"; cout<<"KMP: "<<endl; KMP(p1, t); // cout<<"KMP: "<<endl; // KMP(p2, t); // cout<<"KMP: "; // KMP(p3, t); return 0; }
const int MAXCHAR = 256; void PreProcess(const char * patt, int m, int bmBc[]) { int k = 0; for (k = 0; k < MAXCHAR; k++) bmBc[k] = m; for (k = 0; k < m - 1; k++) { bmBc[patt[k]] = m - k - 1; } } int BMS(string t, string p) { int bmBc[MAXCHAR]; int m = p.length(); const char * patt = p.c_str(); PreProcess(patt, m, bmBc); const char * text = t.c_str(); int n = t.length(); if (m > n) return -1; int k = m - 1; while (k < n) { int j = m - 1; int i = k; while (j >= 0 && text[i] == patt[j]) { j--; i--; } if (j == -1) return i + 1; k += bmBc[text[k]]; } return -1; }
#include <iostream> #include <string> using namespace std; int main(int argc, char** argv) { string p = "GTTAC"; string t = "GCCTCATCCUACGTTAC"; cout<<BMS(t,p)<<endl; return 0; }
int N_gram(string x, string y, int n) { int lp = x.length(); int lt = y.length(); int num_x = lp-n+1; int num_y = lt-n+1; int num_s = 0; for(int i = 0; i < num_x; i++){ string sub_str = x.substr(i, n); if(y.find(sub_str)!=-1) num_s++; } return num_x + num_y - 2*num_s; }
#include <iostream> #include <string> using namespace std; int main(int argc, char** argv) { int N = 2; string p = "Gorbachev"; string t = "Gorbechyov"; cout<<N_gram(p, t, N)<<endl; return 0; }
#include <iostream> #include <string> using namespace std; #define XSIZE 8 #define ASIZE 4 void preBmBc(char *x, int m, int bmBc[]) { int i; for (i = 0; i < ASIZE; ++i) bmBc[i] = m; for (i = 0; i < m - 1; ++i) bmBc[x[i]] = m - i - 1; } void suffixes(char *x, int m, int *suff) { int f, g, i; suff[m - 1] = m; g = m - 1; for (i = m - 2; i >= 0; --i) { if (i > g && suff[i + m - 1 - f] < i - g) suff[i] = suff[i + m - 1 - f]; else { if (i < g) g = i; f = i; while (g >= 0 && x[g] == x[g + m - 1 - f]) --g; suff[i] = f - g; } } } void preBmGs(char *x, int m, int bmGs[]) { int i, j, suff[XSIZE]; suffixes(x, m, suff); for (i = 0; i < m; ++i) bmGs[i] = m; j = 0; for (i = m - 1; i >= 0; --i) if (suff[i] == i + 1) for (; j < m - 1 - i; ++j) if (bmGs[j] == m) bmGs[j] = m - 1 - i; for (i = 0; i <= m - 2; ++i) bmGs[m - 1 - suff[i]] = m - 1 - i; } void BM(char *x, int m, char *y, int n) { int i, j, bmGs[XSIZE], bmBc[ASIZE]; //预处理 preBmGs(x, m, bmGs); preBmBc(x, m, bmBc); // for(int k = 0; k < ASIZE; k++) // cout<<bmBc[k]<<k<<" "; // cout<<endl; //匹配 j = 0; while (j <= n - m) { for (i = m - 1; i >= 0 && x[i] == y[i + j]; --i); if (i < 0) { cout<<"模式串出现在目标串中的位置是:"<<j<<endl; j += bmGs[0]; } else j += (bmGs[i])>(bmBc[y[i + j]] - m + 1 + i)? (bmGs[i]):(bmBc[y[i + j]] - m + 1 + i); } } int main(int argc, char** argv) { char x[] = {'G','C','A','G','A','G','A','G'}; char y[] = {'G','C','A','T','C','G','C','A','G','A','G','A','G','T', 'A','T','A','C','A','G','T','A','C','G'}; char * px = &x[0]; char * py = &y[0]; int m = 8; int n = 24; BM(px, m, py, n); return 0; }