存档

作者存档

【Vim学习】字符串搜索

2012年10月28日  2,606 views 6 条评论

原文出自http://sucre.blog.51cto.com/1084905/270556

1、基本搜索

要自当前光标位置向下搜索(即在下文中搜索),请使用以下命令:

/pattern   Enter

其中,pattern   表示要搜索的特定字符序列。

要自当前光标位置向上搜索(即在上文中搜索),请使用以下命令:

?pattern   Enter

按下   Enter   键后,vi   将搜索指定的   pattern,并将光标定位在   pattern   的第一个字符处。例如,要向上搜索   place   一词,请键入:

?place   Enter

如果   vi   找到了   place,它将把光标定位在   p   处。要搜索   place   的其他匹配,请按   n   或   N:

n,继续朝同一方向搜索   place。

N,反方向进行搜索。

如果   vi   未找到指定的   pattern,光标位置将不变,屏幕底部显示以下消息:

Pattern:   未找到

2、搜索特殊匹配

在上面的示例中,vi   查找到包含   place   的任何序列,其中包括   displace、placement   和   replaced。

要查找单个的   place,请键入该单词,并在其前后各加一个空格:

/   place     Enter

要查找仅出现在行首的   place,请在该单词前加一个插字符号   (^):

/^place   Enter

要查找仅出现在行尾的   place,请在该单词后加一个货币符号   ($):

/place$   Enter

使用   ^

要逐字搜索这种带有插字符号   (^)   或货币符号   ($)   的字符,请在字符前加一个反斜线   (\)。反斜线命令   vi   搜索特殊字符。

使用   $

特殊字符是指在   vi   中具有特殊功能的字符(例如   ^、$、*、/   和   .)。例如,$   通常表示“转至行尾”,但是,如果   $   前紧跟一个   \,则   $   只是一个普通的字符。

使用   \

例如,/(No   \$   money)   向上搜索字符序列   (No   $   money)。紧跟在   $   之前的转义字符   (\)   命令   vi   逐字搜索货币符号。

分类: 转载文章 标签: ,

修改Google Desktop的索引存放位置

2012年9月2日  2,815 views 没有评论

Google是个很伟大的公司,开发了很多非常神奇的应用,不过很可惜的是有一些已经被裁掉,不在开发维护了。

这些被裁掉的应用中,要数NoteBook和Desktop是我最喜欢的了,一直不是很理解为甚么要裁掉这样优秀的应用。话不多说,我们言归正传。

Google Desktop是一款非常优秀的桌面搜索软件,因为是自建索引,所以其搜索范围广,速度快,准确度高,使用起来非常方便,不仅能搜索文件名,还能以文件内容为key来搜索,速度比微软自带搜索快了不知多少。

但是,Google Desktop也有一点不足,这点也是Google应用的通病:不允许用户配置索引存放的路径,直接存放在了系统盘。对于习惯将系统盘分的比较小,而且功能较为单一的同学来说,这就不太方便了,只能看着自己的系统盘一点点被索引文件所侵蚀,慢慢变小。时间长了还会影响系统性能。

此文,将告诉大家如何修改Google Desktop的索引位置,其实一切都非常简单,只要5个步骤:

  1. 退出Google Desktop;
  2. 打开注册表编辑器,找到HKEY_CURRENT_USER\Software\Google\Google Desktop路径;
  3. 记住路径下data_dir的原键值然后修改为你自选的索引存放位置;
  4. 将原键值所在路径下的文件全部拷贝到自选索引存放位置;
  5. 启动Google Desktop。

至此,修改过程结束,整个过程简单的要死……

分类: 心得笔记 标签:

楼层扔鸡蛋问题

2012年8月31日  5,191 views 没有评论

本文最早是从csdn上一篇文章看到,后找到LTang转载的一篇文章。原文已失效,无法找到。

楼层扔鸡蛋的经典问题,找的可行解是很简单的,至于最优解以及m层楼n个鸡蛋的扩展则稍费脑力,此文仅转载原文,个人心得及代码实现以及动态规划问题后续会有新文章总结。

转载文章如下:

==有限层数和蛋数,求即使最坏情况下需要的最少判断次数==
两个软硬程度一样但未知的鸡蛋,它们有可能都在一楼就摔碎,也可能从一百层楼摔下来没事。有座100层的建筑,要你用这两个鸡蛋确定哪一层是鸡蛋可以安全落下的最高位置。可以摔碎两个鸡蛋。(参见[两个鸡蛋--一道Google面试题])
这是典型的动态规划问题。假设f[n]表示从n层楼找到摔鸡蛋不碎安全位置的最少判断次数。假设第一个鸡蛋第一次从第i层扔下,如果碎了,就剩一个鸡蛋,为确定下面楼层中的安全位置,必须从第一层挨着试,还需要i-1次;如果不碎的话,上面还有n-i层,剩下两个鸡蛋,还需要f[n-i]次(子问题,实体n层楼的上n-i层需要的最少判断次数和实体n-i层楼需要的最少判断次数其实是一样的)。因此,最坏情况下还需要判断max(i-1,f[n-i])次。

状态转移方程:f[n] = min{ 1+max(i-1,f[n-i]) | i=1..n }
初始条件: f[0]=0(或f[1]=1)

实际上,两个鸡蛋的情况用数学方程就可以解决,前提是你知道该怎么扔:

一种想法是第一个鸡蛋折半搜索,如100层的楼,先从50层扔下去,如果碎了则第二个鸡蛋在1~49层楼中自底向上线性搜索;如果没碎则第一个鸡蛋再从75层扔。如果这次碎了则第二个鸡蛋在51~74层楼中自底向上线性搜索;如果还没碎则第一个鸡蛋再从88层扔,依此类推。这种方法不是最优,因为最坏情况下安全位置恰好是49层,需要尝试50次。
正确的方法是先假设最少判断次数为x,则第一个鸡蛋第一次从第x层扔(不管碎没碎,还有x-1次尝试机会)。如果碎了,则第二个鸡蛋在1~x-1层中线性搜索,最多x-1次;如果没碎,则第一个鸡蛋第二次从x+(x-1)层扔(现在还剩x-2次尝试机会)。如果这次碎了,则第二个鸡蛋在x+1~x+(x-1)-1层中线性搜索,最多x-2次;如果还没碎第一个鸡蛋再从x+(x-1)+(x-2)层扔,依此类推。x次尝试所能确定的最高楼层数为x+(x-1)+(x-2)+…+1=x(x+1)/2。
比如100层的楼,只要让x(x+1)/2>=100,得x>=14,最少判断14次。具体地说,100层的楼,第一次从14层开始扔。碎了好说,从第1层开始试。不碎的话还有13次机会,再从14+13=27层开始扔。依此类推,各次尝试的楼层依次为

14
27 = 14 + 13
39 = 27 + 12

99 = 95 + 4
100

现在推广成n层楼,m个鸡蛋:

还是动态规划。假设f[n,m]表示n层楼、m个鸡蛋时找到摔鸡蛋不碎的最少判断次数。则一个鸡蛋从第i层扔下,如果碎了,还剩m-1个鸡蛋,为确定下面楼层中的安全位置,还需要f[i-1,m-1]次(子问题);不碎的话,上面还有n-i层,还需要f[n-i,m]次(子问题,实体n层楼的上n-i层需要的最少判断次数和实体n-i层楼需要的最少判断次数其实是一样的)。

状态转移方程:f[n,m] = min{ 1+max(f[i-1,m-1], f[n-i,m]) | i=1..n }
初始条件:f[i,0]=0(或f[i,1]=i),对所有i

Google各种服务的IPv6 Hosts地址

2012年4月26日  16,007 views 6 条评论

之前本博客写过一篇可以通过修改本地Hosts文件来访问Google +的文章,陆陆续续获得了1w+的点击量。不过后来因为没有一直更新IP,貌似现在那些IP都已经不好用了,所以今天我又去网上淘了一套Google服务IPv6的Host地址。

刚刚试了一下,效果非常理想,G+、Docs、Drive、Youtube都无障碍访问。为了防止以后找不到这些数据了,现将Host内容附录于下。在此感谢文档原作者Versus Clyne。

原文档地址:https://docs.google.com/Doc?docid=0ARhAbsvps1PlZGZrZG14bnRfNjFkOWNrOWZmcQ

本站镜像页面(防止docs访问不了):http://test.codeup.org/Google-hosts-IPv6.htm

Hosts文件

鉴于拷贝下文比较费事,我将我本地的Host文件附在这里,大家可以直接下载替换。

hosts文件存放位置:

Windows:%SystemRoot%\system32\drivers\etc\          例如C:\Windows\system32\drivers\etc

Linux:/etc

  hosts (301.5 KiB, 2,730 hits)

Hosts文件内容

#Google和各种网站的IPv6服务hosts

#利用IPv6技术翻墙,保证Google服务可用,校园网用户使用IPv6应该不收取上网费用(至少我们学校如此)

#最下方有各种网站的IPv6 hosts列表

#欢迎转载,请注明来源,以便网友及时更新,谢谢

#本文的发布地址:http://docs.google.com/View?id=dfkdmxnt_61d9ck9ffq

#本文的共享链接:http://docs.google.com/Doc?docid=0ARhAbsvps1PlZGZrZG14bnRfNjFkOWNrOWZmcQ

#有新的Google地址需要添加?请在这里提交或在线编辑,帮助完善此列表,谢谢~

#欢迎穿越传阅

# 5/7 v*.lscache*.l.google.com IP 地址变更(youtube 视频储存服务器除外,谁有日本 yt 的 IP 告诉我- -),由日本东京改为澳洲悉尼,速度我测试变快了
# 5/10 更新 v*.lscache*.c.google.com 感谢 JL Hwung 的提供
# 7/12 《电脑报》你威武!(2010年7月12日G14版第四列)
# 您正在查看的版本更新于 2012-04-25;详细更新日志请见 http://code.google.com/p/ipv6-hosts/source/list (RSS 链接

#顺便提供能够解析出 Google IPv6 地址的 DNS 服务器 (其 ISP 已加入 Google over IPv6 计划),这样不需要修改 hosts,只需改变本机 DNS 设置就可以自动解析出 IPv6 地址,由HE提供:2001:470:20::2 ordns.he.net (ipv6) 74.82.42.42 (ipv4,在内地可能会遭污染,可以和本 hosts 文件配合使用 by www.lostriver.net)

#最近好像有0.5不停的在举报本文有不适宜内容(滥用行为),然后接连收到10余封google发来的本文审核通过可以发表的邮件,建议大家备份一下本文,免得某些人把本文404,reset什么的之类- -

#用文本编辑器打开hosts文件,将以下内容复制进去,保存即可(hosts 文件没有后缀)

#Windows 用户可以以管理员身份直接运行 notepad “%SystemRoot%\system32\drivers\etc\hosts” 进行编辑

#Linux 用户在终端中执行 sudo gedit /etc/hosts 即可开始编辑

#关闭某个IPv6的转发请在那一行的最前面添加#号,启用请去除最前面#号,每行中间的#号是为了区分地址和注释,不用理睬- -

阅读全文…

【细节决定成败】switch篇

2012年4月15日  1,793 views 没有评论

前几天在给埃及局点提供补丁时犯了个低级错误,在switch的一个case中忘了写break语句,造成功能在大部分情况下都是正常的,只有个别场景出现了很诡异的问题,通过函数入参日志还看不出任何问题。

由于switch的各case之间肯定是非常相似的,所以这种问题造成的后果不一定能够立即体现出来,因为执行了下一个case中的逻辑后返回的结果很有可能也是正确的。

这种错误是非常低级的,低级到我都不太好意思写在这里了。但是这种错误又感觉很容易发生,这已经不是我第一次犯这种错误了。之前在做PMS插件时也发生过一次,那次也是功能在部分情况下很正常,只在一种很特殊的场景下会有问题。上次也是定位了很久才发现是个如此低级的问题。已经在同一个地方跌倒了两次,那么绝对不能再有第三次……

今天稍微总结了一下犯这种错误的原因,主要分成两个场景:

1、新写一个switch语句,在写完一个case后直接开始逻辑处理,如果这个case下的逻辑比较复杂,很有可能在写完逻辑后就忘了写break语句了。

2、修改原有的switch语句,有时候修改某个case语句,直接把此case下的所有语句都干掉重写,这时候很容易把break语句一起干掉了。然后在写新的逻辑时就很有可能只关注新的逻辑而遗漏了这个break语句。

之前犯错的两次分别就是以上两种场景,说白了就是只关注case下的逻辑而忽略了switch语句的本身。现在我能想到的预防措施就是要向括号配对一样检查case与break的配对情况,每写一个case语句后首先把break加上。

与此类似的还有if else,有时候也会存在if下逻辑复杂,写完后忘记else分支的情况。为预防此种情况,在写完if语句后必须将else语句先写下来,哪怕else下是个空语句。

分类: 心得笔记 标签: , , ,

【zz】120行俄罗斯方块(Javascript版)

2012年3月10日  1,932 views 没有评论

最近比较流行特简洁的俄罗斯方块,前几天从csdn上看到有人写了这个120行的JS版,感觉挺有意思的,就转录于此。
原作者是CSDN论坛上的 lihanbing这段代码最有意思的是只要新建一个文本文件,将如下代码拷入,手动将文件后缀名修改为.html,然后双击就能运行。

<html>
<style>.c {margin :1px;width:19px;height:19px;background:red;position:absolute;}
.d {margin :1px;width:19px;height:19px;background:gray;position:absolute;}
.f {top:0px;left:0px;background:black;position:absolute;}
</style>
<body></body><html>
<script>
    var over=false,shapes=("0,1,1,1,2,1,3,1;1,0,1,1,1,2,2,2;2,0,2,1,2,2,1,2;0,1,1,1,1,2,2,2;1,2,2,2,2,1,3,1;1,1,2,1,1,2,2,2;0,2,1,2,1,1,2,2").split(";");
    function create(tag,css){
        var elm=document.createElement(tag);
        elm.className = css;
        document.body.appendChild(elm);
        return elm;}
    function Tetris(c, t, x, y){
        var c=c?c:"c";
        this.divs = [create("div",c),create("div",c),create("div",c),create("div",c)];
        this.reset = function(){
            this.x = typeof x != 'undefined'?x:3;
            this.y = typeof y != 'undefined'?y:0;
            this.shape = t?t:shapes[Math.floor(Math.random()*(shapes.length-0.00001))].split(",");
            this.show();
            if(this.field&&this.field.check(this.shape,this.x,this.y,'v')=='D'){
                over=true;
                this.field.fixShape(this.shape,this.x,this.y);
                alert('game over');}}
        this.show = function(){
            for(var i in this.divs){
                this.divs[i].style.left = (this.shape[i*2]*1+this.x)*20+'px';
                this.divs[i].style.top = (this.shape[i*2+1]*1+this.y)*20+'px';}}
        this.field=null;
        this.hMove = function(step){
            var r = this.field.check(this.shape,this.x- -step,this.y,'h');
            if(r!='N'&&r==0){
                this.x-=-step;
                this.show();}}
        this.vMove = function(){
            if(this.field.check(this.shape,this.x,this.y- -1,'v')=='N'){
                this.y++;
                this.show();}
            else{
                this.field.fixShape(this.shape,this.x,this.y);
                this.field.findFull();
                this.reset();}}
        this.rotate = function(){
            var s=this.shape;
            var newShape=[3-s[1],s[0],3-s[3],s[2],3-s[5],s[4],3-s[7],s[6]];
            var r = this.field.check(newShape,this.x,this.y,'h');
            if(r=='D')return;
            if(r==0){
                this.shape=newShape;
                this.show();}
            else if(this.field.check(newShape,this.x-r,this.y,'h')==0){
                this.x-=r;
                this.shape=newShape;
                this.show();}}
        this.reset();}
    function Field(w,h){
        this.width = w?w:10;
        this.height = h?h:20;
        this.show = function(){
            var f = create("div","f")
            f.style.width=this.width*20+'px';
            f.style.height=this.height*20+'px';}
        this.findFull = function(){
            for(var l=0;l<this.height;l++){
                var s=0;
                for(var i=0;i<this.width;i++){
                    s+=this[l*this.width+i]?1:0;}
                if(s==this.width){
                    this.removeLine(l);}}}
        this.removeLine = function(line){
            for(var i=0;i<this.width;i++){
                document.body.removeChild(this[line*this.width+i]);}
            for(var l=line;l>0;l--){
                for(var i=0;i<this.width;i++){
                    this[l*this.width- -i]=this[(l-1)*this.width- -i];
                    if(this[l*this.width- -i])this[l*this.width- -i].style.top = l*20+'px';}}}
        this.check = function(shape, x, y, d){
            var r1=0,r2='N';
            for(var i=0;i<8;i+=2){
                if(shape[i]- -x < 0 && shape[i]- -x <r1)
                    {r1 = shape[i]- -x;}
                else if(shape[i]- -x>=this.width && shape[i]- -x>r1)
                    {r1 = shape[i]- -x;}
                if(shape[i+1]- -y>=this.height || this[shape[i]- -x- -(shape[i+1]- -y)*this.width])
                    {r2='D'}}
            if(d=='h'&&r2=='N')return r1>0?r1-this.width- -1:r1;
            else return r2;}
        this.fixShape = function(shape,x,y){
            var d=new Tetris("d",shape,x,y);
            d.show();
            for(var i=0;i<8;i+=2){
                this[shape[i]- -x- -(shape[i+1]- -y)*this.width]=d.divs[i/2];}}}
    var f = new Field();
    f.show();
    var s = new Tetris();
    s.field = f;
    s.show();
    window.setInterval("if(!over)s.vMove();",500);
    document.onkeydown = function(e){
        if(over)return;
        var e = window.event ? window.event : e;
        switch(e.keyCode){
        case 38: //up
            s.rotate();
            break;
        case 40: //down
            s.vMove();
            break;
        case 37: //left
            s.hMove(-1);
            break;
        case 39: //right
            s.hMove(1);
            break;}}
</script>