路见不平

路见不平,拔刀相助
 
 
昵称:路见不平
园龄:5年
粉丝:1
关注:0

搜索

 
 

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论
  • 我的标签

随笔分类

  • ASP.net(4) (rss)
  • C/C++(2) (rss)
  • Javascript (rss)
  • PHP (rss)
  • Win32,MFC (rss)
  • Windows System(1) (rss)

随笔档案

  • 2008年5月 (1)
  • 2008年4月 (2)
  • 2008年3月 (1)
  • 2007年5月 (1)
  • 2007年4月 (3)
  • 2007年1月 (1)

最新评论

阅读排行榜

评论排行榜

推荐排行榜


Powered by: 博客园
模板提供:沪江博客
博客园 | 首页 | 发新随笔 | 发新文章 | 联系 | 订阅订阅 | 管理

2008年5月20日

打印自己的C语言程序,比较有意思
#include <stdafx.h>
void _tmain(int argc, _TCHAR* argv[])
{
 char *psz="#include <stdafx.h>%cvoid _tmain(int argc, _TCHAR* argv[])%c{%c%cchar *psz=%c%s%c;%c%cprintf( psz , 10 , 10 , 10 , 9, 34, psz , 34,10,9,10);%c}" ;
 printf( psz , 10 , 10 , 10 , 9, 34, psz , 34,10,9,10);
}
posted @ 2008-05-20 10:38 路见不平 阅读(344) 评论(0) 编辑
 

2008年4月11日

自己的搜索引擎1,全文索引1
搜索引擎的第一步,做一个自己的全文引擎,所谓的全文引擎,就是一个倒排表,所谓的倒排表,就是指从词到文档的索引。对于我们通常的文章来讲,是一个文章包含了很多的词,也就是说,文章是关键字,词是内容。那么当我们需要在很多文章中找到所有存在某一个词的文章的时候,在没有倒排索引的情况下,问题出现了,我们必须使用这个词去匹配所有文章的内容,这个效率显然是不能忍受的。这个时候就是倒排索引闪亮登场的时候了,倒排索引就是词是关键字,内容是所有包含这个关键字的文档和位置信息。所以,从理论上来讲,建所引的过程就是从:
    Doc    =>    (Word1,Word2....) 转换成
    Word1    =>    (Doc1,Doc2....)的过程。

    转换的时候,需要考虑一个性能的问题,因为对于一个文档中的每一个词,首先要做得事情就是察看这个词是不是在文章中已经出现过。这里实际上有两个相似的操作,第一个操作是把这个文章的词转换成倒排的格式,第二个操作是把第一步产生的倒排索引合并到达的索引上面去。我觉得还是分开两部操作比较好,因为如果一次性的把文章中出现的词合并到大的索引上面去,会出现很多次没有必要的比较,从而降低性能。
    为了提高创建索引的性能,我想在这里使用一个平衡二叉树,把所有的词作为这个平衡二叉树的节点,这样的话,插入一个节点比较的次数将是ln(n)次的比较,会比线形的n有很大的改善。明天是周末,把这个代码实现了。

To be continued.
posted @ 2008-04-11 21:12 路见不平 阅读(154) 评论(0) 编辑
 
想自己做一个简单的搜索引擎
我是2004年7月份开始做搜索引擎的,到现在也快四年了,期间虽然做过一些和搜索引擎没有关系的杂事,但是基本上算没有中断过。但是总感觉自己对这个东西的理解还是不够深刻,受一个朋友要自己做操作系统的启发,我萌生了自己做一个简单的搜索引擎的想法。我知道自己的缺点,我的缺点就是想法太多,付诸实施的却很少,大部分都是想一想然后就放弃了。我希望这次能够改变我以往的风格,能够把这个事情坚持下去。和以往不同不同的是,我希望以博客的形式,把我这次开发的过程完整的记录下来。

废话不说,先对要做得事情做一个计划吧。


第一步,首先做搜索引擎的核心,做一个全文的引擎,把倒排表建起来。
第二步,倒排表建立好以后,需要做一个查询系统,能支持与或非三种操作,支持纯与条件下的差错查询。
第三步,相关性的排序。

这次算是Version1吧,这次不涉及的东西是蜘蛛,html内容分析提取,中文分词。 OK, Let's go!

(第一个版本我就一个人搞定了,以后如果继续做的话,希望有识之士能够加入。等作到一定的时候,我会申请一个网站,把所有的源代码都公布出来。希望能做出一个中国人自己的Mini版本的Lucene。)
posted @ 2008-04-11 20:28 路见不平 阅读(999) 评论(2) 编辑
 

2008年3月19日

Dos批处理文件Bat的编写
最近由于工作的原因,总是需要些一些命令行下的批处理文件,这些扩展名为".bat"的文件,是从Dos时代一路传承下来的,所以我们总是喜欢叫他bat文件。从上大学的时候,一直用bat做一些小的东西,从来没有感受到过它的威力,最近用它做一些工作,发现这个东西还真的比较有意思。总结一下,希望对大家的工作能有所帮助。Bat有传统的模式,和Command Extensions两种模式,扩展用法通常是指后者。

最常用的命令:Call,Echo,For,Goto,If,Pause,REM,shift

Call 命令:调用另外的一个批处理文件。常用的方式就是:"Call sample.bat",新扩展的一个用法是 "Call :label arguments",也就是说,你可以用Call来调用Bat文件内部的一段脚本,用exit来退出当前的call调用。如果配合Goto语句的话,实际上是扩展的Bat文件支持了一个Ugly的函数。

这里需要注意的是,Batch脚本的参数(%0 %1 ...)有了一些新的变化:
 %* 表示这个批处理文件的所有的参数(%1 %2 ....)
对于每一个%n还有一些扩展:
%~1    删除%1的两端的双引号
%~f1   扩展成%1的全部文件名
%~d1  获取%1的盘符
%~p1  获取%1的文件路径
%~n1  获取%1的文件名称
%~x1  获取%1的扩展名
%~s1  获取短文件名
%~a1  获取文件的属性
%~t1  获取文件的时间
%~z1  获取文件的大小
%~$PATH:1  从指定的PATH环境变量中查找%1并且扩展成全文件名

而且上面的还可以组合,例如:
%~dp1    把%1扩展成盘符和路径
%~nx1    把%1扩展成文件名和扩展名
%~dp$PATH:1    从制定的PATH中搜索%1,并且扩展成盘符和路径的形式
%~ftza1    扩展成dir类似的输出结果,文件名    时间    大小    属性

echo
    用来显示一段文字,没有什么好说的。

goto   
    用来进行跳转:
    goto END
:END
    也没有什么好说的。

for 命令:
    这个里面最复杂的一个命令。
    基本形式:
    for %variable in (set) DO command [command-parameters]
    需要注意的是,这里的variable一定是单个字符的。set可以是一个或者多个文件,也可以使用通配符:
    for %f in (*.txt *.log) DO type %f
    表示查找当前目录下所有的.txt,.log,在屏幕上打印它的内容。
    这里需要注意的是,Do后面可以加()来执行多行的语句;
    for %%f in ( *.txt ) DO (
        echo process %%f...
        type %%f
    )

    对于扩展的For语句,有如下的几种形式:
    for /D %variable IN (set) DO command [command-parameters]
    对目录进行操作

    for /R [[driver:]path] %varable IN (set) do command [command-parameters] 
    对一个路径下的所有的目录作指定的操作

    for /L %variable IN (start,step,end) DO command [command-parameters]
    产生一个列表,例如(1,1,5) 则产生一个(1 2 3 4 5)的列表

    for /F ["options"] %variable IN (file-set|"string"|'command') DO command [command-parameters]
    这个命令分三种情况,第一个是一个文件的集合,这种情况下,所有的这些文件都会被打开,命令将处理文件的内容。如果IN的括号里面是有双引号的,则是处理这个字符串。如果括号里面的是单引号的话,则是处理执行命令以后的结果。如果指定了usebackq的话,则单引号表示的是字符串,反向的单引号表示执行的命令,这个时候双引号可以用来把包含空格的路径括起来。
    一个一个的解释,首先是options,options有如下的选项:
    eol=c     只能指定一个字符,以此开始的为注释行。
    skip=n    跳过文件的n行
    delims=xxx    指出分隔符的结合。缺省的是空格和TAB
    tokens=x,y,m-n,*    指定获取的Token.
    usebackq    使用反单引号(~键一起的那个)
    
    例如:
    for /F "eol=; token=2,3* delims=, " %i IN ( myfile.txt ) do @echo %i %j %k
    解析myfile.txt,忽略分号开始的行,%i是第二个,%j是第三个,%k是剩下的所有。
    
    这里需要注意的是,上面%~进行扩展的那些东西,对于FOR循环中的文件变量也是有效的。
    for %Z in (*.txt) do (
        echo %~fZ
    )
    上面的命令就是用来显示全路径名的。


IF命令:    
    IF命令以供有三种形式:
    IF [NOT] ERRORLEVEL number command
    IF [NOT] string1 == string2 command
    IF [NOT] exists file command
    非常简单,没有什么好说的,扩展的命令如下:

    IF [/I] string1 compare-op string2 command
    IF CMDEXTVERSION number command
    IF DEFINED variable command
    比较操作符如下:
    EQU,NEQ,LESS,LEQ,GTR,GEQ,不多说了,很简单。
    /I标志增加的时候,忽略大小写。
    
    CMDEXTVERSION有点像ERRORLEVEL,不同的是他和Commend Extensions的内部数字作比较。
    DEFINED用来判断一个环境变量是不是被定义。

    可以用%ERRORLEVEL%,%CMDEXTVERSION%,%CMDCMDLINE%作变量用,前面两个很好理解,最后一个就是输入的命令行。

    注意IF ERRORLEVEL命令,这个判断的是上一个命令的结果,所以一定按照ERRORLEVEL从大到小的顺序进行判断。

Pause命令:    
    让程序停下来等按键,没有什么好说的。

REM命令,注释,仅此而已

shift命令:
    shift /2
    修改参数的位置,从第二个参数开始,把后面的一个参数超前挪动一位。%3=>%2,%4=>%3,%0,%1不变。

Choice命令:    
    提示用户作出选择的命令;支持如下的参数
    /C    XNC    给出X,N,C三个选择
    /N    隐藏提示信息
    /CS    支持大小写
    /T    10     10秒超时
    /D    缺省选择
    /M    text    提示信息
 
字符串操作:    
    操作方法一,用FOR命令来进行操作。
    操作方法二,%variable:~start,length%从变量中截取字符串。%variable:replace=candicate%来替换字符串。

set操作:    
    设置变量,可选的参数是:
    /A    用来进行数学运算,支持与C语言一样的操作符
    /P    根据用户的输入来设置环境变量

表达式运算:
    调用expr来运算。
    还可以set /a进行
其他的注意事项:
    在写Bat文件的时候,一定要注意在开始和结束的时候setlocal enabledelayedexpansion/endlocal这样你改变的环境不会影响到外面。

最容易出错的地方:
错误的方法:
for ...... do (
    set /a index+=1
    use .... %index% ...
)
这里所有的%index%都是初始值,而不是你想要的。
下面的才是正确的:
for ...... do (
    set /a index+=1
    use ... !index!...
)
posted @ 2008-03-19 16:43 路见不平 阅读(4256) 评论(0) 编辑
 

2007年5月21日

有感于口碑营销

    最近召开了一次轰轰烈烈的社区大会,在这次胜利而又成功的大会上,一个非常新鲜的,颠覆性的名词“口碑营销”进入了广大IT界,经济界人士的眼帘。我是一个做IT的人,但是我是一个纯粹作技术的人,原本对这些上层人士玩的感念没有什么特别的兴趣,再加上对于营销之类的东西一窍不通,我对这些东西通常不予置评的。但是,这次,我想说几句这样的话。
    察看了一些关于口碑营销的文章,逐渐的看出一些门道来。原来,所谓的颠覆传统的广告模式的方式,其实就是把原来做在门户上的,做在搜索内容边上的广告,完全的融入到社区的内容中间去。让社区的人口口相传,从而让一个产品在社区里面有一个很好的口碑,达到宣传产品的目的。这样的思路,乍一看,是没有什么问题,但是仔细想想,你会发现其中还是有一些问题存在的,有些问题,可能还是致命的。
    现在的社区,为了生存,他们做的事情是自己拉来一些广告,或者是直接在网页里面嵌入一些诸如AdSense之类的东西,以希望通过流量或者是点击来获取一些收益。现在的大部分社区,对于他们的内容的管理相对还是比较严格的。因为这些内容,尤其是一些精彩,中肯,客观的内容,是这些社区在同类网站竞争中生存的根本。这些社区都有一些尽职的编辑或者版主们,对一些广告,或者明显的枪手的文章或者删除文章,或者封ID来保证社区的纯洁。因为,在没有很好的盈利模式被开发出来之前,社区的内容的精彩程度,可信度这些东西,是最容易对用户产生黏着力的。那么我们看看这个崭新的“口碑营销”在做什么?他希望把所谓的口碑(其实就是广告)都融入到社区的内容中间去。如果所有上网的网民都是好人,都是正直无私的好人。所有的这些上网的人,发布的文章都是发自内心的评论,他们对某些商品的评价都是客观公正的。那么,我觉得我们的“口碑营销”模式有资格拿2007年诺贝尔经济学奖!但是现实情况会这么简单吗?当我们走进论坛,里面满满登登的全是枪手们的文章,或者为自己的产品唱赞歌,或者捏造一些事实来攻击竞争对手的产品。或者是一些人,根本没有用过人家的东西,完全是冲着网站的积分或者其他的什么东西去的,从而捏造出一个文章来。如果论坛里面充斥了这样的文章,我想知道,各位,你们还愿意去这样的论坛看看吗?象我,一个普通的网民,我是不愿意去这样的论坛转悠的。
    这样的模式,对于那些渴望盈利超过一切的社区来讲,从表面上来看,还是很有一些吸引力的。如果这个模式能够推广下去,在初期,由于这些采用这些模式的网站比较少,枪手还相对的比较少,应该是能够给他们带来一些盈利的。说白了,这也是一种广告模式,有效果,就会有人向里面扔钱。但是如果这个模式到中期的时候,我们就会发现我们原先所熟悉的论坛变味了!原来还有几个人说真话的论坛,现在充斥了各种各样的枪手和骗子的文章。到这个时候,这个网站对用户的黏着度就会急剧降低。到大量用户都流失的时候,这个社区也就没有什么存在的价值了!因为因为没有用户,广告商凭什么向里面扔钱?没有内容,用户又不是傻的,凭什么到你那里去让你忽悠?这不就是传说中的“饮鸩止渴”吗?
    或许,也是一个好事情,也算是一个革命吧!让现有的那些社区进行一个重新的洗牌!给后来的创业者们一个全新的竞争环境。
    让暴风雨来得更加猛烈一些吧!

posted @ 2007-05-21 10:31 路见不平 阅读(164) 评论(0) 编辑
 

2007年4月17日

C#中的正则表达式

      正则表达式是我喜欢的东西,正则表达式在字符串处理方面,除了性能问题外,它有着无可比拟的优势。C#中引入了正则表达式的类库,给我们带来了很大的方便。
      要在C#中使用正则表达式,需要引用如下的名字空间:

      using System.Text;
      using System.Text.RegularExpressions;

      在C#中使用正则表达式,最重要的类是Regex。Regex对象的构造函数参数中最常见的一个是正则表达式的串,另外一个经常使用的是RegexOptions。正则表达式的字符串和正则表达式的语法这里就不罗嗦了,大家有兴趣的话,可以给我写邮件和我讨论讨论。关于RegexOptions,下面是其中一些主要参数的介绍:
      RegexOptions.Compiled         让C#把正则表达式编译成一个Assembly,这样可以在执行正则的时候启动的更快。这个参数需要注意的事情是,使用这个选项时,正则表达式一定是静态的字符串,而不能使动态的字符串(可以想象,动态字符串是不会有任何效果的)。
      RegexOptions.IgnoreCase      让正则表达式匹配的时候忽略大小写。
      RegexOptions.Multiline           多行模式正则匹配。
      RegexOptions.None               不指定任何的选项。
      RegexOptions.RightToLeft      从右向左开始匹配。
      RegexOptions.SingleLine        单行模式正则匹配。

      下面讨论正则表达式的使用:
       Regex token = new Regex(@"((?<protocol>[a-zA-Z]*?)://)?(?<domain>[^/]*)(?<path>.*)", RegexOptions.Compiled);
       Match matchList = token.Match("http://www.sina.com.cn/index.html");

       if (matchList.Success)
       {
                Console.WriteLine( "Protocol:{0},Domain:{1},Path:{2}" ,
                        matchList.Groups["protocol"] ,
                        matchList.Groups["domain"] ,
                        matchList.Groups["path"]) ;
       }
      
      上面的是匹配单行的情况,下面的例子是演示的匹配多个结果的情况:

       Regex token = new Regex(@"\s*((?<protocol>\w*?)://)?(?<domain>[^\/\s]+)(?<path>[^\s]*)", RegexOptions.Compiled);
       MatchCollection matches = token.Matches("http://www.sina.com.cn/index.html http://www.microsoft.com ftp://ftp.cav.com/info.zip");

       if (matches.Count != 0)
       {
                foreach (Match matchList in matches)
                {
                    Console.WriteLine("Protocol:{0},Domain:{1},Path:{2}",
                            matchList.Groups["protocol"],
                            matchList.Groups["domain"],
                            matchList.Groups["path"]);

                    foreach (Capture c in matchList.Captures)
                    {
                        Console.WriteLine("Capture:[" + c + "]");
                    }
                }
       }

      下面是一个Replace的用法,主要目的是为了演示MatchEvaluator.
       public static string ReplaceEva(Match match)
       {
            return match.Groups["protocol"].Value + "://" + "www.google.com/" + match.Groups["path"].Value;
       }

      Regex token = new Regex(@"\s*((?<protocol>\w*?)://)?(?<domain>[^\/\s]+)(?<path>[^\s]*)", RegexOptions.Compiled);
      string strNew = token.Replace("www.sohu.com/index.htm",new MatchEvaluator(ReplaceEva));
      Console.WriteLine("New Line:{0}", strNew);

      MatchEvaluator是一个函数代理,用来处理替换过程中得到的每一个Match。返回的字符串就是替换后的字符串。


      最后演示以下最简单的使用正则进行Splite的操作,例子代码如下:

      Regex r = new Regex("(-)"); 
      string[] s = r.Split("one-two-banana");

      OK, That's all.希望能够对大家有所帮助。
           

posted @ 2007-04-17 11:26 路见不平 阅读(328) 评论(0) 编辑
 

2007年4月16日

数独问题全解
摘要: 数独是一个很多人都喜欢的游戏。对于这样的问题,我比较喜欢的解决方案是写一个程序来解决这些问题。不过这些问题显然是那种需要回溯需要优化的问题。游戏规则我就不罗嗦了,言归正传。首先是解决数独问题的算法。程序输入,一个9*9的输入矩阵,有数字的地方就是指定的数字,没有数字的地方输入为0。算法的主要思想如下:1、创建一个堆栈trackStack,用来保存用程序填入的格子的信息。2、查找所有的数字为0的地方...阅读全文
posted @ 2007-04-16 16:10 路见不平 阅读(7132) 评论(21) 编辑
 
DataTable操作中的性能问题
摘要: 最近的一项工作是关于性能提升方面的。要做的第一个事情是要把很多同类型的DataTable合并到一起,查了很多关于DataTable的相关函数以后,我决定用Merge函数来合并这些DataTable。DataTable[] srcTables = ... ;foreach( DataTable src in srcTables ){dest.Merge( src ) ;}但是测试的结果让我很是失望,...阅读全文
posted @ 2007-04-16 11:54 路见不平 阅读(5983) 评论(14) 编辑
 

2007年1月26日

在ASP.NET中使用用户控件
posted @ 2007-01-26 10:11 路见不平 阅读(587) 评论(0) 编辑
 
仅列出标题