算法:相信大家对算法肯定不陌生(但其实绝大多数开发人员对这个非常陌生且抗拒),因为从学校没毕业开始就已经被算法折磨了,哈哈
设计模式:爱学习的开发人员对这个也不会陌生,是些到了一定工作阶段必须学的思想以及解决问题的通用方法
企业应用架构模式:Martin Fowler所著,其实从难度上讲,比不上设计模式,只是内容较多,更加实际且更加符合人类的理解
架构模式:最著名的资料是POSA那几本书,讲的是云里雾里,看这本书时,设计模式那点难度根本就不叫难度,哈哈,看起来极其痛苦,但是又非常快乐(哈哈,这就要看看书的人了)
在这些概念当中,个人认为架构模式以及算法是比较难的,如果只能选择一个,我就选算法为最难,所以携程才招了一帮博士搞算法,因为其他的都能慢慢搞懂,唯独算法是需要真正长久专研下去的,能够达到非常深奥。
题外话:像这些概念其实都80、90年代就已经出现了,可惜,我们却刚开始研究人家的东西,悲哀啊。
很多人认为
其实不然,memcache是怎么发明的?操作系统的调度算法怎么实现的?为啥这么实现而不是那样实现?有和依据?为什么加了数据库的索引后搜索能飞快?为什么加了这个索引却没有用?为什么大规模文本搜索时要用Lucene来搜索,而不是sql server或者oracle?
这些为什么后面大部分是由算法和架构决定的,绝不是简单的分层架构。
希望广大的开发人员能关注这些,中国的研发需要中国程序员。
其他LeetCode题目欢迎访问:LeetCode结题报告索引
Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
For example,
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog"
,
return its length 5
.
Note:
分析:这种题,肯定是每次改变单词的一个字母,然后逐渐搜索,很多人一开始就想到用dfs,其实像这种求最短路径、树最小深度问题bfs最适合,可以参考我的这篇博客bfs(层序遍历)求二叉树的最小深度。本题bfs要注意的问题:
我们利用和求二叉树最小深度层序遍历的方法来进行bfs,代码如下: 本文地址
1 class Solution { 2 public: 3 int ladderLength(string start, string end, unordered_set<string> &dict) { 4 // IMPORTANT: Please reset any member data you declared, as 5 // the same Solution instance will be reused for each test case. 6 //BFS遍历找到的第一个匹配就是最短转换,空字符串是层与层之间的分隔标志 7 queue<string> Q; 8 Q.push(start); Q.push(""); 9 int res = 1; 10 while(Q.empty() == false) 11 { 12 string str = Q.front(); 13 Q.pop(); 14 if(str != "") 15 { 16 int strLen = str.length(); 17 for(int i = 0; i < strLen; i++) 18 { 19 char tmp = str[i]; 20 for(char c = 'a'; c <= 'z'; c++) 21 { 22 if(c == tmp)continue; 23 str[i] = c; 24 if(str == end)return res+1; 25 if(dict.find(str) != dict.end()) 26 { 27 Q.push(str); 28 dict.erase(str); 29 } 30 } 31 str[i] = tmp; 32 } 33 } 34 else if(Q.empty() == false) 35 {//到达当前层的结尾,并且不是最后一层的结尾 36 res++; 37 Q.push(""); 38 } 39 } 40 return 0; 41 } 42 };
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:
For example,
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Note:
分析:本题主要的框架和上一题是一样,但是还要解决两个额外的问题:一、 怎样保证求得所有的最短路径;二、 怎样构造这些路径
第一问题:
第二个问题:
1 class Solution { 2 public: 3 typedef unordered_set<string>::iterator HashIter; 4 vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { 5 // Note: The Solution object is instantiated only once and is reused by each test case. 6 queue<string> Q; 7 Q.push(start); Q.push(""); 8 bool hasFound = false; 9 unordered_map<string,vector<string> >prePath;//前驱路径 10 unordered_set<string> hashtable;//保证bfs时插入队列的元素不存在重复 11 while(Q.empty() == false) 12 { 13 string str = Q.front(), strCopy = str; 14 Q.pop(); 15 if(str != "") 16 { 17 int strLen = str.length(); 18 for(int i = 0; i < strLen; i++) 19 { 20 char tmp = str[i]; 21 for(char c = 'a'; c <= 'z'; c++) 22 { 23 if(c == tmp)continue; 24 str[i] = c; 25 if(str == end) 26 { 27 hasFound = true; 28 prePath[end].push_back(strCopy); 29 //找到了一条最短路径,当前单词的其它转换就没必要 30 goto END; 31 } 32 if(dict.find(str) != dict.end()) 33 { 34 prePath[str].push_back(strCopy); 35 //保证bfs时插入队列的元素不存在重复 36 if(hashtable.find(str) == hashtable.end()) 37 {Q.push(str); hashtable.insert(str);} 38 } 39 } 40 str[i] = tmp; 41 } 42 } 43 else if(Q.empty() == false)//到当前层的结尾,且不是最后一层的结尾 44 { 45 if(hasFound)break; 46 //避免进入死循环,把bfs上一层插入队列的元素从字典中删除 47 for(HashIter ite = hashtable.begin(); ite != hashtable.end(); ite++) 48 dict.erase(*ite); 49 hashtable.clear(); 50 Q.push(""); 51 } 52 END: ; 53 } 54 vector<vector<string> > res; 55 if(prePath.find(end) == prePath.end())return res; 56 vector<string> tmpres; 57 tmpres.push_back(end); 58 ConstructResult(prePath, res, tmpres, start, end); 59 return res; 60 } 61 62 private: 63 //从前驱路径中回溯构造path 64 void ConstructResult(unordered_map<string,vector<string> > &prePath, 65 vector<vector<string> > &res, vector<string> &tmpres, 66 string &start, string &end) 67 { 68 if(start == end) 69 { 70 reverse(tmpres.begin(), tmpres.end()); 71 res.push_back(tmpres); 72 reverse(tmpres.begin(), tmpres.end()); 73 return; 74 } 75 vector<string> &pre = prePath[end]; 76 for(int i = 0; i < pre.size(); i++) 77 { 78 tmpres.push_back(pre[i]); 79 ConstructResult(prePath, res, tmpres, start, pre[i]); 80 tmpres.pop_back(); 81 } 82 83 } 84 };
另外这一题如果不用队列来进行bfs,可能会更加方便,使用两个哈希表来模拟队列,这样还可以避免前面提到的同一个元素加入队列多次的问题,具体可以参考这篇博客
【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3443512.html
先说说大伙关心的工作上的事,在上家公司任了一个多月的技术经理后,和公司中止了合作关系。
主要原因在于一开始的待遇没谈的太清楚:
1:没有合同,没有公积金,连社保也没交。
2:工资的30%变成了绩效(对我还实行特例,按季度或按项目发,而且绩效只有按期完成(发)与没完成(不发))
3:税后的问题,要自己去弄发票来填。
只能说缘来的太快,份走的也太快。
对于工作上的事,一个多月的时间,从需求文档到概要文档到详细文档,到产品原型到系统架构,基本上已经走完了。
项目成员也招聘完成,开发的按我的计划稳定的进行着,所有的技术难点,我都提前解决了。
虽然人走,但后续剩下点的任务也安排好了,剩下的开发有种没了我依然一切如旧的悲凉感觉。
交待完前事,下面进入技术正题。
加载模板(aspx、cshtml)-》调用引擎解析成(语法树)-》生成CS代码-》动态编绎-》返回最终模板。
相对来说,这种模板引擎,性能相对来说会下降一些,但是搭载VS IED的智能提示,和大伙多年的开发习惯,已经占据了主流。
对于Razor有兴趣研究的,想深入的可以下载源码去慢慢慢慢研究,Razor 的源码(取自mvc5源码的razor项目):点击下载
这里也有篇Razor的原理基础文章,可供参考: http://www.cnblogs.com/JamesLi2015/p/3213642.html源码目录截图:
XHtmlAction模板引擎的基本原理:
和ASP.NET自带的模板引擎比较,这里没有语法树、生成代码和动态编绎过程,因此可以得到高性能的体验。
另外相对来说,对Xml及XPath语法的操作进行了封装,简化了很多后台开发代码。当然相对缺点就是不能在模板里混合写后台代码了,换个说法是没有强大的IDE智能提示(若换个角度看,也成优点,模板和后台代码真正分离了)。
XHtmlAction实现也相当的轻量级,一共就6个文件,老少皆宜,有兴趣研究的可以看 CYQ.Data V4.55的源码:
曾经也写过两篇相关的文章:
1:多语言的(MutilLanguage),可以让你很轻松的编写多语言网站:实战篇-简单多语言的实现
2:XHmlAction的使用(以前类名叫XmlHelper,用法是一样的):CYQ.Data.Xml XmlHelper 助你更方便快捷的操作Xml/Html
除了介绍的(XmlHelper)用法,最近V5版本增加了“CMS标签替换”功能,下面介绍。
先写个函数,创建文本数据库和添加数据:
该代码执行后,生成两个文件:demo.ts(表结构)demo.txt(json格式的表数据)
文本里的Json数据:
文本数据库相当于创建好了,配置里添加一行数据库链接请求:
弄好数据库,可以写代码了,单条数据的标签替换:
代码解答:
如果把上面的代码注释放开,Html如下:
对于一个html,可能涉及到相同的字段名(同表的不同行数据,不同表的数据)需要标签替换,因此LoadData(数据行,前缀)方法需要前缀来区分。
同时前缀也可以传空"",不使用前缀(但要注释避免和其它的冲突)。
对于行的数据,是在获取xml.OutXml属性的时候才处理,因为对于标签,可以存在任意地方,因此不能以节点来处理,只能在最终输的时候,拿到html,再用正则替换。
对于表格的输出,需要获取某个节点,以对节点下的内容,进行克隆复制循环输出,由于已经存在节点,所以在xml.SetForeach的时候就处理了。
如果涉及到字段格式化,仍按SetForeach的事件处理即可。
本文及示例介绍的是标签替换的功能,节点替换的操作方式,仍和以前的操作方式一致。
对于Web开发框架,主打关键就三块:URL重写(路由)、模板引擎(视图引擎)、数据层框架(ORM)。
如果你能掌控或自由实现这三模块,你的开发方式选择就自由化很多,如果不能,你只能局域于微软给你的WebForm和MVC。
对于框架,有时候研究的再深,也不如自己写一个浅的。