算法之美_源代码发布(2)

本文辑录了《算法之美——隐匿在数据结构背后的语言》(电子工业出版社2016年出版)一书第3章之代码(P62~P90)。全文目录、“45个算法”目录“22个经典问题目录”,以及有奖捉虫活动详情请见如下链接:http://blog.csdn.net/baimafujinji/article/details/50484348

附录中的经典笔试、面试问题参考答案请见:

http://blog.csdn.net/baimafujinji/article/details/50484683

算法之美_源代码发布(2)_第1张图片

内容简介:探秘算法世界,求索数据结构之道;汇集经典问题,畅享编程技法之趣;点拨求职热点,敲开业界名企之门。本书围绕算法与数据结构这个话题,循序渐进、深入浅出地介绍了现代计算机技术中常用的四十余个经典算法,以及回溯法、分治法、贪婪法和动态规划等算法设计思想。在此过程中,本书也系统地讲解了链表(包括单向链表、单向循环链表和双向循环链表)、栈、队列(包括普通队列和优先级队列)、树(包括二叉树、哈夫曼树、堆、红黑树、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;
}

P74:KMP算法


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;
}

P82:BMH算法


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;
}

P88:N元距离模型


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;
}

本章补充程序:BM算法


#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;
}




你可能感兴趣的:(数据结构,C++,算法)