《算法之美》第一二章读书笔记

第一章:

1.分治法和动态规划(dp)的区别:

1)分治法(自顶向下):

主要用递归操作,并且各个部分之间没有联系。需要递归若干次并且需要重复计算已经计算好的数据。因此效率低

function Devide(x){
 if(足够小并且简单)
{
return x;
}
else{
for (int i=0;i<n;i++)
{
devide(xi);//进行递归
}
}
}

主要应用:

传染病问题,二分搜索,快速排序,矩阵乘法,汉诺塔问题

2)动态规划(自底向上)

主要通过之前已知的数据,推导出另一部分的数据,各个数据之间联系很大。

不需要重复计算已知的值,但是有的时候会计算出后期完全没有用到的数据,效率高于分治法。

主要应用:

快速傅里叶;多边形最优分割;找零钱问题;最短路径问题;背包问题;链式乘法问题

第二章:指针与数组

1.指针与自增

*p++  <==> *(p++),因为++和*是同一优先级,因此按照从右到左的结合顺序;该语句表示:获取当前p指针的值,然后将指针后移

(*p)++,表示读取p指针当中的内容,然后自增1

*++p和*(++p)是一样的,都是指针后移1位之后,读取p指针的指向的后一个数据;

2.z字形问题:

// ch2-2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
/*
Z字形编排问题
*/
#include<iostream>
#include<iomanip>//用来格式化输出结果
using namespace std;

#define SIZE 8

int _tmain(int argc, _TCHAR* argv[])
{
	int matrix[SIZE][SIZE] = {0};
	int a[SIZE][SIZE] = {0};
	int *p = &matrix[0][0];



	for (int i = 0; i < SIZE*SIZE; i++)
	{
		*p++ = i;
	
	}
	cout << "原始矩阵----------------------------\n";
	//原始矩阵是从0~63的8*8的矩阵
	for (int i = 0; i < SIZE; i++)
	{
		for (int j = 0; j < SIZE; j++)
		{
			cout << setw(4) << *(*(matrix+i)+j);
		
		}
		cout << endl;
	}

	int i = 0, j = 0;

	for (int x = 0; x < SIZE; x++)
	{
		for (int y = 0; y < SIZE; y++)
		{
			*(*(a + i) + j) = *(*(matrix + x) + y);//将matrix的内容按照某一个特定的顺序复制到a矩阵当中。
			//case1:如果在第0行或者是第size-1行,并且是偶数列的时候,向右移动
			if ((i == 0 || i == SIZE - 1 )&& j % 2 == 0)
			{
				j++;
				continue;
			
			}
			//case2:如果在第0列或者第size-1列,并且是奇数行的时候,向下移动
			if ((j == 0 || j == SIZE - 1) && i % 2 == 1)
			{
				i++;
				continue;
			
			}
			//case3:如果(i+j)%2是偶数,那么就向右上移动
			if ((i + j) % 2 == 0)
			{
				i--;
				j++;
				continue;
			
			}
			//case4:如果(i+j)%2是奇数,那么就向左下移动
			else if ((i + j) % 2 == 1)
			{
				i++;
				j--;
				continue;
			
			}
		
		}
	
	}

	cout << "经过Z字形转变之后\n";
	for (int i = 0; i < SIZE; i++)
	{
		for (int j = 0; j < SIZE; j++)
		{
			cout << setw(4) << *(*(a + i) + j);
		
		}
		cout << endl;
	
	}



	return 0;
}

2.3大数乘法问题:

大数问题的集合:http://blog.csdn.net/lisp1995/article/category/6384570

输入数据:从右往左输入数据:

若想输入12345,那么a[0]=5,a[1]=4,a[2]=3,a[3]=2,a[4]=1

// ch2-3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

/*
大数乘法:输入是从右向左输入的,eg:
若想输入12345,那么a[0]=5,a[1]=4,a[2]=3,a[3]=2,a[4]=1

*/
#include<iostream>
#include<memory.h>
using namespace std;
#define SIZE 3
int* multi(int size1, int *num1, int size2, int *num2)
{
	int size = size1 + size2;
	int *result = new int[size];
	
	
	memset(result, 0, sizeof(int)*size);

	for (int i=0; i < size1; i++)
	{
		int k = i;
		for (int j = 0; j < size2; j++)
		{
			result[k++] += num1[j] * num2[i];
		
		}
	
	}
	//对于计算结果进行修改,将大于10的进行取模进位
	for (int i = 0; i < size; i++)
	{
		if (result[i]>10)
		{
		
			result[i + 1] += result[i] / 10;//进位
			result[i] %= 10;//保留当前位的个位
		}
	
	}
	return result;
}



int _tmain(int argc, _TCHAR* argv[])
{
	int num1[SIZE] = { 2, 2 };

	int num2[SIZE] = { 1, 2 };

	//cout << length(num1) << endl;
	//cout << length(num2) << endl;
	int *result = multi(3, num1, 3, num2);
	//输出22*21的结果,从右往左进行计算,num1[0]是个位
	for (int i = 3 * 2 - 1; i >= 0; i--)
	{
	
		cout << result[i];
	}
	delete[] result;
	return 0;
}

    原文作者:Z字形编排问题
    原文地址: https://blog.csdn.net/mdjxy63/article/details/79147809
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞