MIT-Scheme 入门

1. MIT-Scheme 是Lisp语言的一类分支,是SICP(计算机程序的构造和解释)的教学语言。

2. 下载地址参考GNU网站,此外注意查阅文档(HTML版),和一个简单的介绍(豆丁)。

3. 晚上折腾了一会,发现Emacs的分支Edwin用的不是很顺手,明天有空把说明书看看。

附上一个牛顿法求平方根Scheme代码:

(define (square x) (* x x))

(define (abs x)
	(if (< x 0) (- x) x))

(define (average x y)
	(/ (+ x y) 2))

(define (improve guess x)
	(average guess (/ x guess)))

(define (good-enought? guess x)
	(< (abs (- (square guess) x)) 0.001))

(define (sqrt-iter guess x)
	(if (good-enough? guess x)
	guess
	(sqrt-iter (improve guess x) x)))

(define (sqrt x))
	(sqrt-iter 1.0 x)

后记: 第二天继续尝试Edwin, RTFM。

这里可以参考RPI的Scheme教学文档

比起生硬的说明文档,这个好看的多,尤其是老师说“I believe some students in previous years have gotten it running on a Mac, but I don't know any details.” 的时候我笑的不行了。

综上,文档里建议结合GNU-Emacs使用Scheme,不过我有些想把他转接到vim上去。

发表在 Lisp, 读书 | 标签为 , , , , | 留下评论

2011年12月30日

孤灯曲径残影石,酒翁踏水一蓑衣;

我自将心葬明月,楼兰夜色几时还。

发表在 无法分类 | 标签为 | 留下评论

C++ 原地归并

起因是之前面百度,被面试官鄙视在了原地归并,后来翻了翻代码,其实不难,可能是当时没有突破思维把。

刚刚hzh又提起原地归并,发现自己都忘的差不多了,坑爹,还是写下来。


void merge(int * v, int n, int pos) // 数组v, 有n个元素,从pos位置开始分割,前后两段分别有序
{
    int fir = 0, sec = pos;
    while (fir < sec && sec < size) {
    while (fir < sec && v[fir] <= v[sec]) fir ++;
    int max_move = 0;

    while (sec < size && v[fir] > v[sec]) sec++, max_move++; // 核心,用来统计这一段元素到底该插到什么地方。
    exchange(&v[fir], sec-fir, sec-fir -max_move) ; // 特殊的放置函数,后面会举个栗子的
    fir += max_move;
    }

}

例如:       1 2 6 7 | 4 5 9 8  n=8 pos = 4
首次循环停止时, fir =  2 , 因为 v[2] = 6 > v[4] = 4,  
随后 sec 和 max_move 加了两次,因为 v[2] = 6 < v[6] = 9

传入 exchange的参数为  (&v[2], 4, 2) 

表示从第三个位置开始(也就是6在的位置),之后的4个元素(包括它),整体循环右移2次,

然后就变成了 1 2 4 5 6 7 9 8,  fir + max_move, 移到它的新位置,后面的特例就不再分析了。

最后这个方法的复杂性就落在了 exchange上,不过如果用链表来实现就很低了,想来当时的面试官是想这样考我的。。

发表在 C, 编程 | 标签为 , | 4条评论

Python开发中的一个小细节


for id in id_list:
    if ooxx(id):
        id_list.remove(id)
        continue

这样的写法是不合适的,因为当remove掉id时,目前的指针会指向下一个元素,而continue会跳过他
所以这样的现象是,一旦remove,就会跳过下一个元素

可以考虑这样实现

for id in id_list:
    if ooxx(id):
        remove_list.append(id)
        continue

...

for id in remove_list:
    id_list.remove(id)
发表在 Python, 编程 | 标签为 | 留下评论

2011年12月8日

34c800864b5fbdf1f5bdf07880580cbc
b651e465c558f19486d04132cc5a9e99
8d52c9ba70a64c76bef1ebb2873df29d
67f8ac0ae1cd830626a3d1cfe119ba4c
e6480f95effef1cf42e0907d24efd2f9
cb6d1732acec16d0a446b3ec3b948238
48c97b6ace6e545426bab8995aa21937
0a
由SMS4算法加密。

发表在 许愿墙 | 留下评论

[整理合辑]那些我所知道的中翻

偶然的原因,开始整理在一位作者在网上发布的音乐。

中翻,简单的说,指的是把已有的曲谱重新填词演唱,

他们大部分不是流行歌曲,也不是经典老歌,如果要定出个概括,那他们都是很中国风的歌曲。

希望你会喜欢。

下载地址:http://115.com/file/e6a6541t#
———————–
选一首上传了,试听:[audio:http://www.seenthewind.com/./wp-content/uploads/2011/12/lvc.mp3|titles=绿茶]
PS: 各种风格都有,所以不要说是怨妇歌了 -_-!

————————

PPS: 目前作者已经停止发布他的整理了,我这个转手卖萌也不会继续了,目前正好一共十辑。

解压密码是我的名字三个首字母,同样可以发送邮件到miuc.cpp[at]gmail.com来获取密码

发表在 音乐 | 标签为 , | 留下评论

在silverlight与防盗链的网站中提取音乐文件

[audio:http://www.seenthewind.com/./wp-content/uploads/2011/11/secret_base.mp3|titles=secret_base]

url: http://bz.5sing.com/941638.html
step:
1. 查看网页源码,发现mp3链接,无法下载,估计已经配置的防盗链。
2. 使用chrome打开,输入 about:cache,查找到mp3-url的缓存,另存为。
3. 打开播放器,不能播放,用vim打开,发现是http报文明文 (╯#-皿-)╯~~╧═╧
4. 查找到ID3标签(MP3文件的标志头),截取出真正的mp3,还不够,目前是十六进制字符串的表示,我们要把他们换算成二进制存起来。
5. 写了一个python,做字符串处理,提取出纯净的hex-string。

import os
fp = open('123.txt', 'r')
wp = open('secret_base.txt', 'w')
for line in fp:
    l = line.split()
    #print l
    for l_hex in l[1:17]:
        wp.write(l_hex)
        #print l_hex,
    #print ''
    #os.system('pause')

6. 然后把文件中的hex-string流转换成纯二进制保存,用python处理二进制不太舒服,换成C++。

#include 
#include 
#define READ_MAX 1024

unsigned char chartohex(unsigned char * data)
{
    unsigned char ret = 0x00;

    if (*data < 'a') 
        ret = ret+(*data - '0');
    else
        ret = ret+10+(*data - 'a');
    ret = ret << 4;

    data++;
    if (*data < 'a') 
        ret = ret+(*data - '0');
    else
        ret = ret+10+(*data - 'a');
    return ret;
}

int main()
{
    FILE * fpr, * fpw;
    fpr = fopen("secret_base.txt", "r");
    fpw = fopen("secret_base.mp3", "wb");

    unsigned char readbuffer[READ_MAX];
    unsigned char writebuffer[READ_MAX/2];

    int len, i;
    while ( len=fread(readbuffer, sizeof(unsigned char), READ_MAX, fpr) )
    {
        for (i=0; i

7. ok, 提取出来的音乐在文章开头。

发表在 C, C++, Python, 编程 | 标签为 , , , | 留下评论

2011年11月23日

景蓝花,湿衣雨;
岁安巷,守城铁。
口莫言,心自辩;
不想念,若待缘。

发表在 唠叨, 许愿墙 | 留下评论

Windows下的非阻塞socket编程初探

下午检查灰度部署的结果,突然系统有点延迟,原来是因为网络策略的变更,导致防火墙把socket的一个主连接挡住了。
虽然会自动切换到备连接,但是系统每隔5分钟会再去检查主连接是否恢复。

这个时候,由于防火墙挡掉的socket链接就会阻塞很长一段时间才会返回错误,需要修改。

因为在Linux下面的情况比较简单,提供一个下面的语句做参考。

setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); // 通过SO_SNDTIMEO来控制connect的超时时间

据表哥介绍,这个设置原本是用来设置发送超时的,不过Linux下面貌似会很”巧合”的把连接超时也搞定了。
Windows下面当然没这么简单,下面整理网上的一些资料,对windows下面的socket非阻塞链接做探讨。

写在前面:下面的程序在windows下编译需要链接ws2_32.lib/DLL

继续阅读

发表在 C++, Windows, 系统, 编程 | 标签为 , , | 留下评论

Unix 下信号相关知识(Signal, kill)

1. 文章参考APUE第10章

kill在*nux族中主要代表两类,一是在函数内部调用的kill函数,用于给其他进程发送signal。
函数原型 int kill(pid_t pid, int sig);)

二是在Shell执行的kill命令,用于给后台进程发送信号。(参考这里

至于9是什么,在*unix中,signal是一组整数。
参考这个头文件

例如:

#define SIGKILL		 9
#define SIGUSR1		10
#define SIGUSR2		12
#define SIGSTOP		19

上面代码展示的几个值是比较关键的。我们继续来谈。

聊完了kill, 就有必要知道程序是怎么处理信号的,因为是特别篇所以我懒得讲到中断什么的。。这里就讲一下怎么用signal覆盖或者无视中断。

程序调用signal()函数来自定义对信号的处理,他的原型是: void (*signal(int signo, void (*func)(int)))(int);

这个原型比较复杂,推荐把他看懂。 (看不懂参考这里

简单介绍一下。 首先我们看到 signal, 他的左边是(),右边是*, 说明他是一个返回*号的函数,参数是()里面的东西。

然后跳出 signal所在的括号看,void ()(int) 眼熟么,就像void (*p) (int) ,这是一个指向函数的指针,函数的参数是int。如此以来,signal返回的是一个指向函数的指针

说明signal返回的是一个函数指针,然后在看signal(这里),是 int signo, void(*func)(int) 眼熟么,第一个参数是int, 第二个参数是函数指针。

当然这是自我折腾的函数声明,其实人民也会这样定义它。

typedef void Signalfunc(int);

Signalfunc * signal(int, Signalfunc *);

好了,这回还看不懂。。。就去多读书孩子。。

说了那么多,signal可以做几件事情,我们关心的有:

1. 屏蔽对一些信号的响应,传入 Signalfunc = SIG_IGN

一般来说,SIG_IGN 的定义是: #define SIG_IGN (void (*)()) 1,我暂时没有找到他在头文件里的定义,有兴趣可以找找。

2. 修改对一些信号的响应,自己定义一个Signalfunc函数,传到signal接口里就行了。

要注意的事情是,参数 SIGKILL 和 SIGSTOP 不能覆盖或者屏蔽。

最后贴一段代码,测试signal函数

#include 
#include 

static void sig_usr(int);

int main()
{
    if (signal(SIGUSR1, sig_usr) == SIG_ERR)
        printf("can't catch SIGUSR1\n");
    if (signal(SIGUSR2, sig_usr) == SIG_ERR)
        printf("can't catch SIGUSR2\n");

    for (;;)
        sleep(1);
}

static void sig_usr(int signo)
{
    if (signo == SIGUSR1)
        printf("recevied SIGUSR1\n");
    else 
        if (signo = SIGUSR2)
            printf("recevied SIGUSR2\n");
        else
            printf("recevied signal %d\n", signo);
}

下班了,准备出趟门,对了SIGUSR1和SIGUSR2是系统默认给用户自定义的。

测试这个函数的方法是:
mattchen@ooxx:~/code/signal$ ./a.out &
[1] 15781
mattchen@ooxx:~/code/signal$ kill -USR1 15781
recevied SIGUSR1
mattchen@ooxx:~/code/signal$ kill -USR2 15781
recevied SIGUSR2
mattchen@ooxx:~/code/signal$ kill -9 15781

发表在 C, C++, Linux, 系统, 编程 | 标签为 , , | 留下评论