本文辑录了《算法之美——隐匿在数据结构背后的语言》(电子工业出版社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;
}