按 ‘ 程序 ’ 标签归档

程序员入伙书——程序在干什么?

程序员是写程序的,程序是干什么的?

我的独门总结:形形色色的程序,大到组成整个操作系统或者办公软件,小到打印一个九九乘法表,它们都有三个共同的功能块:

  • 计算
  • 流程控制
  • 输入输出

计算,不但是数学运算,也包括对语言文字信息的分析,判断异同、比较大小,都属于“计算”的范畴。如果没有计算,如果所有的数据、信息都不需要处理,我们要计算机做什么?当打字机使么?

流程控制,包括条件判断、循环、跳转。通过使用流程控制,我们可以写很短的程序,让计算机重重复复地执行成千上万的步骤,并且花样繁多。计算机虽然不会思考,但它们做明确具体的事情时还是比人速度快、而且重复性好。你让计算机做两个数相除,做一亿次的结果都是一样的,且它也不喊累。可让人来做的话,首先就是慢,也可能做错,做十次会不耐烦,做五百次会精神崩溃。小时候被老师罚抄作业十遍的同学,请自行默默回忆童年时的阴影。

输入:键盘、鼠标指令,从网络上接收服务请求,或者从硬盘读个图片……把外部设备上的电信号吸纳进计算机的过程,都算是输入。输出:在屏幕上显示一张图片、一些文字,往U盘上拷东西,播放音乐或视频……把计算机心里想明白的事情说出来的过程,这些都是输出。如果程序没有输入,那么它每次的运算都是从已知的、固定的条件开始,结果会单调得让人厌烦。学编程的时候,看到一群老年大专生用BASIC语言打印熊猫,以为自己在编程,心里的怜悯油然而生。如果程序没有输出,计算机有电没电的区别就不太大了,当然,冬天屋里冷的时候,多开个电器,确实可以更暖和一些。

可以说,所有的程序做的事情不外乎这三个概念。你打开网络浏览器,IE也好,FireFox也罢,你输入一个网址,按回车键,它就向网络端口上输出一个请求,向那个网址要网页,要来的网页从网络端口输入进来,浏览器反复判断每个传进来的数据流,看它们是图片还是一般文字,如果是图片,还需要做些解码工作计算摆放它们的位置,显示在窗口上。在这个回合里,计算、流程控制、输入输出都是齐全的。除了这三样,确实也没有其它的操作了。

说了这么多,我来演示三个例子吧。

第一个例子,是算从1加到100的总和,传说高斯用很聪明的办法搞定了这道题,我们来看看很笨很死脑筋、却擅长做高速计算的计算机是怎么做的。打开Python的窗口(说啥呢?),输入(虽然可以拷贝粘贴,但我更希望你亲自敲一遍):

total = 0
for i in range(1, 101):
	total = total + i
	# 请在这里多敲一两次回车(Enter)键,以使Python显示>>>提示符
print(total)

打字时请注意,Python对每行的缩进要求很严格,因为它认为这是表达程序结构的一部分,所以一定要按照这个例子里来敲。敲完最后一行“print(total)”,如果你看到了5050,就知道自己做对了。
猛击阅读全文

二十四点

这是一个算二十四点的程序。从命令行输入四个数字,结果以后缀表达式输出。如:

$ calc24 8 8 3 3
8383/-/

即8/(3-8/3)。

#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<ctype.h>
#include	<math.h>

void	calc24(int, int, int, int);
double	calc(char *);

void	main(int argc, char *argv[])
{
	int	n[4];
	int	i, j, k, m;

	if (argc != 5) {
		printf("Usage: %s a b c d\n", argv[0]);
		return;
	}
	for (i = 0; i < 4; i++)
		if ((n[i] = atoi(argv[i+1])) < 1 || n[i] > 9) {
			printf("%s is not a valid input\n", argv[i+1]);
			return;
		}
	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++) {
			if (j == i)
				continue;
			for (k = 0; k < 4; k++) {
				if (k == i || k == j)
					continue;
				for (m = 0; m < 4; m++) {
					if (m == i || m == j || m == k)
						continue;
					calc24(n[i], n[j], n[k], n[m]);
				}
			}
		}
}

void	calc24(int a, int b, int c, int d)
{
	char	expr[10];
	char	*oper = "+-*/";
	int	i, j, k, m;

	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++) {
			for (k = 0; k < 4; k++) {
				sprintf(expr, "%d%d%d%d%c%c%c", a, b, c, d, oper[i], oper[j], oper[k]);
				if (fabs(calc(expr) - 24) < 1.0E-3)
					puts(expr);
				sprintf(expr, "%d%d%d%c%d%c%c", a, b, c, oper[i], d, oper[j], oper[k]);
				if (fabs(calc(expr) - 24) < 1.0E-3)
					puts(expr);
				sprintf(expr, "%d%d%d%c%c%d%c", a, b, c, oper[i], oper[j], d, oper[k]);
				if (fabs(calc(expr) - 24) < 1.0E-3)
					puts(expr);
				sprintf(expr, "%d%d%c%d%d%c%c", a, b, oper[i], c, d, oper[j], oper[k]);
				if (fabs(calc(expr) - 24) < 1.0E-3)
					puts(expr);
				sprintf(expr, "%d%d%c%d%c%d%c", a, b, oper[i], c, oper[j], d, oper[k]);
				if (fabs(calc(expr) - 24) < 1.0E-3)
					puts(expr);
			}
		}
}

double	calc(char *expr)
{
	double	a, b, stack[4];
	int	top, i, n;

	n = strlen(expr);
	top = 0;
	for (i = 0; i < n; i++) {
		if (isdigit(expr[i])) {
			stack[top++] = expr[i] - '0';
			continue;
		}
		if (top < 2)
			return	9999;
		b = stack[--top];
		a = stack[--top];
		switch(expr[i]) {
		case '+':
			stack[top] = a + b;
			break;
		case '-':
			stack[top] = a - b;
			break;
		case '*':
			stack[top] = a * b;
			break;
		case '/':
			if (b == 0.0)
				return	9999;
			stack[top] = a / b;
			break;
		}
		top++;
	}
	if (top != 1)
		return	-9999;
	return	stack[0];
}

98%的人一小时也做不出来的题目

据说这是98%的人一小时也做不出来的题目。在网上看见,一时技痒,编了个程序来解,总算落到那2%里面了。哈哈。

请回答下面10个问题:

1、第一个答案是b的问题是哪一个?
(a)2;(b) 3;(c)4;(d)5;(e)6
2、唯一的连续两个具有相同答案的问题是:
(a)2,3;(b)3,4;(c)4,5;(d)5,6;(e)6,7
3、本问题答案和哪一个问题的答案相同?
(a)1;(b)2;(c)4;(d)7;(e)6
4、答案是a的问题的个数是:
(a)0;(b)1;(c)2;(d)3;(e)4
5、本问题答案和哪一个问题的答案相同?
(a)10;(b)9;(c)8;(d)7;(e)6
6、答案是a的问题的个数和答案是什么的问题的个数相同?
(a)b;(b)c;(c)d;(d)e;(e)以上都不是
7、按照字母顺序,本问题的答案和下一个问题的答案相差几个字母?
(a)4;(b)3;(c)2;(d)1;(e)0。(注:a和b相差一个字母)
8、答案是元音字母的问题的个数是:
(a)2;(b)3;(c)4;(d)5;(e)6。(注:a和e是元音字母)
9、答案是辅音字母的问题的个数是:
(a)质数;(b)阶乘数;(c)平方数;(d)立方数;(e)5的倍数
10、本问题的答案是:
(a)a;(b)b;(c)c;(d)d;(e)e

唯一的答案是CDEBEEDCBA,算法如下:

#include	<stdio.h>

int	a[10];

void	select(int n, int answer);

void	main()
{
	int	i;

	for (i = 'a'; i <= 'e'; i++)
		select(0, i);
}

void	select(int n, int answer)
{
	int	i;
	int	same, pos;
	int	asum, bsum, csum, dsum, esum;
	int	diff;

	a[n] = answer;
	if (n < 9) {
		for (i = 'a'; i <= 'e'; i++)
			select(n + 1, i);
		return;
	}
	/* 1 */
	for (i = 0; i < 6; i++)
		if (a[i] == 'b')
			break;
	if (i < 1 || i > 5 || a[0] != 'a' + i - 1)
		return;
	/* 2 */
	same = 0;
	pos = 0;
	for (i = 0; i < 9; i++)
		if (a[i] == a[i+1]) {
			if (same)
				return;
			same = 1;
			pos = i;
		}
	if (pos < 1 || pos > 5 || a[1] != 'a' + pos - 1)
		return;
	/* 3 */
	if (a[2] == 'a' && a[0] != a[2])
		return;
	if (a[2] == 'b' && a[1] != a[2])
		return;
	if (a[2] == 'c' && a[3] != a[2])
		return;
	if (a[2] == 'd' && a[6] != a[2])
		return;
	if (a[2] == 'e' && a[5] != a[2])
		return;
	/* 4 */
	asum = 0;
	bsum = 0;
	csum = 0;
	dsum = 0;
	esum = 0;
	for (i = 0; i < 10; i++) {
		switch (a[i]) {
		case 'a':
			asum++;
			break;
		case 'b':
			bsum++;
			break;
		case 'c':
			csum++;
			break;
		case 'd':
			dsum++;
			break;
		case 'e':
			esum++;
			break;
		}
	}
	if (asum != a[3] - 'a')
		return;
	/* 5 */
	if (a[9+'a'-a[4]] != a[4])
		return;
	/* 6 */
	if (asum == bsum && a[5] != 'a')
		return;
	if (asum == csum && a[5] != 'b')
		return;
	if (asum == dsum && a[5] != 'c')
		return;
	if (asum == esum && a[5] != 'd')
		return;
	if ((asum == bsum || asum == csum || asum == dsum) && a[5] == 'e')
		return;
	if ((bsum == csum || csum == dsum || dsum == esum ||
	    esum == bsum || esum == csum || bsum == dsum) && a[5] != 'e')
		return;
	/* 7 */
	diff = a[6] - a[7] > 0 ? a[6] - a[7] : a[7] - a[6];
	if (a[6] != 4 - diff + 'a')
		return;
	/* 8 */
	if (asum + esum < 2 || asum + esum > 6 || a[7] != 'a' + asum + esum - 2)
		return;
	/* 9 */
	switch (bsum + csum + dsum) {
	case 3:
	case 7:
		if (a[8] != 'a')
			return;
		break;
	case 4:
	case 9:
		if (a[8] != 'c')
			return;
		break;
	case 6:
		if (a[8] != 'b')
			return;
		break;
	case 8:
		if (a[8] != 'd')
			return;
		break;
	case 10:
		if (a[8] != 'e')
			return;
		break;
	default:
		return;
	}
	/* 10 */
	/* print solution */
	for (i = 0; i < 10; i++)
		putchar(a[i]);
	putchar('\n');
}