2007年8月3日星期五

《C++沉思录》阅读笔记(2)

1.很多最成功、最有名的软件最初都是由少数人开发的;
2.软件业中,软件制造的规模和经济效益不成正比;
3.抽象是机器所不易而是人所擅长的工作,不同层次的抽象产生不同层次的系统,要厘清不同语言能赋予人不同的层次的抽象能力。有些抽象不是语言的一部分。
4.在某处很显然的约定在另一写地方会成为"隐讳"的细节而不为自己和他人所觉察、最终成为最难于Debug的Bug。
5.人应该成为工具的主人而不是依附工具的奴仆。

2007年8月2日星期四

C++沉思录阅读笔记(1)

实用和抽象是C++的本质特性。不要陷入教条主义的泥潭,但要尊重编程手册与智慧。在面对代码时要始终保持实用主义原则,而在确保程序正常工作的基础上,敢于挑战自我,用眼光考察代码的未来,用头脑抽象问题的本质。对于一个优秀的C++科学家来说。编程应是(1)集中考量问题的本质(2)定义一个类来抓住本质,确保其能工作(3)将其逐步抽象建立一个更一般问题的解决方案(4)在遇到符合这个本质的问题就采用该类。
思索是C++程序员的特权,因为从语言角度C++给于程序员最大的自由度。

2007年7月1日星期日

python过滤HTML代码小记

我常用Python来过滤HTML代码,其中一项工作是将网络上批量下载的文章进行重命名。一般操作是先下载索引页面(HTML),然后用FlashGet批量下载文件;用Python过滤索引页面以获取文件下载名与实际文件名的对应列表,最后转换为BAT文件批处理。
但我一直没有能解决如何判断A标签的class属性问题,因为我以前的代码是:
def start_a(self,attrs):
idText = [ v for k, v in attrs if k == 'class' ]
fileHref = [ v for k, v in attrs if k == 'href' ]
print fileHref
if idText == 'a': #这里判断class的属性,有问题的
self.inValid = True
self.fileHrefs.append( fileHref )
def end_a(self):
self.inValid = False
其中判断A标签的class属性那段是有问题的。原因是我没有区分Python中数组与字符串的关系。今天我重读Python帮助后才意识到这一点。我的新代码如下:
def start_a(self,attrs):
idText = [ v for k, v in attrs if k == 'class' ]
fileHref = [ v for k, v in attrs if k == 'href' ]
print fileHref
if idText == ['a'] : #用数组来判断
self.inValid = True
self.fileHrefs.append( fileHref [0]) #在序列数组中添加字符串而非子序列数组
def end_a(self):
self.inValid = False
这样就解决问题了。

2007年6月25日星期一

批量下载后的文件名过滤

用FlashGet批量下载文件后面临一个文件名更改过滤的问题。我的解决方案是:
1.在批量下载时,同时下载该网页的HTML文件;
2.用Python来过滤出对应的HTML文件;
3.将过滤文件修补成Bat文件,运行后则可批量更改名称;
=====================================================================
Python过滤源代码
# -*- coding: cp936 -*-
# yankchina@gmail.com
# 2007-06-26 pass

from sgmllib import SGMLParser
class MyHtmlFilter(SGMLParser):
def reset(self):
SGMLParser.reset(self)
self.inValid = False
self.fileHrefs = []
self.fileNames = []

def start_a(self,attrs):
#idText = [ v for k, v in attrs if k == 'class' ]
fileHref = [ v for k, v in attrs if k == 'href' ]
#if idText == 'a01' :
self.inValid = True
self.fileHrefs.append( fileHref )
def end_a(self):
self.inValid = False


def handle_data(self, text ):
if self.inValid:
self.fileNames.append( text )


def FilteHtmlFile( inFileName,outFile ):
''' Filte Html File

'''
import os
if os.path.exists( inFileName ):
inFile = open( inFileName, "r")
parser = MyHtmlFilter()
parser.feed( inFile.read() )
inFile.close()
parser.close()
print len( parser.fileNames )
for i in range( len( parser.fileNames) ):
outFile.write( parser.fileHrefs[i][0] + " " + parser.fileNames[i]+ ".doc \n " )
print parser.fileNames[i]
print parser.fileHrefs[i]
print inFileName, len( parser.fileHrefs )

if __name__ == "__main__" :
outFileName = 'output.txt'
outFile = open( outFileName, "w" )
htmlFileName = "1.htm"
FilteHtmlFile(htmlFileName, outFile )
outFile.close()

2007年6月21日星期四

AutoIt的学习与开发心得

AutoIt3是一个Windows平台下的自动脚本工具,其脚本语言接近VBScript,但拓展了许多Windows平台的有效功能,如窗体控制、DLL调用、网络开发等。我下载了AutoIt3并进行了短期学习,开发了一个简单的脚本程序,用来在TotalCmd中调用创建一个Readme.txt文档。以前我经常手动创建这样的文档很烦人,而现在看着屏幕上一闪而过的Notepad,自有一种欣慰。
下面是程序脚本:
#cs ----------------------------------------------------------------------------
AutoIt 版本: 3.2.3.14第一版)
脚本作者: yankchina@gmail.com
Email: yankchina@gmail.com
QQ/TM:
脚本版本: 1.0
脚本功能: 新建一个名为Readme.txt的文档,并在文档首部写入日期和作者信息

#ce ----------------------------------------------------------------------------

; 脚本开始 - 在这后面添加您的代码.
Dim $AuthorInfor = "yankchina@gmail.com " ;作者信息
Dim $ReadmeFilePath = "F:\CacheTemp\" ; 默认保存路径
;如果有命令行参数,则取第一个命令行参数为文件保存位置
if $CmdLine[0] > 0 Then
$ReadmeFilePath = $CmdLine[1]
EndIf
Dim $ReadmeFileName = $ReadmeFilePath & "readme.txt"
;判断文件是否存在
Dim $FileIsExist = FileExists( $ReadmeFileName )
;以写模式打开文件,并写入题头信息
$file = FileOpen($ReadmeFileName,1)
; 检查文件是否正常打开
If $file = -1 Then
MsgBox(0, "错误", "无法打开目标文件"&$ReadmeFileName)
Exit
EndIf
;写入标题信息
if not $FileIsExist Then
FileWriteLine($file,"帮助说明文档")
FileWriteLine($file,$AuthorInfor)
EndIf
FileWriteLine($file,"")
FileWriteLine($file, getCommentLine("-",40) )
FileWriteLine($file,@YEAR&"-"&@MON&"-"&@MDAY&" "&@HOUR&":"&@MIN)

FileClose($file)
;运行记事本程序
Run("notepad.exe "& $ReadmeFileName) ;运行记事本程序
if WinWaitActive("readme.txt - 记事本") Then
Send("^{END}") ;下移到文件底部
Send("!+0") ;开启中文输入法
EndIf
;--------------------------------------------------------------------------
;获取一个注释字符串列
Func getCommentLine($CmtChar,$CmtNumber)
$ResultStr = ""
For $i = 0 to $CmtNumber -1
$ResultStr = $ResultStr & $CmtChar
Next
Return $ResultStr
EndFunc
;---------------------------------------------------------------------------

用AutoIt自带工具编译成exe文档后,在TotalCmd中设置一个自定义命令,参数是
%P,这样就可方便地在当前活动目录中创建Readme.txt文件了。

2007年5月17日星期四

Windows下没有图形界面

Windows是以图形界面的方便易用而行销于世,但如果没有图形界面,该如何控制Windows呢?
昨天虾米管的服务器出现问题了,其无法启动“网络连接”界面来设置网卡的IP地址。我怀疑是某个服务进程损坏了。重装Windows是最后一步庸招,当前还不需要使出来。在没有图形界面的时候,命令行是最有效的工具。
我的方法是编写如下Bat文件,通过 netsh interface 命令修改了网卡的IP地址。
netsh interface ip reset name="本地连接"
netsh interface ip set address name="本地连接" source=static addr=*.*.*.* mask=255.255.255.0
netsh interface ip set address name="本地连接" gateway=*.*.*.* gwmetric=1
netsh interface ip set dns name="本地连接" source=static addr=*.*.*.*
netsh interface ip set wins name="本地连接" source=static addr=none

看来在Windows下,学习命令行还是相当有用的。

2007年3月30日星期五

美丽的素数 伟大的证明[转贴]

(来源: 科学网)

公元前3世纪,古希腊数学家欧几里得已经证明素数的数目是无穷的;2004年,陶哲轩和格林证明存在任意长的素数等差数列,他们的发现揭示了素数中存在的某种规律。

在数学家的眼中,素数是美丽的。就像原子之于化学家、DNA之于遗传学家,素数是自然界中全部数的最基本的结构砖块。那么究竟什么是素数呢?也许任何一位小学三年级的学生都会清楚地回答这个问题:在正整数中,除了1以外,只能被自身和1整除的数就是素数,素数从2,3,5,7,11和17开始……

美丽的素数

1,2,3……是正整数,其他数字如负数、有理数则都是以正整数为基础定义出来的,所以,研究正整数的规律非常重要。因为任何一个整数均可表示为素数的乘积,而且这个表示是唯一的,所以,研究清楚素数的问题非常重要,但从素数中是很难得到一条定理的。

公元前3世纪,古希腊数学家欧几里得已经证明素数的数目是无穷的。今天,陶哲轩和格林证明“存在任意长度的素数等差数列”,揭示了素数中存在的某种规律。

什么是等差数列呢?这是一个古老的数学课题。一个数列从第二项起,从后项减去前项所得的差是一个相同的常数,则这个数列就被称为等差数列。比如,1,3,5是一组由三个数构成的等差数列,1,3,5,7则是由4个数构成的等差数列。

用素数构成的等差数列被称为素数等差数列。比如从5开始,以12为间隔常数,就可以得到这样的序列:5,17,29,41,53,65……但对这个数列来说,只有前5个数是素数,因此,5,17,29,41,53是一个由5个素数构成的等差数列。因为65可以被5和13整除,不是素数,所以这个特定的素数等差数列不可能延展到6个数的长度。

问题出现了:由其他素数构成的等差数列会更长吗?答案是肯定的。事实上,199,409,619,829,1039,1249,1459,1669,1879,2089就是间隔常数为210的10个素数构成的等差数列。

而且,数学家们一直认为,由素数构成的等差数列可以任意长,这个猜想提出的时间太长,以至没有人知道这个问题最初是由谁提出来的。但是,在2004年前,没有数学家能证明它。

永不消失的素数

到目前为止,已知的素数等差数列的长度为23,即由23个素数构成的等差数列,而且这还是在当今最先进的计算机上找到的,这个数列的第一个数是 56211383760397,数之间的间隔常数为44546738095860,最后一位数是56211383760397+ 44546738095860×22.

根据上面的描述,一个比较清楚的事实是:随着自然数数值的增加,素数的分布变得越来越稀疏,要寻找这样的等差素数序列就越来越困难。但是,古希腊数学家知道素数是永远不会彻底消失的,自然界中有无穷多个素数。

尽管在正整数中,素数看起来是以一种随机的方式出现的,但在19世纪末,法国数学家雅克。哈达玛达(Jacques Hadamard)和比利时数学家法勒布赛(Charles de la Vallee-Poussin )证明:一种隐藏的规则存在于素数稀疏的背后。换言之,在看似混乱无序的素数数列中,一定存在某种规律。

而存在任意长的素数等差数列则是素数性质中的另外一种规律。尽管数学家一直认为“存在任意长度的素数等差数列”,但到2004年前,还没有人能证明它的存在。

有关这个问题的一个真正的进展出现在1939年,当时,荷兰数学家Johannes van der corput证明:有无穷多个由3个素数构成的等差数列。那么,由4个素数构成的等差数列的数目是不是也无穷多呢?

伟大的证明

英国大数学家Atath Brown证明,由前面三个素数和后面不超过两个素数的乘积构成的4个数的等差数列有无穷多。

1975年,匈牙利科学院的数学家施米列迪(Endre Szemeredi)证明了一个定理。如果简单地解释,这个定理的意思是在任何不会快速稀疏的整数子集中,肯定会有任意长度的等差数列。世界上只有极少数数学家能懂得这个证明,但施米列迪定理不适合于素数,因为,随着自然数的增加,素数的出现会突然变得稀疏。

2002年,两位20多岁的数学家着手证明施米列迪定理在某种特定性质的素数子集中也成立,他们希望能证明:有无穷多个由4个素数构成的等差数列。为了证明这个问题,陶和格林用了两年多的时间分析证明施米列迪定理的4个完整证明的背后因素。

陶哲轩说:“我们研究施米列迪定理并努力推进它,以便它能解决素数的问题。为了实现这个目标,我们借用这4个证明方法来建造一个施米列迪定理的扩展版。每次当格林和我陷入困境时,其中一个证明的思想总能解决我们的问题。”

两年后,用了一个非常漂亮的方法,格林和陶哲轩解决了问题,但结果实在惊人。2004年4月18日,两人宣布:他们证明了“存在任意长度的素数等差数列”,也就是说,对于任意值K,存在K个成等差级数的素数。例如 K=3,有素数序列3, 5, 7 (每两个差2)……K=10,有素数序列 199, 409, 619, 829, 1039, 1249, 1459, 1669, 1879, 2089 (每两个差210)。他们将长达 50页的论文——《素数含有任意长度的等差数列》——张贴在当日的预印本网站上,并向《美国数学年鉴》(Annals of Mathematics)投稿。

这是一项惊人的成就,他们的发现揭示了素数中存在的某种规律。这是一项伟大的成就,他们的证明立即在国际学术界引起轰动。2004年5月21日出版的美国《科学》杂志报道说,“两位数学家用数论中一个令人眩晕的突破结束了一个问题。”

《发现》杂志将陶哲轩和格林在素数方面的研究评选为2004年100项最重要的发现之一;2004年出版的《现代数论导引》已经引用这篇尚未正式发表的论文所涉及的工作。

据最新消息,格林和陶哲轩的这篇论文已被《美国数学年鉴》接受,即将出版。(王丹红/编译整理)