本文辑录了《算法之美——隐匿在数据结构背后的语言》(电子工业出版社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;
}原文:http://blog.csdn.net/baimafujinji/article/details/50483247