关于抽象思维

  • 我们需要快速应对世界的复杂多变性,我们就需要有抽象思维
  • 抽象思维可以帮助我们提取共性,应对变化
  • 抽象思维是我们认识和表达复杂世界的关键
  • 抽象思维可以帮助我们分析藏在复杂现象背后的本质和规律

对比算法,发现共性

1 ) 对比下楼问题和跳马问题

  • 两个问题的具体分析在前面的文章中已经完成,我们来对比一下两者
  • 两者结构很像,都用递归枚举算法, 下楼问题有三个分叉,跳马问题有四个分叉
  • 两者与或图基本相同,在算法上是同一类问题,可以使用基本相同的程序来求解
  • 两个不同场景下的问题是具有同一性质,但是它们并不能用同一个程序来做,因为它们之间是有差异的
  • 两个问题的差异
    • 是否达到目标不一致:对下楼而言,高度是否为0;跳马问题,位置坐标是否等于(8,4)
    • 新位置的计算:对下楼而言,高度只需要减下来;跳马问题,需要根据规则计算落点坐标
    • 判断是否合法:对下楼而言,剩余高度大于等于0;跳马问题,要保证在棋盘之上

2 ) 下楼问题算法重构

#include <iostream>
using namespace std;int h;
int num;
struct position { int x; };
position dxy[] = {{1}, {2}, {3}};
position start_pos = {0}, goal_pos = {h};
position path[100];/* --------------------- 辅助函数 开始 ------------------------ */
bool IsEq(position pos1, position pos2) { return (pos1.x == pos2.x);
}
bool IsDone(position pos) {return IsEq(pos, goal_pos);
}bool IsValid(position pos) {return (pos.x >=0) && (pos.x <= h);
}position GetNewPos(position pos, int k) {position next_pos = {pos.x + dxy[k].x};return next_pos;
}
void LogStep(int step, position pos) {path[step] = pos;
}void OutStep(position pos) { cout << pos.x << ' ';
}void OutAll(int step) {for (int i=0; i<step; i++) {OutStep(path[i]);}cout << endl;
}
/* --------------------- 辅助函数 结束 ------------------------ */// 递归函数
void Jump(position pos, int step) {// 是否达到目标if(IsDone(pos)) {num++; // 方案数+1cout << "当前位置" << num << ": ";OutAll(step); // 输出方案return;}// 遍历N种方案for (int k = 0; k < sizeof(dxy) / sizeof(dxy[0]); k++) {position next_pos = GetNewPos(pos, k);if(!IsValid(next_pos)) {continue; // nex_pos是否可行?}LogStep(step, next_pos); // 记录方案Jump(next_pos, step + 1); // 走下一步}
}// main函数
int main() {// 要求用户输入来更新最终位置cout << "请输入楼梯台阶数:"; cin >> h;position h_num = {h};goal_pos = h_num;num = 0; // 初始方案数置0Jump(start_pos, 0); // 走第一步cout << "总方案数: " << num << endl;return 0;
}
  • 这个下楼问题算法重构是逆向思维转化为上楼问题,都是状态的转变
  • 当然稍微修改下算法就可以变成下楼问题了,两者方案都是一样的解决方案
  • 之前的算法是输出步骤,现在的算法是输出位置

3 ) 跳马问题算法重构

#include <iostream>
using namespace std;struct position { int x, y; };
position dxy[] = {{1,2}, {2,1}, {2, -1}, {1, -2}};
position start_pos = {0, 0}, goal_pos = {8, 4};
position path[100];
int num;/* --------------------- 辅助函数 开始 ------------------------ */
bool IsEq(position pos1, position pos2) {return (pos1.x == pos2.x) && (pos1.y == pos2.y);
}bool IsDone(position pos) {return IsEq(pos, goal_pos);
}bool IsValid(position pos) {return (pos.x >= 0) && (pos.x <= 8) && (pos.y >= 0) && (pos.y <= 4);
}position GetNewPos(position pos, int k) {position next_pos = {pos.x + dxy[k].x, pos.y + dxy[k].y}; return next_pos;
}
void LogStep(int step, position pos) {path[step] = pos;
}void OutStep(position pos) {cout << "(" << pos.x << ", "<< pos.y << ") ";
}
void OutAll(int step) {for (int i=0; i<step; i++) OutStep(path[i]);cout << endl;
}
/* --------------------- 辅助函数 结束 ------------------------ */void Jump(position pos, int step) {// 是否达到目标if(IsDone(pos)) {num++; // 方案数+1cout << "当前位置" << num << ": ";OutAll(step); // 输出方案return;}// 遍历N种方案for (int k = 0; k < sizeof(dxy) / sizeof(dxy[0]); k++) {position next_pos = GetNewPos(pos, k);if(!IsValid(next_pos)) {continue; // nex_pos是否可行?}LogStep(step, next_pos); // 记录方案Jump(next_pos, step + 1); // 走下一步}
}int main() {num = 0; // 初始方案数置0 Jump(start_pos, 0); // 走第一步cout << "总方案数:" << num << endl;return 0;
}
  • 从两个问题的算法重构可以看出:

    • 通过辅助函数把两个问题的共同特点找回来了,同时把差异的地方隔离开来
    • 递归程序完全相同,main函数也趋近一致
    • 不管是下马,跳楼,还是是类似的问题,只要稍微修改下,即可成为一个solid的解决方案
  • 所以算法重构有很多的好处

4 ) 下楼和跳马问题通用算法框架

void Jump(position pos, int step) {// 是否达到目标if(IsDone(pos)) {num++; // 方案数+1cout << "当前位置" << num << ": ";OutAll(step); // 输出方案return;}// 遍历N种方案for (int k = 0; k < sizeof(dxy) / sizeof(dxy[0]); k++) {position next_pos = GetNewPos(pos, k);if(!IsValid(next_pos)) {continue; // nex_pos是否可行?}LogStep(step, next_pos); // 记录方案Jump(next_pos, step + 1); // 走下一步}
}int main() {num = 0; // 初始方案数置0 Jump(start_pos, 0); // 走第一步 return 0;
}
  • 总结一下,这类算法框架的三个关键点:

    • 判断结束状态
    • 产生新的状态
    • 判断是否合法

数据结构与算法笔记:抽象思维之对比算法,发现共性(下楼梯台阶和象棋跳马问题算法重构)相关推荐

  1. 推荐系统中常用算法 以及优点缺点对比

    推荐系统中常用算法 以及优点缺点对比 2014/09/20 [Martin导读]随着互联网特别是社会化网络的快速发展,我们正处于信息过载的时代.用户面对过量的信息很难找到自己真正感兴趣的内容,而内容提 ...

  2. 《算法笔记》2.3小节——C/C++快速入门-选择结构

    <算法笔记>2.3小节--C/C++快速入门->选择结构 Contest100000567 - <算法笔记>2.3小节--C/C++快速入门->选择结构 Conte ...

  3. 数据结构与算法笔记:抽象思维之转换视角,提炼共性(分书和八皇后问题算法重构)

    转换视角,提炼共性 有时算法本身乍一看是不一样的,而且很不一样,比较结构特点,看不出来有什么共性 如果我们转换下看问题的视角,是否能够找到共性呢 1 ) 对比分书问题和八皇后问题 这两个问题,其实差异 ...

  4. 明翰数据结构与算法笔记V0.8(持续更新)

    文章目录 前言 数据结构 `线性表` `数组` `链表` `栈与队列` [串/字符串] 树 并查集 `二叉树` [二叉排序树/二叉搜索树] `红黑树` 红黑树操作 霍夫曼树 `堆` [大/小]根堆 可 ...

  5. 算法笔记(三)特殊数据结构——哈希表、有序表、并查集、KMP、Manacher、单调栈、位图、大数据类题

    layout: post title: 算法笔记(三)特殊数据结构--哈希表.有序表.并查集.KMP.Manacher.单调栈.位图.大数据类题 description: 算法笔记(三)特殊数据结构- ...

  6. 数据结构与算法笔记 - 绪论

    数据结构与算法笔记 - 绪论 1. 什么是计算 2. 评判DSA优劣的参照(直尺) 3. 度量DSA性能的尺度(刻度) 4. DSA的性能度量的方法 5. DSA性能的设计及其优化 x1. 理论模型与 ...

  7. 数据结构源码笔记(C语言):置换-选择算法

    //实现置换-选择算法#include<stdio.h> #include<malloc.h> #include<string.h> #include<std ...

  8. 数据结构源码笔记(C语言):哈希表的相关运算算法

    //实现哈希表的相关运算算法 #include<stdio.h> #include<malloc.h> #include<string.h>#define MaxS ...

  9. 数据结构源码笔记(C语言):二叉平衡树的相关操作算法

    //二叉平衡树的相关运算 #include<stdio.h> #include<malloc.h> #include<string.h>typedef char I ...

最新文章

  1. php多文件上传类源码,PHP单文件上传类或多文件上传类源码
  2. ZedGraph曲线图实现X轴与Y轴可拖动,并且对应曲线也一起移动
  3. 20189211 《网络攻防》第五周作业
  4. Swift-binary search tree
  5. Effective Java之静态工厂代替构造器(一)
  6. Springboot配置不当
  7. WindowsMobile应该如何发展?(未完待续)
  8. object转date类型_js-最常用的类型判断
  9. 创新创业技术路线怎么写_怎么创业起步 如何写创业计划?
  10. 2021年C++项目中的十大Bug:乍一看都正确的代码,实则暗藏玄机
  11. 2021芜湖高考成绩查询,2021芜湖市地区高考成绩排名查询,芜湖市高考各高中成绩喜报榜单...
  12. iOS 使用脚本自动化复制target
  13. ElasticSearch全文搜索引擎之Linux版安装教程
  14. Python好酷|allpairspy一款高效的正交实验法生成用例工具
  15. 批量给excel表中的每行添加表头
  16. 八类网线测试仪之深入探讨-AEM
  17. 如何把PPT连背景一起复制?
  18. Python问题:UnboundLocalError: local variable 'xxx' referenced before assignment
  19. hp1015驱动64位_在win10/win7 64位系统上安装 hp laserjet 1015对应的打印机驱动
  20. 规范化、标准化、归一化、正则化

热门文章

  1. 计算机模拟地球爆炸,模拟地球爆炸
  2. md 文件使用html阅读,使用markdow-it渲染md文件为html页面
  3. JavaFX调用虚拟键盘
  4. mac 命令行查看DNS
  5. python函数由什么组成_python的函数
  6. matlab pdepe函数边界,科学网-使用MATLAB中pdepe函数求解一维偏微分方程-邓浩鑫的博文...
  7. win10看不到家庭组计算机,win10专业版没有家庭组怎么办?一招帮你解决问题
  8. 计算机的存储器有哪2类,存储器有哪两种
  9. 快速搭建微信小程序第三方平台基础教程(一)第三方平台是做什么的
  10. 在UC浏览器投放广告的优势、效果!