C#WinForm实现不规则窗体

这个纯属娱乐,因为其实用的不是太多,因为非主流,非标准的界面不符合用户的体验,不符合可用性功能的某一条HE规则。 为了完成这个效果,首先需要自己动手画个你需要的界面出来,界面边缘需要是一种可以很好区别的颜色,比如纯蓝色,因为实现不规则窗体是让C#使边缘颜色透明化来实现的,所以需要唯一识别。因为我用的图是一张灰色的图,我然后圈了一个蓝色的边缘。 刚开始的图; 然后新建windows应用程序。创建windows窗体并设置窗体基本属性。 (1)将 FormBorderStyle 属性设置为 None。 (2)将窗体的 BackgroundImage 属性设置为先前创建的位图文件。不必将文件添加到项目系统中;这将在指定该文件作为背景图像时自动完成。 (3)将 TransparencyKey 属性设置为位图文件的背景色,本例中为蓝色。(此属性告诉应用程序窗体中的哪些部分需要设置为透明。 ) 上面两个步骤已经完成了不规则窗体自身显示效果的制作。 有人说在24位色以下的环境中可以显示正常,但在24位色以上时黄色背景不能消失,所以上述不能胜任24位色以上环境。但我看到了一种解决方法,那就是先将背景图片添加到资源文件,然后在窗体构造时为窗体设置背景图片:   实测是可以的。 然后就是为窗体添加移动、关闭、最大最小化的事件。代码直接给出 还有其他一些比如关闭按钮的添加,都很简单,直接添加一个button,事件里写,两个选一个。 我最终的效果是个圆,可以看到,锯齿很明显,我想要效果好的话,那个位图得好好设计。这个只是演示。。所以。。还有一种方法是链接1中提供的,有兴趣的可以试试。 工程源码下载:IrregularForm.7z 参考: http://www.cnblogs.com/KissKnife/archive/2006/10/02/520116.html http://allancandy.cnblogs.com/archive/2005/09/01/227814.html

GET和POST有什么区别?及为什么网上的多数答案都是错的。

今天突然看到很多好的技术文章,转载收藏备用分享。 如果有人问你,GET和POST,有什么区别?你会如何回答? 我的经历 前几天有人问我这个问题。我说GET是用于获取数据的,POST,一般用于将数据发给服务器之用。 这个答案好像并不是他想要的。于是他继续追问有没有别的区别?我说这就是个名字而已,如果服务器支持,他完全可以把GET改个名字叫GET2。他反问道,那就是单纯的名字上的区别喽?我想了想,我觉得如果说再具体的区别,只能去看RFC文档了,还要取决于服务器(指Apache,IIS****)的具体实现。但我不得不承认,我的确没有仔细看过HTTP的RFC文档。于是我说,我对HTTP协议不太熟悉。这个问题也就结束了。 最普遍的答案 回来之后寻思了很久,他到底是想问我什么?我一直就觉得GET和POST没有什么除了语义之外的区别,自打我开始学习Web编程开始就是这么理解的。 可能很多人都已经猜到了,他要的答案是: 1. GET使用URL或Cookie传参。而POST将数据放在BODY中。 2. GET的URL会有长度上的限制,则POST的数据则可以非常大。 3. POST比GET安全,因为数据在地址栏上不可见。 但是很不幸,**这些区别全是错误的,**更不幸的是,这个答案还是Google搜索的头版头条,然而我根本没想着这些是答案,因为在我看来他们都是错的。我来一一解释一下。 GET和POST与数据如何传递没有关系 GET和POST是由HTTP协议定义的。在HTTP协议中,Method和Data(URL, Body, Header)是正交的两个概念,也就是说,使用哪个Method与应用层的数据如何传输是没有相互关系的。 HTTP没有要求,如果Method是POST数据就要放在BODY中。也没有要求,如果Method是GET,数据(参数)就一定要放在URL中而不能放在BODY中。 那么,网上流传甚广的这个说法是从何而来的呢?我在HTML标准中,找到了相似的描述。这和网上流传的说法一致。但是这只是HTML标准对HTTP协议的用法的约定。怎么能当成GET和POST的区别呢? 而且,现代的Web Server都是支持GET中包含BODY这样的请求。虽然这种请求不可能从浏览器发出,但是现在的Web Server又不是只给浏览器用,已经完全地超出了HTML服务器的范畴了。 知道这个有什么用?我不想解释了,有时候就得自己痛一次才记得住。 HTTP协议对GET和POST都没有对长度的限制 HTTP协议明确地指出了,HTTP头和Body都没有长度的要求。而对于URL长度上的限制,有两方面的原因造成: 1. 浏览器。据说早期的浏览器会对URL长度做限制。据说IE对URL长度会限制在2048个字符内(流传很广,而且无数同事都表示认同)。但我自己试了一下,我构造了90K的URL通过IE9访问live.com,是正常的。网上的东西,哪怕是Wikipedia上的,也不能信。 2. 服务器。URL长了,对服务器处理也是一种负担。原本一个会话就没有多少数据,现在如果有人恶意地构造几个几M大小的URL,并不停地访问你的服务器。服务器的最大并发数显然会下降。另一种攻击方式是,把告诉服务器Content-Length是一个很大的数,然后只给服务器发一点儿数据,嘿嘿,服务器你就傻等着去吧。哪怕你有超时设置,这种故意的次次访问超时也能让服务器吃不了兜着走。有鉴于此,多数服务器出于安全啦、稳定啦方面的考虑,会给URL长度加限制。但是这个限制是针对所有HTTP请求的,与GET、POST没有关系。 安全不安全和GET、POST没有关系 我觉得这真是中国特色。我讲个小段子,大家应该可以体会出这个说法多么的可笑。 觉得POST数据比GET数据安全的人会说 _ “防君子不防小人;中国小白多,能防小白用户就行了。”_ _ “哼,”我不以为然,“那你怎么不说,_URL__参数都Encode__过了,或是Base64__一下,小白也看不懂啊。” 那人反驳道,_“_Encode__太简单了,聪明点儿的小白很容易就可以Decode__并修改掉。” 我笑道,_“五十步笑百步耳,再聪明点儿的小白还会截包并重发呢,_Opera__就有这功能。” 那人阴险地祭出神器——最终解释权,说,“这个不算小白。” 我日啊。 最后一点儿感想 我之前一直做Windows桌面应用,对Web开发无甚了解,直到一年多前转做服务器端开发,才开始接触到HTTP。(注意,我说的是HTTP,不是HTML。服务器开放接口是基于REST理念设计的,使用的协议是HTTP,但是传输的内容不是HTML。这不是Web Server,而是一个Web Service) 所以我对于GET和POST的理解,是纯粹地来源于HTTP协议。他们只有一点根本区别,简单点儿说,一个用于获取数据,一个用于修改数据。具体的请参考RFC文档。 如果一个人一开始就做Web开发,很可能把HTML对HTTP协议的使用方式,当成HTTP协议的唯一的合理使用方式。从而犯了以偏概全的错误。 可能有人会觉得我钻牛角尖。我只是不喜欢模棱两可,不喜欢边界不清、概念不明,不喜欢“拿来主义”,也不喜欢被其它喜欢钻牛角尖的人奚落得无地自容。 “知之为知之,不知为不知,是知也。” 原文链接:http://www.cnblogs.com/nankezhishi/archive/2012/06/09/2542968.html

SASS用法指南

作者: 阮一峰 日期: 2012年6月19日 学过CSS的人都知道,它不是一种编程语言。 你可以用它开发网页样式,但是没法用它编程。也就是说,CSS基本上是设计师的工具,不是程序员的工具。在程序员眼里,CSS是一件很麻烦的东西。它没有变量,也没有条件语句,只是一行行单纯的描述,写起来相当费事。 很自然地,有人就开始为CSS加入编程元素,这被叫做“CSS预处理器”(css preprocessor)。它的基本思想是,用一种专门的编程语言,进行网页样式设计,然后再编译成正常的CSS文件。 各种"CSS预处理器"之中,我自己最喜欢SASS,觉得它有很多优点,打算以后都用它来写CSS。下面是我整理的用法总结,供自己开发时参考,相信对其他人也有用。 ============================================ SASS用法指南 作者:阮一峰 一、什么是SASS SASS是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护。 本文总结了SASS的主要用法。我的目标是,有了这篇文章,日常的一般使用就不需要去看官方文档了。 二、安装和使用 2.1 安装 SASS是Ruby语言写的,但是两者的语法没有关系。不懂Ruby,照样使用。只是必须先安装Ruby,然后再安装SASS。 假定你已经安装好了Ruby,接着在命令行输入下面的命令: gem install sass 然后,就可以使用了。 2.2 使用 SASS文件就是普通的文本文件,里面可以直接使用CSS语法。文件后缀名是.scss,意思为Sassy CSS。 下面的命令,可以在屏幕上显示.scss文件转化的css代码。(假设文件名为test。) sass test.scss 如果要将显示结果保存成文件,后面再跟一个.css文件名。 sass test.scss test.css SASS提供四个编译风格的选项: nested:嵌套缩进的css代码,它是默认值。 expanded:没有缩进的、扩展的css代码。 compact:简洁格式的css代码。 compressed:压缩后的css代码。 生产环境当中,一般使用最后一个选项。 sass –style compressed test.sass test.css SASS的官方网站,提供了一个在线转换器。你可以在那里,试运行下面的各种例子。 三、基本用法 3.1 变量 SASS允许使用变量,所有变量以$开头。 $blue : #1875e7; div { color : $blue; } 如果变量需要镶嵌在字符串之中,就必须需要写在#{}之中。 $side : left; .rounded { border-#{$side}-radius: 5px; } 3.2 计算功能 SASS允许在代码中使用算式: body { margin: (14px/2); top: 50px + 100px; right: $var * 10%; } 3.3 嵌套 SASS允许选择器嵌套。比如,下面的CSS代码: div h1 { color : red; } 可以写成: div { hi { color:red; } } 属性也可以嵌套: p { border-color: red; } 可以写成: p { border: { color: red; } } 注意,border后面必须加上冒号。 3.4 注释

FreeAnony-代理采集设置工具

这个名字确实有点不太好。。因为刚开始我想到这个工具是在今天早上看到一个别人的代理工具的时候,突然想做的,没有好好规化,结果后来代码越写越多。。不过收获很大。 先看界面,因为是简单实现一下,所以就不要吐槽界面了。。 刚开始想的思路就是先去一个经常发布代理IP的网页去采集。然后解析成一条条的信息。然后显示出来。中途遇到几个问题,一个就是在做代理验证的时候,没有用多线程,导致直接界面无响应。另一个就是DataGridView控件要实现对一个数组的绑定,需要的一个实体对象。

gif反转工具

首先看下效果图: 然后是两张gif的对比  //原本图是正着走的  //处理后是倒着走的 gif是动态的嘛。然后我昨天和一个朋友聊天的时候发了一串相同的gif图,然后看着千篇一律的东西。我想能不能写个程序实现gif的初始状态不同呢。什么意思呢。我们知道,gif是由帧构成的,我想实现的功能是比如一个gif共有十帧,那么我写出来的程序能够生成10个gif文件,分别对应不同的初始状态来进行循环。后来一想,gif帧太多的话,比较慢,而且也不实用,于是决定简化一下,只做一个反转工具,比如一个gif是从左到右播放的,通过这个成功可以生成一个相同的gif图,不过是倒着播放的。 思路很简单,就是先把gif分解成很多帧,然后对帧进行合并,合并帧之前把帧的位置反转一下就可以了。因为我自己对图像处理的知识不懂,只想到了思路,所以这些功能都要找些资料,然后修改,测试。 分割帧的代码如下

MySQL ERROR 1005: Can't create table (errno: 150)解决办法

最近在做数据库大作业,采用mysql建立数据库的时候出现了这个情况,查了一下,解决了。 出现问题的大致可能情况 1、外键的引用类型不一样,如主键是int外键是char 2、找不到主表中引用的列 3、主键和外键的字符编码不一致,也可能存储引擎不一样 对于第一个问题,检查一下自己的主外键记录数据类型是否一样,改了就行了,对于第二个问题,同样的道理,确定你主表中有对应的列。对于第三个问题  括号外面的语句设置了引擎。实战过程中通过。中间的外键设置了delete 和update约束。uid引用了pw_other表中的uid键 记下语法,出现问题的时候就可以用了。

属性文法

 我们知道,许多编译程序采用属性文法和语法制导翻译方法对语义处理工作进行比较规范和抽象的描述。  而一个属性文法包含一个上下文无关文法和一系列文法规则,语义规则是指:对于文法的每个产生式都配备了一组属性的计算规则  语义规则附在文法的每个产生式上,而语法制导翻译是指在语法分析过程中,完成附加在所使用的产生式上的语义规则描述的动作。  ·语法制导:基于语法分析中用到的文法产生式  ·翻译:完成语义分析的各项功能,不仅指生成中间代码  形式上讲,一个属性文法是一个三元组,A=(G,V,F),其中G是一个上下文无关文法;V是有穷的属性集,每个属性与文法的一个终结符或非终结符关联,属性加工的过程即是语义处理的过程。F是关于属性的属性断言或一组属性的计算规则(称为语义规则)。断言或语义规则与一个规则式关联,只引用该规则式左端或右端的终结符或非终结符关联的属性。形式化的东西看看就好,后面给出具体例子分析。  既然称之为属性文法,那么什么属性呢。这些属性代表与文法符号相关信息,比如它的类型、值、代码序列、符号表内容等等。属性与变量一样,可以进行计算和传递。可以类比我们平时写代码时候一些成员变量。。属性又分为综合属性和继承属性。 n在一个属性文法中,对应于每个产生式A→a都有一套与之相关联的语义规则,每条规则的形式为: b:=f(c1,c2,…,ck),只有在已知 c1-ck 值的基础上,才能计算属性值 b, 称属性 b 依赖于属性 c1-ck,至于c1-ck依赖于哪个,就得看由c1-ck在左侧的规则了。也就是看下面的规则了。  这里,f是一个函数,而且或者  1. b是A的一个综合属性并且c1,c2,…,ck是产生式右边文法符号的属性,或者  2. b是产生式右边某个文法符号的一个继承属性并且c1,c2,…,ck 是A或产生式右边任何文法符号的属性。 属性b依赖于属性c1,c2,…,ck。  属性文法中常用记号N·t表示与非终结符号N相关联的属性t。  注意:¨终结符只有综合属性,由词法分析器提供 ¨非终结符既可有综合属性也可有继承属性,文法开始符号的所有继承属性作为属性计算前的初始值 ¨在语法树中,一个结点的综合属性的值由其子结点的属性值确定。一个结点的继承属性由此结点的父结点和/或兄弟结点的某些属性确定  根据包含的属性类型,属性文法分为:S-属性文法和L-属性文法  S-属性文法是仅包括综合属性的属性文法;L -属性文法是包括综合属性和继承属性的属性文法。  给出一个简单的实例说明上面的内容:  考虑非终结符A,B和C,其中,A有一个继承属性a和一个综合属性b,B有综合属性c,C有继承属性d。产生式A→BC可能有规则 C.d:=B.c+1  A.b:=A.a+B.c  而属性A.a和B.c在其它地方计算  为什么是这样的,因为此时A就是A,B是X1,C是X2,对于d来说,他是产生式右部C的一个属性,c是右部B的属性,属性d依赖于属性c,和1,所以它是C的继承属性,对于c来说,他是产生式右部B的一个属性,但是c不依赖于d,而是d依赖于c所以c属性类型无法确定,对于b,他是A的一个属性,并且a是A的属性,c是产生式右部的属性,所以b是A的综合属性,而对于a,因为不能确定a属性依赖于那个属性,所以。无法得知。从上面我可以得出一个规律,对于一个属性规则来说,一条规则只能确定其左侧的属性类型,而右侧的属性需要由一个由他在左侧的规则来确定。比如,可以看到上面的规则中,c和a都不能确定,就是因为在规则右侧。  此部分可能理解不够深刻,如有错误欢迎指正。  参考:  http://jpkc.hdu.edu.cn/computer/byyl/online/5-2.htm  http://metc.gdut.edu.cn/compile/nandian/n-8.htm

你为什么会说是?-[影响力]

今天早上把这本书读完了,短短的300页,绝对是今年读到的又一本经典之作,书摘什么的因为是读的纸质版,所以没有写什么笔记,但是还是简单的总结下书中的内容。顺带谈谈自己的感受。  就像昨天文章中提到的,这本书讲的不是成功学,而是心理学,讲我们在生活中为什么有时候会受到他人,或者是一些定律的影响,不知不觉中做了后来后悔的事情。或者是明明已经后悔了,却无法反悔。  影响力的几个武器;  第1种武器:互惠  互惠原理认为,我们应该尽量以相同的方式来回报他人为我们所作的一切。接受往往和偿还联系在一起,尽管互惠原理经常带给人们以负债感,但是总体而言,我们从中得利的时候还是占多数的,相比而言还是划算的。从而,相信并服从这个原理成为人们日常生活中一个十分重要的准则,而违背它则要付出严重的代价。人们普遍对那种只求索取不知偿还的人感到不信任,并尽量远离避免与之接触。往深里讲,互惠原理是人类社会形成的一大助力,是群体协作的默认基础。 在商业上最经典的案例则体现在商场里的“免费试用”中。很多人觉得,如果从那个笑容可掬的小姐手中接受了可以免费品尝的食物,就不好意思把杯子一还转身离开,总得买点什么吧,即时他们对那种商品并不是那么感兴趣。  第2种武器:承诺与一致  一旦我们做出了一个决定,或选择了一种立场,就会有发自内心以及来自外部的压力来迫使我们与此保持一致。在这种压力下,我们总是希望以实际行动来证明我们以前的决定是正确的。我们要让自己相信,自己作出了明智的抉择,而且毫无疑问地,自我感觉良好。  一个例子是安利公司就要求每个销售人员都要定下一个销售目标,而且不是光说说而已,必须得写下来。书面声明之所以特别有效,原因之一是它能使目标和方向都更明确,更重要的是,它能够轻易地公之于众。一旦个人公开选择某种立场之后,马上就会有一种维持这种立场的压力,因为他想在别人眼里显得前后一致。我承认我非常讨厌这家公司,有个笑话是这样的,十年后,我们不经意间再次相遇,她低声问我:“这些年过得好吗?她对你好吧。”我很伤感,说:“我还没结婚,一直等你。”她眼圈红了红,说:“你晚上7点来宾馆找我吧。”七夕夜,月如钩,我手捧鲜花,提前半小时来到宾馆,她迎我进去,招呼我坐下,幽幽问道:“你听说过安利吗?”  要想戒烟或者减肥成功,这种方法是非常有效的。给自己在乎的人说自己一定要减肥成功,并且勇敢说出来,这种压力会迫使你减肥成功  第3种武器:社会认同  有点像是从众,但不完全是,社会认同原理指出,我们进行是非判断的标准之一就是看别人是怎么想的,尤其是当我们要决定什么是正确的行为的时候。如果我们看到别人在某种场合做某件事情,我们就会断定这样做是有道理的。一个很有趣的实验可以证实这一点,站在一条繁忙的人行道上,选定天空中的某一快空白,盯着看上1分钟,在这段时间里你的身边大概不会发生什么事情;第二天,你带上四五个朋友到同一地点一起往上看,不出1分钟,就会有大群路人停下来,把脖子伸得长长的,跟你们几个一起往天上看;即使是那些没有加入你们的行人,也无法阻抗那种至少往上瞄一眼的压力。  在形势模糊不清的时候,每个人都希望看一看别人正在做什么,从而致使一个极为重要的现象的出现――“多元无知”。这个可以很好的解释小悦悦事件,因为路人多了以后,前一个的人的行为影响了后一个人,大家都在看别人在做什么,并且人多了以后,每个人的责任感被分散,因此,施救的概率降下来了,我不是要辩护什么,而是反对喜欢扣标签的人,这件事并不能说明社会道德什么下降及其厉害,虽然有下降,这件事只是很典型的一个社会心理学实例罢了。  书中做出指出,如果你遇到了危难,很可能出现人很多,但没人施救。。 本书作者的建议是,当你遇到突发灾难时,直接从人群中挑出一个人来,注视着他,指着他,直接对他说:“你,蓝夹克的先生,我需要帮助,请叫一辆救护车来”,总之,在紧急状态中需要帮助时,最有效的策略是减少周围人对你的处境和他们和责任的不确定性,尽量把你所需要的帮助表达精确。不要让旁观者自己去下结论,因为社会认同原理和多元无知效应很可能使他们对你的处境作出错误的诊断,在人群中尤其如此。 这样说了以后,被指定的那个人有了一种责任感,进行施救,其他人会因为确定了状况加入救助的行列。  第4种武器: 喜好  一句话就是:人们总是比较愿意答应自己认识和喜爱的人提出的请求 ,产生喜好的来源主要有外表的吸引力,这个不多解释,美女得到的帮助在陌生的时候必其他人要多,相似性,指对和自己相似的人,比如外貌,衣着,爱好的相同都会产生;称赞,是指人们会奉承话通常来之不拒,并对奉承者产生好感,接触和合作,指一般经历了一起合作的人之间会产生明显的好感,一个有意思的例子是人们对和他们一起吃饭的人好感尤其强烈;关联,指人们会爱屋及乌,比如中国古代的近朱者赤,近墨者黑,表示的有点这个意思,人们会把你交往的人的品质关联到你自己身上,也会把你传递的消息关联上你的身上,如果你经常传递不好的消息,,你懂的。  要对付这么多赢取我们好感的手段,不是一件容易的事。一个有效的方法是,将注意力集中在效果而不是原因上。当我们在和那些老练的推销员打交道时,我们只需要注意一件事,我们是不是过于迅速地对这个人产生了过多的好感。一旦答案为“是”的时候,我们就该反击了。不过这个只针对于商业上的,在真实的社交中,我还是很相信一见钟情,相见恨晚的。嘻嘻。  第5种武器:权威  密歇根大学的心理学教授Mligram (1974)主持了一个实验,结果表明,具有独立思考能力的成年人也会为了服从权威的命令而做出一些完全丧失理智的事情。这可以解释那些利用各种假头衔,衣着(比如警服)来骗人的人。如何克服,两步,第一步,问自己对方是不是会真的专家,第二步问自己他是不是会为自己考虑,同时还要提防有些专家通过抛出一些自己的小缺点来增强”诚实“,表明自己的可信度。这里面有个说法是我以前在社会心理学里看到的,讲到一个演讲的成功与否很大程度上取决于权威的权威,和主题没什么太大关系,这可以解释为什么有时候听专家演讲觉得跟没听似的。。  第6种武器:短缺  短缺原理在现实生活中最常见的运用就是商家所策划的“限量版”商品。不管数量有限的信息是真的还是伪造的,商家的用意都是让顾客相信某种东西不可多得,从而立刻觉得它身价百倍。与数量有限技巧相对应得是“截止时间”策略,也就是对顾客获得推销从业者提供得商品的机会加上时间限制,所谓的“最后三天,清仓甩卖”即源于此。我家附近的最后三天已经for循环了N次了。。。  最后作者也认为世界还是很复杂的,有时候被影响影响也无伤大雅,因为事情太多,不可能完全兼顾,但是对于一些很重要的事情还是要注意避免这类影响。我在读的过程中,也就是书的前半段,讲到利用对比原理和喜好原理来审问犯人,一个好警察一个坏警察,来套取犯人的口供,这在法律上是许可的 ,可我却有些不好的感受,对犯人来说,他受到了心理学的影响,他以为那个警察真的关心他,他以为这个好警察真的好,可是事实上,这只是一种策略罢了,这是多么残忍的一件事啊,所以,昨天我想到了一个词,叫做反心理学,我也不知道具体想表达什么意思,可能当时想的就是避免受到这类心理学应用的影响,不被残忍对待吧。

Turing机、人工智能以及我们的世界

matrix67大牛太帅了。这篇文章给我很大的震撼,他传递的信息远不止计算机世界。强烈推荐,精彩的部分做了引用,事实上,全都很精彩啊。  昨天终于读完了《The Annotated Turing》一书,第一次完整地阅读了 Turing 最经典的那篇论文,理解了 Turing 机提出的动机和由此带来的一系列结论。不过,这本书的最大价值,则是让我开始重新认识和思考这个世界。在这里,我想把我以前积累的哲学观点和最近一些新的思考记下来,与大家一同分享。《The Annotated Turing》一书中的一些学术内容,留待以后几篇日志与大家分享。今年是 Alan Turing 诞辰 100 周年,图灵公司将推出这本书的中译本《图灵的秘密》,现在正在紧张的编辑排版中,不久之后就能和大家见面。  1928 年, David Hilbert 提出了一个著名的问题:是否存在一系列有限的步骤,它能判定任意一个给定的数学命题的真假?这个问题就叫做 Entscheidungsproblem ,德语“判定性问题”的意思。大家普遍认为,这样的一套步骤是不存在的,也就是说我们没有一种判断一个数学命题是否为真的通用方法。为了证明这一点,真正的难题是将问题形式化:什么叫做“一系列有限的步骤”?当然,现在大家知道,这里所说的“有限的步骤”指的就是由条件语句、循环语句等元素搭建而成的一个机械过程,也就是我们常说的“算法”。不过,在没有计算机的时代,人们只能模模糊糊地体会“一个机械过程”的意思。 1936 年,Alan Turing 在著名的论文《On computable numbers, with an application to the Entscheidungsproblem》中提出了一种假想的机器,第一次给了“机械过程”一个确凿的含义。  Turing 提出的机器非常简单。假设有一张无穷向右延伸的纸条,从左至右分成一个一个的小格子。每一个小格子里都可以填写一个字符(通常是单个数字或者字母)。纸条下方有一个用来标识“当前格子”的箭头,在机器运行过程中,箭头的位置会不断移动,颜色也会不断变化。不妨假设初始时所有格子都是空白,箭头的颜色是红色,并且指向左起第一个格子。为了让机器实现不同的功能,我们需要给它制定一大堆指令。每条指令都是由五个参数构成,格式非常单一,只能形如“如果当前箭头是红色,箭头所在格子写的是字符 A ,则把这个格子里的字符改为 B ,箭头变为绿色并且向右移动一格”,其中最后箭头的移动只能是“左移一格”、“右移一格”、“不动”中的一个。  精心设计不同的指令集合,我们就能得到功能不同的 Turing 机。你可以设计一个生成自然数序列的 Turing 机,或者是计算根号 2 的 Turing 机,甚至是打印圆周率的 Turing 机。 Turing 本人甚至在论文中实现了这么一种特殊的 Turing 机叫做通用 Turing 机,它可以模拟别的 Turing 机的运行。具体地说,如果把任意一个 Turing 机的指令集用 Turing 自己提出的一种规范方式编码并预存在纸条上,那么通用 Turing 机就能够根据纸条上已有的信息,在纸条的空白处模拟那台 Turing 机的运作,输出那台 Turing 机应该输出的东西。  但是, Turing 机并不是无所不能的。 Turing 证明了一个看似有些惊人的事实:不存在这样的一个 Turing 机,它能读取任意一个 Turing 机的指令集,并判断该 Turing 机是否将会在纸条上打印出至少一个 0 。注意,简单地用通用 Turing 机做模拟并不是一个可行的方案,因为模拟到现在还没有打出 0 ,不意味着今后也就永远不会打出 0 。这个定理有一个更深刻的含义,即没有一种通用的方法可以预测一台 Turing 机无穷远后的将来(后人把这个结论简化为了著名的停机问题)。正如《The Annotated Turing》封底上的一段文字所说:在没有计算机的时代, Turing 不但探索了计算机能做的事,还指出了计算机永远不能做到的事。  在论文的最后一章, Turing 给出了一种 Turing 机指令集和一阶逻辑表达式的转换规则,使得这个 Turing 机将会打出 0 来,当且仅当对应的一阶逻辑表达式为真。然而,我们没有一种判断 Turing 机是否会输出 0 的算法,因此我们也就没有一种判断数学命题是否为真的通用办法。于是, Entscheidungsproblem 有了一个完美的解答。  有趣的是,Turing 机本身的提出比 Entscheidungsproblem 的解决意义更大。计算机诞生以后,出现了五花八门的高级编程语言,一个比一个帅气,但它们的表达能力实际上都没有超过 Turing 机。事实上,再庞大的流程图,再复杂的数学关系,再怪异的语法规则,最终都可以用 Turing 机来描述。 Turing 机似乎是一个终极工具,它似乎能够表达一切形式的计算方法,可以描述一切事物背后的规律。在同一时代,美国数学家 Alonzo Church 创立了 λ 算子(λ-calculus),用数学的方法去阐释“机械过程”的含义。后来人们发现, Turing 机和 λ 算子是等价的,它们具有相同的表达能力,是描述“可计算性”的两种不同的模型。 Turing 机和 λ 算子真的能够描述所有直观意义上的“可计算数”、“可计算数列”、“可计算函数”吗?有没有什么东西超出了它们的表达能力?这个深刻的哲学问题就叫做 Church–Turing thesis 。当然,我们没法用形式化的方法对其进行论证,不过大家普遍认为, Turing 机和 λ 算子确实已经具有描述世间一切复杂关系的能力了。人们曾经提出过一些 hypercomputer ,即超出 Turing 机范围的假想机器,比如能在有限时间里运行无穷多步的机器,能真正处理实数的机器,等等。不过这在理论上都是不可能实现的。

LR(1)项目集规范簇的构造

首先我们知道LR(0)的项目的形式是[A→α·β ]这样的.而在LR(1)中的项目形式是[A→α·β ,a ],其中A→α·β 为LR(0)项目,称为心,a为终结符或#,称为向前搜索符。对归约项目[A→α·,a],仅当前输入符号是a时,才能用A→α进行归约。一会将会看到具体的例子。  课本上给出的规则是:我将要对照着规则来说明,这里要强调一下,",‘在这里是分隔符。不是终结符。他是一个标志,  以S′→·S,#属于初始项目集中,把’#‘号作为向前搜索符,表示活前缀为γ(若γ是有关S产生式的某一右部)要归约成S时,必须面临输入符为’#‘号才行。因此对初始项目S′→·S,# 求闭包后再用转换函数逐步求出整个文法的LR(1)项目集族。具体构造步骤如下:  (1) 构造LR(1)项目集的闭包函数。  a) I 的任何项目都属于CLOSURE(I) b) 若有项目[A→α·Bβ,a ]属于CLOSURE(I),B→γ是文法中的产生式,β∈V*,b∈FIRST(βa), 则[B→·γ,b]也属于CLOSURE(I)中。 c) 重复b)直到CLOSURE(I)不再增大为止。  (2) 转换函数的构造  LR(1)转换函数的构造与LR(0)的相似,GO(I,X)=CLOSURE(J) 其中I是LR(1)的项目集,X是文法符号: J={任何形如[A→αX·β,a]的项目 | [A→α·Xβ,a]∈I}  例如下列文法G′为:  (0) S′→S (1) S→aAd (2) S→bAc (3) S→aec (4) S→bed (5) A→e 构造他的LR(1)项目集规范簇。  以I0=CLOSURE(S′→·S,#)开始。运算。若有项目[A→α·Bβ,a ]属于CLOSURE(I),B→γ是文法中的产生式,β∈V*,b∈FIRST(βa), 则[B→·γ,b]也属于CLOSURE(I)中。此时,我们可以把S看成B,#看成a,然后需要求FIRST集合,此时没有β,a为#,所以FIRST(#)中只有一个b=#,而S有四个产生式。所有四个产生式加上#都是在I0中,最终求得的I0项目集为  { S′→·S,# S→·aAd,# S→·bAc,# S→·aec,# S→·bed,# }  然后使用GO函数来构造I1,从J={任何形如[A→αX·β,a]的项目 | [A→α·Xβ,a]∈I}我们可以知道I1的核(最初的产生式)就是这里的J,然后呢。X是I(也就是我们的I0)中的·后面的符号,也就是输入符。。可以看到在I0中,X可以为S,a,b,我们先以I1=GO(I0,S)=CLOSURE( S′→S·,# ),注意,·号已经前进了。因为J是I输入进一的项目,求I1,发现·后面没符号了,所以闭包就是他自己了。最终求得的I1的项目集为:  {S′→S·,# }  我们上一步是用的I1=GO(I0,S)来求得,我们求I2的时候使用GO(I0,a)来求,此时X就是a了。然后我们吧I0中符合的项目中的·后移一位得到J然后对J求闭包,就是I2了。此处J=S→a·Ad,# 和S→a·ec,#  I2=GO(I0,a)=CLOSURE(S→a·Ad,# S→a·ec,#),然后又回到了求闭包了。  对于S→a·ec,#,因为输入符下一位是一个终结符,也就是说没有B→γ这样的产生式,所以这个就不用继续向下求闭包了,闭包就是他自己嘛。然后关键是S→a·Ad,# 此处的A相当于规则中的B,d相当于规则中的β,A→e存在。为了确定这个心的向前搜索符,我们根据规则需要求b∈FIRST(βa),这里也就是求First(d#),显然结果为b=d,规则中指出[B→·γ,b]也属于CLOSURE(I),所以可以确定A→·e,d也在I2中。。  最终I2的项目集为  { S→a·Ad,# S→a·ec,# A→·e,d }  到这里,关键点就说完了。只需要继续求GO(I0,b),然后求GO(I1,X),GO(I2,X)等等。X的确定前面已经说了,就是I1,I2的·后面的符号。就行了。。当然像此处的I1,·后面已经没付好了,所以GO(I1,X)就不用求了。。  这种东西还是要自己手动练习的。所以我给出最终的全部项目集规范簇,大家按照这个步骤来做一做。看看结果对不对吧。 I0: S′→·S,# S→·aAd,# S→·bAc,# S→·aec,# S→·bed,#I1: S′→S·,#I2: S→a·Ad,# S→a·ec,# A→·e,dI3: S→b·Ac,# S→b·ed,# A→·e,cI4: S→aA·d,#I5: S→ae·c,# A→e·,d I6: S→bA·c,# I7: S→be·d,# A→e·,c I8: S→aAd·,# I9: S→aec·,# I10:S→bAc·,# I11:S→bed·,#  构造的过程很繁琐。有点暴力计算的意思。不过,真正算起来步骤还是比较少的。