本文辑录了《算法之美——隐匿在数据结构背后的语言》(电子工业出版社2016年出版)一书第1~2章之代码(P1~P61)。全文文件夹、“45个算法”文件夹、“22个经典问题文件夹”,以及有奖捉虫活动详情请见例如以下链接:http://blog.csdn.net/baimafujinji/article/details/50484348
附录中的经典笔试、面试问题參考答案请见:
http://blog.csdn.net/baimafujinji/article/details/50484683
探秘算法世界。求索数据结构之道;汇集经典问题,畅享编程技法之趣;点拨求职热点,敲开业界名企之门。
网上书店:
京东链接: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),内有很多其它资源等你,而你在读书中遇到的疑问也将得到我第一时间的解答。
很多其它关注本博客,我将陆续公布该书所有源码至本博客。
P2:C++中的原子数据类型与它们所占的存储空间
#include <iostream> using namespace std; int main(int argc, char** argv) { cout << "bool: " << sizeof(bool) << endl; cout << "char: " << sizeof(char) << endl; cout << "short: " << sizeof(short) << endl; cout << "int: " << sizeof(int) << endl; cout << "long: " << sizeof(long) << endl; cout << "float: " << sizeof(float) << endl; cout << "double: " << sizeof(double) << endl; return 0; }
P25:变量与地址
#include "stdafx.h" #pragma runtime_checks( "", off ) int _tmain(int argc, _TCHAR* argv[]) { int a = 97; int b = 98; int c = 99; return 0; }
P29:使用指针变量
#include "stdafx.h" #include "iostream" #pragma runtime_checks( "", off ) using namespace std; int _tmain(int argc, _TCHAR* argv[]) { unsigned int a = 5; unsigned int *pint = NULL; cout << "&a = " << &a << endl << " a = " << a << endl; cout << " &pint = " << &pint << endl << " pint = " << pint << endl; cout << " &(*pint) = " << &(*pint) << endl << endl; pint = &a; cout << "&a = " << &a << endl << " a = " << a << endl; cout << " &pint = " << &pint << endl << " pint = " << pint << endl; cout << " &(*pint) = " << &(*pint) << endl << endl; *pint = 10; cout << "&a = " << &a << endl << " a = " << a << endl; cout << " &pint = " << &pint << endl << " pint = " << pint << endl; cout << " &(*pint) = " << &(*pint) << endl << endl; system("PAUSE"); return 0; }
P32:函数的參数传递——按值传递
#include <iostream> using namespace std; void fun(int x) { cout<< “x = ”<<x<<endl; x++; cout<< “x = ”<<x<<endl; } int main(int argc, char** argv) { int x = 0; cout<<"x = " <<x<<endl; fun(x); cout<<"x = " <<x<<endl; return 0; }
P33:按值传递对象
#include <iostream> using namespace std; class Student { string name; int age; public: Student() : name(""), age(0) {} void set_age(int age) {this->age = age;} int get_age() { return age;} void set_name(string name) {this->name = name;} string get_name() { return name;} }; void increment_age(Student s) { s.set_age(s.get_age() + 1); } int main(int argc, char** argv) { Student s; s.set_name("Wumingshi"); s.set_age(20); increment_age(s); cout << s.get_age() << endl; return 0; }
P34:函数的參数传递——指针传递
#include <iostream> using namespace std; void fun(int* p) { cout<< "*p = "<<*p<<endl; (*p)++; cout<< "*p = "<<*p<<endl; } int main(int argc, char** argv){ int x = 0; cout<<"x = " <<x<<endl; fun(&x); cout<<"x = " <<x<<endl; return 0; }
P35:函数的參数传递——引用传递
#include <iostream> using namespace std; void fun(int& r) { cout<< "r = "<<r<<endl; r++; cout<< "r = "<<r<<endl; } int main(int argc, char** argv){ int x = 0; cout<<"x = " <<x<<endl; fun(x); cout<<"x = " <<x<<endl; return 0; }
P36:採用引用传递方式来传递指针
#include <iostream> using namespace std; void first_bigger(int*& p, int threshold) { while (*p <= threshold) { p++; } } int main(int argc, char** argv) { int numbers[] = {0, 12, 32, 44, 33, 5, 85, 45, 100, 75}; int* result = &numbers[0]; cout <<"Begin at: "<< *result << endl; first_bigger(result, 60); cout <<"Result is: "<< *result << endl; return 0; }
P39-1:数组的使用(数组元素求和)
#include <iostream> using namespace std; int main(int argc, char* argv[]) { int a[10] = {1, 32, 65, 2, 100, 34, 33, 21, 10, 1}; int sum = 0; for(int i = 0; i < 10; i++){ sum = sum + a[i]; } cout << "数组中元素的和为 " << sum<< endl; return 0; }
P39-2:数组的越界訪问
#include <iostream> using namespace std; int main(int argc, char* argv[]) { int a[5] = {1, 2, 3, 4, 5}; int b[5] = {6, 7, 8, 9, 10}; cout << b[6] << endl; return 0; }
P41:矩阵转置
#include <iostream> using namespace std; int main(int argc, char** argv) { int a[4][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, {12, 13, 14, 15}}; int i = 0; int j = 0; int tmp = 0; for(i =0; i < 4; i++) { for(; j < 4; j++) { tmp = a[i][j]; a[i][j] = a[j][i]; a[j][i] = tmp; } j=i+1; } for(i = 0; i < 4; i++) { for(j = 0; j < 4; j++) { cout<<a[i][j]<<" "; } cout<<endl; } return 0; }
P42:数组与指针的关系
#include <iostream> using namespace std; int main(int argc, char* argv[]) { int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int * p; p = &a[0]; cout<< a[0] <<endl; cout<< &a[0]<<endl; cout<< &a<<endl; cout<< a <<endl; cout<< p <<endl; cout<< *p<<endl; return 0; }
P43:自加运算符与指针
#include <iostream> using namespace std; int main(int argc, char* argv[]) { int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int * p; p = &a[0]; cout<< *(p++)<<endl; p = &a[0]; cout<< *p++<<endl; p = &a[0]; cout<< *(++p)<<endl; return 0; }
P44:指针訪问多维数组
#include <iostream> using namespace std; int main(int argc, char* argv[]){ int a[3][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; int * p; p = &a[0][0]; for(int i = 0; i<9; i++) cout<<*p++<<endl; return 0; }
P46:数组的抽象数据类型
头文件
#ifndef ARRAY_H #define ARRAY_H #include <iostream> using namespace std; const int DefaultSize = 20; template <class Type> class Array { Type *elements; //数组存放空间 int ArraySize; //当前长度 public: Array(int Size=DefaultSize); //构造函数 Array(const Array<Type>& x); //拷贝构造函数 ~Array() {delete []elements;} //析构函数 Array<Type> & operator = (const Array<Type> & rhs); //数组复制 Type& operator [] ( int i ); //取元素值 int Length () const { return ArraySize; } //取数组长度 void ReSize (int sz); //扩充数组 }; template <class Type> Array<Type>& Array<Type >::operator= (const Array<Type >& rhs) { int n = rhs. ArraySize; // 取rhs的数组大小 if (ArraySize != n) { delete [] elements; // 删除数组原有内存 elements = new Type[n]; // 又一次分配n个元素的内存 if (elements == NULL) //假设分配内存不成功,输出错误信息 { ArraySize = 0; cerr << "存储分配错误!" << endl; exit(1); } ArraySize = n; //记录本对象的数组大小 } // 从rhs向本对象复制元素 Type* destptr = elements; Type* srcptr = rhs. elements; while (n--) *destptr++ = *srcptr++; return *this; // 返回当前对象的引用 } template <class Type> Array<Type> :: Array (int sz) { if ( sz <= 0 ) { ArraySize = 0; cerr << "非法数组大小" << endl; return; } elements = new Type[sz]; if (elements == NULL) { ArraySize = 0; cerr << "存储分配错误!" << endl; exit(1); } ArraySize = sz; } template <class Type> Array<Type> :: Array (const Array<Type> & x ) { int n = x.ArraySize; ArraySize = n; elements = new Type[n]; if ( elements == NULL ) { ArraySize = 0; cerr << "存储分配错" << endl; exit(1); } Type *srcptr = x.elements; Type *destptr = elements; while ( n-- ) * destptr++ = * srcptr++; } template <class Type> Type& Array<Type> :: operator [] (int i){ if ( i < 0 || i > ArraySize-1 ) { cerr << "数组下标超界" << endl; exit(1); } return elements[i]; } template <class Type> void Array<Type> :: ReSize (int sz) { if (sz >= 0 && sz != ArraySize) { Type * newarray = new Type[sz]; //创建新数组 if (newarray == NULL) { cerr << "存储分配错" << endl; return; } int n = (sz <= ArraySize) ? sz : ArraySize; //按新的大小确定传送元素个数 Type *srcptr = elements; //源数组指针 Type *destptr = newarray; //目标数组指针 while (n--) * destptr++ = * srcptr++; delete [] elements; elements = newarray; ArraySize = sz; } } #endif
測试程序
#include <iostream> #include <iomanip> #include "Array.h" using namespace std; int main(int argc, char** argv) { Array<int> A(10); int n; int primecount = 0, i, j; cout << "Enter a value >= 2 as upper limit for prime numbers: "; cin >> n; A[primecount++] = 2; // 2是一个质数,[]下标运算 for(i = 3; i < n; i++) { if (primecount == A.Length()) A.ReSize(primecount + 10); if (i % 2 == 0) continue; j = 3; while (j <= i/2 && i % j != 0) j += 2; if (j > i/2) A[primecount++] = i; } for (i = 0; i < primecount; i++) { cout << setw(5) << A[i]; if ((i+1) % 10 == 0) cout << endl; } cout << endl; return 0; }
P49:Z字形编排问题
请參见博文——ZigZag排列问题与经典笔试面试题目解析
(链接地址:http://blog.csdn.net/baimafujinji/article/details/50388584)
P51:大整数乘法问题
#include <iostream> #include <memory.h> #define SIZE 14 using namespace std; // 返回位数为size1+size2 int* multi(int* num1, int size1, int* num2, int size2) { int size = size1 + size2; int* ret = new int[size]; int i = 0; memset(ret, 0, sizeof(int) * size); for (i = 0; i < size2; ++i) { int k = i; for (int j = 0; j < size1; ++j) ret[k++] += num2[i] * num1[j]; } for (i = 0; i < size; ++i) { if (ret[i] >= 10) { ret[i+1] += ret[i] / 10; ret[i] %= 10; } } return ret; } int main(int argc, char** argv) { int num1[SIZE] = {1,2,3,4,5,6,7,8,9,1,1,1,1,1};//第一个大整数 11111987654321 int num2[SIZE] = {1,1,1,2,2,2,3,3,3,4,4,4,5,5};//第二个大整数 55444333222111 int* ret = multi(num1, SIZE, num2, SIZE); for (int i = SIZE*2-1; i >= 0; i--) cout << ret[i]; delete[] ret; //释放内存 return 0; }
P52:九宫格问题
#include <iostream> #include <iomanip> #include <memory.h> using namespace std; int main() { cout<<"请输入幻方的大小n(n是一个大于1的奇数):"; int n=1; cin>>n; cout<<endl; int **a = new int*[n]; for(int i=0; i<n; ++i){ a[i]=new int[n]; memset(a[i], 0, n*sizeof(int)); } int row=0; int col=n/2; for(int i=1; i<=n*n; i++) { a[row][col]=i; row--; col++; if(row<0&&col>=n) { col--; row+=2; } else if(row<0) { row=n-1; } else if(col>=n) { col=0; } else if(a[row][col]!=0) { col--; row+=2; } } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { cout<<setw(6)<<a[i][j]; } cout<<endl; } for(int i = n; i > 0;) delete[] a[--i]; delete[] a; return 0; }
P55:用new来创建对象
#include <iostream> using namespace std; class Point { int x; int y; public: Point() { x = 0; y = 0; }; Point(int xx, int yy) { x = xx; y = yy; }; ~Point(){cout<<"END"<<endl;}; int getX(){return x;}; int getY(){return y;}; void setX(int newX){x = newX;}; void setY(int newY){y = newY;}; }; int main(int argc, char** argv) { Point * point1 = new Point; Point * point2 = new Point(3, 5); cout<<point1->getX()<<endl; cout<<point2->getX()<<endl; delete point1; delete point2; return 0; }