编程珠玑-笔记1
来源:互联网 发布:2017最新网络神曲 编辑:程序博客网 时间:2024/05/22 02:30
为什么要自己造轮子
Ex:怎样给一个磁盘文件排序?
不同的排序条件,比如待排序大小,可提供的内存空间不同,都会使程序不同,所以我们不能盲目的使用系统提供的排序功能
所以对小问题的仔细分析有时可以得到明显的实际益处。
程序的一般原理:
- 正确的问题
- 位图数据结构
- 多趟算法
- 时间-空间折中与双赢
- 简单的设计
算法的重要性
三个问题
1、给定一个包含32位整数的顺序文件,它至多只能包含40亿个这样的整数,并且整数的次序是随机的。请查找一个此文件中不存在的32位整数。在有足够内存的情况下,你会如何解决这个问题?如果你可以使用若干外部临时文件但可用主存却只有上百字节,你会如何解决这个问题?
如果内存足够可以使用,位图技术(每一位代表一个数)
如果内存不够可以使用,二分搜索
2、将一个具有n个元素的一维向量向左旋转i个位置。例如,假设n=8,i=3,那么向量abcdefgh旋转之后得到向量defghabc。你只能使用1字节的辅助变量。
方法1:块变换
旋转向量实际就是交换xy的两段,x(abc),y(defgh)。将y分为两段yl(de),yr(fgh)。交换x和yr,也就是将xylyr转换成yrylx。这时x已经处于正确的位置,然后再递归的处理b的两部分即可。(程序较复杂)
方法2:分别反向(leetcode 189. Rotate Array)
reverse(0,i-1); //abcdefgh
reverse(i,n-1); //cbahgfed
reverse(0,n-1); //defghabc
3、给定一本英语单词词典,请找出所有的变位词集。例如,因为”pots” “stop” “tops”相互之间都是由另一个词的各个字母改变序列而构成的,因此这些词相互之间就是变位词。
(leetcode 49. Group Anagrams)
如何思考:使这些变位词集合具有相同的标识,然后再集合
1、标识:排序后的单词
2、将所有的单词按照其标识排序
Code:
class Solution {public: vector<vector<string>> groupAnagrams(vector<string>& strs) { vector<vector<string>> res; unordered_map<string,vector<string>> hash; for(int i=0;i<strs.size();i++) { string s=strs[i]; sort(s.begin(),s.end()); hash[s].push_back(strs[i]); } unordered_map<string,vector<string>>::iterator it=hash.begin(); for(;it!=hash.end();it++) res.push_back(it->second); return res; }};
数据决定程序结构
好的数据结构可以使程序短小、清晰、漂亮。
思考数据的几条原则:
- 使用数组重新编写重复代码
冗长的相似代码常常可以使用最简单的数据结构–数组来更好地表述 - 封装复杂结构
当需要非常复杂的数据结构时,使用抽象术语进行定义,并将操作表示为类 - 尽可能使用高级工具
超文本、名字-键值、电子表格、数据库,编程语言等都是特定问题领域中的强大的工具。 - 从数据得出程序的结构
通过使用恰当的数据结构来替代复杂的代码,从数据可以得出程序的结构。
编写正确的程序
- 问题定义
- 算法设计
- 数据结构的选择
Ex:编写二分搜索的程序
//递归方法int Binary_Search_Recursion(vector<int> v, int begin, int end, int key){ if (begin > end) return -1; int mid = (begin + end) >> 1; if (v[mid] > key) return Binary_Search_Recursion(v, begin, mid - 1, key); else if (v[mid] < key) return Binary_Search_Recursion(v, mid + 1, end, key); else return mid;}//非递归方法int Binary_Search(vector<int> v, int begin, int end, int key){ if (begin > end) return -1; int mid = 0; while (begin <= end) { mid = (begin + end) >> 1; if (v[mid] > key) end = mid - 1; else if (v[mid] < key) begin = mid + 1; else return mid; } return -1;}
如何调试
1、学会打断点
2、计时
C/C++中的计时函数是clock(),而与其相关的数据类型是clock_t
在time.h文件中,还定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,其定义如下:
#define CLOCKS_PER_SEC ((clock_t)1000)
可以看到每过千分之一秒(1毫秒),调用clock()函数返回的值就加1。
Test code:
int main(){ vector<int> data = { 1, 2, 3, 4, 5, 6, 7 }; clock_t start; clock_t finish; start = clock(); int a1 = Binary_Search(data, 0, data.size() - 1, 1); int b1 = Binary_Search(data, 0, data.size() - 1, 7); int c1 = Binary_Search(data, 0, data.size() - 1, 10); finish = clock(); cout << (double)(finish - start) / CLOCKS_PER_SEC << endl; return 0;}
- 编程珠玑笔记1
- 编程珠玑-笔记1
- 编程珠玑学习笔记1
- 《编程珠玑》笔记
- 《编程珠玑》笔记
- 编程珠玑笔记
- 编程珠玑学习笔记
- 《编程珠玑》第一章笔记
- 读《编程珠玑》笔记
- 编程珠玑笔记--排序
- 编程珠玑笔记~~开篇
- 编程珠玑 笔记
- 编程珠玑笔记第一章
- 《编程珠玑》第一章笔记
- 编程珠玑学习笔记
- 《编程珠玑》笔记一
- 《编程珠玑》看书笔记
- 《编程珠玑》 心得笔记
- PHP 导出excel 设置文本格式,数字前不去掉0
- 【C#】50.使用await操作连续的异步任务
- Spring学习01--IOC容器(简介,注入)
- 将value值转换为字符串方法以及原理详解
- 贪吃蛇,游戏,动画,JavaScript
- 编程珠玑-笔记1
- 设备驱动中的platform(kernel-4.7)
- C++ 虚函数表解析
- 聚焦核心竞争力:自建与外购
- 【HIbernate框架学习】:Hibernate对象继承关系映射(一)
- 迷茫中的大二狗,从今天开始认真学习~
- ubuntu12.04 Qt调试器无法正常工作
- Maven的安装与配置
- 字典树(背单词,LA 3942)