人要有梦想,万一实现了呢

拿老马的这句话套在这里应该是没有什么问题的。最近比较忙,没时间写,现在可以利用组会聊一聊这个了。

先从老马讲起吧,抛开高考、教师乱七八糟的经历,从99年十八罗汉在住宅里开始电子商务开始,浮浮沉沉,从亚马逊,卓越,当当到京东,拍拍,易迅。几易身边的对手最后终于走到了纳斯达克的交易所。有人靠技术驱动,有人靠产品立足,在讲到阿里的时候则是谈到了生态。。那再抽象一些呢,是不是可以用“人要有梦想,万一实现了呢”来做总结呢。

QQ让交流与沟通走到了线上,淘宝,京东让线下的购物转到了线上。搜狐,网易完成了在互联网的媒体功能。百度,谷歌做到的是从互联网中获取信息。衣食住行,教育医疗,金融,交友,种种这些都可以看作互联网作为新兴行业,新型模式对旧势力,旧模式的洗牌与冲击。所谓敢为人先应该是怀着这种梦想去做,万一实现了呢。

自然语言处理的三个硬需求:搜索、词典(翻译)和输入法。主要谈谈搜索吧,谷歌、百度起家的东西。

AlgoDA-1

Divide and Conquer - 分治

把原始问题分解为若干子问题,在逐个解决各个子问题的基础上,得到原始问题的解。 经常和递归联系在一起。因此如果计算时间复杂度,其递推公式很重要。

几个常见的使用分治的问题

  • FindMaxMin

n个整数元素的数组A[1… n], n 为2的幂, 传统算法的比较次数为2n-2,采用分治得到的公式为 C(n) = 1 n=2; C(n) = 2C(n/2)+2 n > 2 根据递推公式可以得到其比较的次数为 3/2n-2,相对传统算法得到了提升。

  • 二分查找

在已经排序的数组上进行二分查找,其时间复杂度了log(n)。其递推公式为(n) = 1 n=1 ; C(n) = C(n/2)+1 n>1

  • 合并排序

思路很简单,将待排序数组对半分成两个子数组;分别对两个子数组排序;将两个已排序的子数组合并。给出最大笔记次数和最小比较次数的递推公式。
C(n) = 0 n=1 ;C(n) = 2C(n/2)+n-1 n>1 || C(n) = 0 n=1 ; C(n) = 2C(n/2)+n/2 n>1

  • 寻找第K小的元素

    比较朴素的做法有,直接查找,找到第1小,然后找第2小。。一直到第k小,时间复杂度应该是 kn,如果k接近 n/2,那么复杂度为 n*n/2.第二种比较朴素的做法进行排序,nlog(n)的复杂度。在分治的算法中有一个办法,比较复杂,就直接贴算法的照片了。

    除了分治之外,还有减治和变治

    减治:每次算法迭代总是从实例规模中减去一个规模相同的常量。经常地,这个常量等于一。

被推着走,跟着生活流

周末回了一次家,无意中谁问了一句,最近还有日记吗?日记?哦,初一就开始写的东西,断断续续如果现在还没有停的话,想想已经有10年了。还好hexo还在支持,就用这个Template好了,放一些想说的话,估计也没人来看,挺好的,挺好的。

上次还是3月,过了8个月,讲讲我最近的近况吧。。

做完了毕设,还在负责网络中心的项目,现在来看bug越来越少,对网站开发有了一定的了解,更加期待尝试一下MVC。当初感觉这个项目毫无技术含量,一路做来用最原始的Servlet,反而
对网站的前端后端有了一定的了解,尽管现在是个移动的时代,懂一些web的开发总不是坏事。但愿将来也可也靠这个做点私活。

大创也有了个结果,优秀固然是好,不知道还能不能报销实在是蛋碎,谁知道呢?大创总体来说没有啥收获,最后的加班总算是让这个事情有了个结果,要不然也是尴尬,正如ppt中讲的
如果有收获,我想那个python的爬虫框架真心不错,但之后跟梁师傅交流,又提到了Scrapy的强大。如果以后再需要,这两个工具有可能都需要好好使用,再就是
那套NLP的接口了,是一个长期的计划,这是不是以后的自己的“黑科技”,我不敢说,但这套工具应该要好好做。

再就是M$,进展可以接受吧,可能会吧TLC这个工具尝试在local上试试,不得不说这个还是方便的很。其他的? EQA还在做,现在来看v0还是比较乐观的,我想着这应该是最完整的一个东西了
还是很兴奋的。

好了,可以讲讲其他的了。现在如果问我如果要创业,你是为了什么,我想,大概就是一笔不错的收入吧,没有了之前要做出来一款产品的期待,也许正是那句话, 小孩子才谈产品,大人
只讲利益,我觉得很对,现在给我的时间更要好好珍惜,能不能自己做一些好的产品,来上一笔收入,还是个问题。keep thinking,keep trying, keep doing。

NLP的三大刚需:搜索,输入法和翻译(包括词典),如果可以想到第4个?我想那一定是个point。

leetcode-1

之前说是要刷北大的JudgeOnline,结果种种理由没有去刷,但实验室的师兄告诉了我一个不错的在线编程,讨论的网站,题目不是很多,也不是针对ACM,主要是针对面试的,我想这个应该就很有用了,废话不说先贴网站,LeetCode

LeetCode OJ is a platform for preparing technical coding interviews. Pick from an expanding library of more than 140 questions, code and submit your solution to see if you have solved it correctly. It is that easy!

bootstrap的风格,很是nice,150+的题目,据说刷上几遍面google的实习生的coding interview都有了机会,尽管现在看上去没有什么用,但算法这个东西毕竟是计算机的基础之一,有时候在想计算机科班出身能比别人强在哪?培训机构出来的也可以做网站、写各种app,甚至像hadoop,mapreduce也不在话下。那科班有什么意义呢,新东方学电脑好了,我想对算法的敏感度是一个不得不提的问题,在上课期间,学C,学数据结构,等等这些无非不是让你对算法有个意识,对数据结构有个意识,而不再是简简单单的解决问题,多了这一层次的思考也许就能写出更好的代码。

废话不多说了,我在leetcode里面刷的题目也不多,但是对比较好的题目总结一下肯定不是坏事。而且这个习惯要坚持下去。

Evaluate Reverse Polish Notation

波兰式,应该是学栈最经典的题目吧,LIFO,o(n)的复杂度。

Single Number

Given an array of integers, every element appears twice except for one. Find that single one.这个问题简单的做法就是建个字典,找到出现一次的数,时间复杂度是o(n),但空间复杂度也是O(n),但空间复杂度怎么从O(n)降到O(1)呢?自己木有想到,看了discuss才找到怎么做,利用位运算,取^(异或)。

这个我用python写的了,用了字典,空间复杂度高

def singleNumber(self, A):
    b = {}
    for item in A:
        if item not in b:
            b.setdefault(item, 1)
        else:
            b[item] += 1
    for item in b:
        if b[item] == 1:
            return item

这是discuss里面的网友提出来的,相当漂亮,用了异或,相等的两个数异或为0,留下的那个就是single number了

int num=0;
for(int x : A) num ^= x;
return num;

当然这个问题还有一个进阶版啦,就是Single Number II ,原来的两个数变成了三个数,当让O(1)的空间复杂性的算法我还没懂,如果懂了立刻贴过来。

Two Sum

这个问题在面阿里实习生的时候被问过,想出了nLog(n)的算法,当然,被面试官教育了o(n)的算法,不过空间换时间嘛,精髓就是hash了,当然这个问题还可以扩展,比如题目中每个数不止出现一次,于是我把value改成了list,如果这里面的数很多很多,hash都不够了该咋办。

呃,只有我那个nLog(n)的算法,大概是先排序,然后首尾变量,移动。在编程之美2.12中也是有这个问题的,同时也是有各种进阶版,我会在想一下进阶版的问题,分享出来。

C#中ref和out的使用小结

最近在看《programming C#》,其中看到关于C#中的方法传参,看到ref和out感觉这个很有意思,在书中对这两种讲的也很清楚尤其是有一些例子,对这两种用法就显得更清楚了。

ref是传递参数的地址,out是返回值,两者有一定的相同之处,不过也有不同点。使用ref前必须对变量赋值,out不用。out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改。

区别可以参看下面的代码:

using System;
class TestApp
{
 static void outTest(out int x, out int y)
 {//离开这个函数前,必须对x和y赋值,否则会报错。 
  //y = x; 
  //上面这行会报错,因为使用了out后,x和y都清空了,需要重新赋值,即使调用函数前赋过值也不行 
  x = 1;
  y = 2;
 }
 static void refTest(ref int x, ref int y)
 { 
  x = 1;
  y = x;
 }
 public static void Main()
 {
  //out test
  int a,b;
  //out使用前,变量可以不赋值
  outTest(out a, out b);
  Console.WriteLine("a={0};b={1}",a,b);
  int c=11,d=22;
  outTest(out c, out d);
  Console.WriteLine("c={0};d={1}",c,d);

  //ref test
  int m,n;
  //refTest(ref m, ref n); 
  //上面这行会出错,ref使用前,变量必须赋值

  int o=11,p=22;
  refTest(ref o, ref p);
  Console.WriteLine("o={0};p={1}",o,p);
 }
}