存档:2009年九月

算法世界的哲学思考

九月 16, 2009 | 数学, 数据结构算法, 软件工程/编程技巧/设计模式 | RSS 2.0

每每读到一些好的算法都会让人有叹为观止的感觉,巧妙的设计让我们回味起数学,物理等,物理的测万有引力,远古时代没有任何工具的情况下的测量出地球的半径,人就是这么一个奇妙的动物。想体味下巧妙,你可以看下《啊哈,灵机一动》google黑板报的《数学之美》系列,微软的《编程之美》等,大道至简,简单的道理抽象到了一定的高度就适应于任何事物,在我看来数学和哲学都是抽象到一定程度的事物,你可以体味下1+1=2,事物的都是有联系的普遍性。俗话说大道至简。
读计算机以来,自然也学到不少算法,虽然现在搞些web的开发,当初也是软件开发的,总是忘不了学过的那些经典的算法,经常及其老师讲解时候的费力和樯橹灰飞烟灭。自己体味好多计算机里面的算法,定理,思想,更大自然世界很协调。
先举几个简单的小例子:
1 将两只小猫放到足球场的对面,相距100码,他们以每分钟10码的速度相向行走。同时这两只小猫的母亲在足球场的一端,它可以以每分钟100码的速度跑步,猫妈妈从一只小猫跑到另一只小猫,来回轮流跑而速度不减,一直跑到两只小猫在中场相遇,问猫妈妈跑了多远?
2 渔民在池塘放养了大量鱼苗。养到一定程度后,我们要估计现在池塘中有多少鱼?
3 有一根27厘米的细长杆,在第3厘米,7厘米,11厘米,17厘米,23厘米在五个位置各放有一只蚂蚁,木杆很细,不能同时通过两次蚂蚁,开始时,蚂蚁头朝右还是朝左是任意的,他们只会超前或者调头,当不会后退。当任意两只蚂蚁碰头时,两只蚂蚁会同时掉头朝反方向走,假设蚂蚁每秒钟可以走一厘米的距离,所有蚂蚁离开木杆的最短时间和最长时间。
4 棋盘覆盖问题。在一个2k x 2k ( 即:2^k x 2^k )个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。

1005341

5 某一天,一个新研究员向托马斯爱迪生报到。爱迪生要求他计算出一个空灯泡壳的体积。在使用测径仪和微积分进行数小时饿计算后,这个新员工给出了答案150立方厘米,而爱迪生在几秒之内计算就给出了更接近155,他是如何实现的呢?

—————————————-给出部分提示————————–

1 不要用蛮力,首先通过两只小猫可以计算出猫妈妈的跑步的时间,两只小猫相距100米,每分钟20码在接近,故5分钟完成,所以猫妈妈是500米

2 这个牵涉到数学中的概率等的知识,概率统计还是挺实用的一门学科,可以考虑用极大似然估算算法,即捞出一定数量的鱼,不能过少,坐上标记,过一定时间取出看看标记的比例

3 和第一个的思想有点像,碰头后蚂蚁会继续潜行,看做是个体运动就好考虑了

4 第四题图片方格少,还好,如果多了,你就不一定能搞定了,还需保证是4的k次幂,其实可以采用分治的思想,即图上可以上下左右四部分,带黑色宽那个就可以填好了,挨着黑色块的即中心的可以填好了,然后就把其他的搞定,如果更多如何?就行切分,分治,分而治理。

5 想想阿基米德王冠的故事你就明白了

现在可以看到了

一题三给我们一个解决问题的思路用时间求解较容易,摊还分析就是用这样一个思路,一如一个附加变量,位势,

二题,五题也是给我们一种思路转换问题的思路。4题给我们一个解决问题分而治之。

可以看到什么样的哲学思想呢?首先事物是联系的,解决了这个事物,和其关系的别的也就可以相应的解决了,整体和局部的思想,局部解决了,整体也就好了。

看看别的算法

1 递归于分治策略,递归?现实生活中哪里有递归的影子?没想到?那就照照镜子吧,看到了,这个就是递归,事物本身的属性,局部整体的哲学思想

2 动态规划,类似分治递归,当他们的若干个问题不是独立的是联系的,第n个问题和n-1个问题是有关系的,

3 贪心算法很明晰矛盾分主要矛盾和次要矛盾,抓住了主要矛盾就抓住了问题的核心

4 概率算法:事物发展的不确定性,螺旋式发展。舍伍德算法,拉斯维加斯算法,我们经典的抛针算π的算法,蒙特卡洛算法,现在基本都忘记了。

5 线性规划,回溯法,分枝限界法 这些都是通过把问题抽象,合理的布局,解决之,算是事物之间的联系吧。别的暂时没行到。

6np完全性理论和近似算法:图灵机等,应该是事物的发展变化的各个状态,著名的图灵机问题,问题的各个态势的变化,这个算法我不熟。

暂时先想到这里,也算是对自己学过的算法课程的一个回忆。

没有评论 »

批量替换文件夹下所有文件内容脚本(shell,php,python)

九月 14, 2009 | linux, php, python | RSS 2.0

批量替换一个文件夹下的字符或者其他的应该经常可以见到,近期读《卓有成效的程序员》有点感触,他提到了一些可以加快工作效率的容易让人忽略的小细节,加速法则,专注法则,自动化 法则,规范化法则。那这个批量替换应该属于自动化法则,有时候文件特别多的是很,替换是个非常容易烦人的事情。显然这些应该是计算机做的事情,下面给出以上三个版本:

shell:

sed跨行需要使用参数:N等控制,这里不适用,忘记。

shell学了个皮也不皮,毛也不毛

 
for i in `find . -name "*.html"`
do
sed "s|<\!--{if \!empty(\$this->_visiteduser->_gender)&& \(\$this->_visiteduser->_gender\)=='m'}-->他<\!--{else}--> 她<\!-  -{/if}-->|{\1}|g" $i > $i-new
mv $i $i-old
mv $i-new $i
done

当然你可以用sed的i直接替换,尽量替换前做个备份。

python的批量替换脚本:

刚开始学写的特别烂:

import os
import re
def getHtmlFile(rootdir):
allfile=[]
for   parent, dirnames, filenames   in   os.walk(rootdir):
for   filename   in   filenames:
#if os.path.isfile(os.path.join(0)
allfile.append(os.path.join(parent, filename))
return allfile
 
def replace(filename):
file_object = open(filename)
try:
all_the_text = file_object.read( )
finally:
file_object.close( )
'''
grouped_word = re.compile('<div id="header">([\s\S]*)?</div>')
all_the_text = re.sub(r'xxxxxxxxxxxxxxxxxx',all_the_text);
'''
all_the_text = re.sub('<div id="header">[\s\S]+?</div>','header',all_the_text);
all_the_text = re.sub('<div id="footer">[\s\S]+?</div>','footer',all_the_text);
#all_the_text = re.sub('\r','',all_the_text);
open(filename, 'w').write(all_the_text)
 
file=getHtmlFile('/home/liufb/studypython/gonglue');
test = re.compile("\.html$", re.IGNORECASE)
file = [f for f in file if test.search(f)]
for i in file:
print i+"\n"
replace(i)

学的时间相对比较长,但是依旧比较烂:

function changefile($filename) {
global $text1;
global $text2;
$file = file_get_contents($filename);
$file2 = preg_replace('@<div id="header">([\s\S]*)?</div>@iU',$text1,$file);
$file3 = preg_replace('@<div id="footer">([\s\S]*)?</div>@iU',$text2,$file2);
$file3 = preg_replace('@\r@iu','',$file3);
file_put_contents($filename,$file3);
 
}
function getFile($dirname) {
if ($handle = opendir($dirname)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
$file=$dirname.'/'.$file;
if(is_file($file) && substr($file,-5) =='.html') {
//echo $file."\n";
 
changefile($file);
}else if(is_dir($dirname.'/'.$file)) {
$dirscan = realpath($file);
//$dirscan = $dirname.'/'.$file;
//echo $dirscan."\n";
getFile($dirscan);
}
}
}
}
closedir($handle);
}
getFile('.');

没有评论 »

python初学记

九月 9, 2009 | linux | RSS 2.0

刚刚学习了一点python,感觉挺简单,看《dive into python》 两个小时就可以看完,像我这种啥也没学会乱起八糟,能写简单的php,c,shell,然后再学python,基本上都能理解,虽然语法和别的大部一样,但是import ,等还是都比较熟悉,只是控制块不用{}和大多数语言不一样,好多函数和c比较类似,以前面试过几家公司,大部分都说用python做抓取,心想用python有啥好处呢?高效?那还不如用c呢,开发速度快?php开发业不慢啊,虽然不支持多线程,但是cli可以多进程,网上学习了两个例子发现,果真写个抓取很简单。而且可以跑多线程。还不错。以后又空就捣鼓下。

openurl=urllib.urlopen(baiduurl)
text=openurl.read()
openurl.close()
r=re.compile(r’nowrap><a href=”s.+?>(.+?)</a>’,re.U|re.I|re.S)
m=r.findall(text)
if m:
print ‘crawl pasre success \n’
else:
print ‘#####parse’+ baiduurl +’some problems,please check##### \n’

抓取个东西就是这么简单。想多线程也简单

可以学习的几个:

1  http://wiki.ubuntu.org.cn/Python%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97

2 http://www.htmldata.cn/?p=212

3 http://www.htmldata.cn/?p=205

4 http://www.cnblogs.com/ashun/archive/2007/06/01/python_proxy_checker.html

5 http://www.hilaosan.com/post/python-spider-multithreading.html

6 http://hi.baidu.com/whoqiaoxin/blog/item/bb6fddc415ee09c839db495c.html

没有评论 »

For , While 那个更快?

九月 5, 2009 | c/c++, 数据结构算法, 软件工程/编程技巧/设计模式 | RSS 2.0

到底是for快还是while快?有人做了一下测试:

for (;;) {
}

while (1) {
}

生成的汇编分别是:

for的是:

.text
.globl _main
_main:
pushl    %ebp
movl    %esp, %ebp
subl    $8, %esp
L2:
jmp    L2
.subsections_via_symbols

while的是:

.text
.globl _main
_main:
pushl    %ebp
movl    %esp, %ebp
subl    $8, %esp
L2:
jmp    L2
.subsections_via_symbols

现在你知道了吧

—————————————————http://blog.marcelotoledo.org/2008/10/22/for-or-while/


				

没有评论 »

mod10校验算法(信用卡 银行)

九月 1, 2009 | 数据结构算法 | RSS 2.0

先看一下mod10算法的描述:

计算的规则:

1 Beginning on the right, with the digit that immediately precedes the check digit and moving toward the left, double every other digit. After doubling each selected digit, if the result is ten or greater, add the two digits together to arrive at a single-digit result.

4012 8888 8888 1881
[8]0[2]2 [16]8[16]8 [16]8[16]8 [2]8[16]1
8022 7878 7878 2871

2  Each individual resulting digit, plus those bypassed, above is then added together.
8022 7878 7878 2871
8+0+2+2+7+8+7+8+7+8+7+8+2+8+7+1
= 90
3 This sum is then subtracted from the lowest multiple of ten that is equal to or greater than the sum, and the single-digit result is the check digit.
90 ÷ 10 = 9
90 Mod 10 = 0

简单的讲就是从号码后面的最后一位乘以1算起,然后上一位的2倍,2倍后大于9这则减去9或者十位和各位相加。最后把这些的和对10进行取模,看是否是0,然后进行决定是否是信用卡号:

网上有找到两段代码,一段是c的,一段时JavaScript的,c的写的比较巧。

1 :

int LuhnMod10(char* cardNumber, int size)
{
static int table[10] = { {0,1,2,3,4,5,6,7,8,9}, {0,2,4,6,8,1,3,5,7,9} };
 
for (int i=size-1, odd=0, sum=0; i&gt;=0; i--)
if (isdigit(cardNumber[i]))
sum += table[(odd=1-odd)][cardNumber[
<div id=":s8">i]-'0'];
sum %= 10;
return (sum ? 10-sum : 0);               /* return the check digit *
}
</div>
js的的则相当繁琐,如果读懂了两段代码,可以看到上面用c写的之妙,之美:
function Mod10(ccNumb) {  // v2.0
var valid = “0123456789″  // Valid digits in a credit card number
var len = ccNumb.length;  // The length of the submitted cc number
var iCCN = parseInt(ccNumb);  // integer of ccNumb
var sCCN = ccNumb.toString();  // string of ccNumb
sCCN = sCCN.replace (/^\s+|\s+$/g,”);  // strip spaces
var iTotal = 0;  // integer total set at zero
var bNum = true;  // by default assume it is a number
var bResult = false;  // by default assume it is NOT a valid cc
var temp;  // temp variable for parsing string
var calc;  // used for calculation of each digit

// Determine if the ccNumb is in fact all numbers
for (var j=0; j<len; j++) {
temp = “” + sCCN.substring(j, j+1);
if (valid.indexOf(temp) == “-1″){bNum = false;}
}

// if it is NOT a number, you can either alert to the fact, or just pass a failure
if(!bNum){
/*alert(”Not a Number”);*/bResult = false;
}

// Determine if it is the proper length
if((len == 0)&&(bResult)){  // nothing, field is blank AND passed above # check
bResult = false;
} else{  // ccNumb is a number and the proper length – let’s see if it is a valid card number
if(len >= 15){  // 15 or 16 for Amex or V/MC
for(var i=len;i>0;i–){  // LOOP throught the digits of the card
calc = parseInt(iCCN) % 10;  // right most digit
calc = parseInt(calc);  // assure it is an integer
iTotal += calc;  // running total of the card number as we loop – Do Nothing to first digit
i–;  // decrement the count – move to the next digit in the card
iCCN = iCCN / 10;

// subtracts right most digit from ccNumb
calc = parseInt(iCCN) % 10 ;    // NEXT right most digit
calc = calc *2;                                 // multiply the digit by two
// Instead of some screwy method of converting 16 to a string and then parsing 1 and 6 and then adding them to make 7,
// I use a simple switch statement to change the value of calc2 to 7 if 16 is the multiple.
switch(calc){
case 10: calc = 1; break;       //5*2=10 & 1+0 = 1
case 12: calc = 3; break;       //6*2=12 & 1+2 = 3
case 14: calc = 5; break;       //7*2=14 & 1+4 = 5
case 16: calc = 7; break;       //8*2=16 & 1+6 = 7
case 18: calc = 9; break;       //9*2=18 & 1+8 = 9
default: calc = calc;           //4*2= 8 &   8 = 8  -same for all lower numbers
}
iCCN = iCCN / 10;  // subtracts right most digit from ccNum
iTotal += calc;  // running total of the card number as we loop
}  // END OF LOOP
if ((iTotal%10)==0){  // check to see if the sum Mod 10 is zero
bResult = true;  // This IS (or could be) a valid credit card number.
} else {
bResult = false;  // This could NOT be a valid credit card number
}
}
}
// change alert to on-page display or other indication as needed.
if(bResult) {
alert(”This IS a valid Credit Card Number!”);
}
if(!bResult){
alert(”This is NOT a valid Credit Card Number!”);
}
return bResult; // Return the results
}
// –>
</script>

摘自:http://www.techrss.cn/html/2008/10-20/152593.htm

没有评论 »