您的位置:首页 > 编程语言

编程珠玑(第三章)中的有趣的一道练习题(习题8):seven-segment devices

2012-11-07 09:28 225 查看
编程珠玑第三章有真么一道练习题:seven-segmnt devices provide an inexpensive display ofthe ten decimal digits;



The seven segments are usually numbered as



Write a programthat displays a 16-bit positive integer in five seven-segment digits.The outputis an array of five bytes;bit i of byte j is one if and only if the ith segmentof digit j should be on.
题目的大概意思是:seven-segment devices其实就是我们每人都接触过的计算器。所以的数字都是由数字8的某些部分组成的。
第二章图为8的各个边编了序号。每一个数字对一个唯一的边集,在边集中的边显示,不在其中的不显示。例如:1对应的边集就是{3,5}.现在我们来用程序实现这种设备。
现在我们就要用程序来实现这种设备了。程序的目标就:当给定了一个数字,输出其seven-segmnt表示法。
1.首先我们要构造10个数字对应的边集:
数字
边集
0
2,3,4,5,6,0
1
3,5
2
2,4,1,5,0
3
2,4,1,6,0
4
3,1,4,6
5
2,3,1,6,0
6
2,3,1,5,6,0
7
2,4,6
8
1,2,3,4,5,6,0
9
2,3,4,1,6,0
好了,我如果拿到了每个数字的边集,那么显示数字全然不费功夫。给个7我就知道要显示的那个8字的第2,4,6条编。

计算机实现

接下来的目的就是怎么用计算机来实现边集。我这里采用了一个7bit的bitmap来表示每个边集。第bitmap中的0th bit代表0th边,1th bit 代表 1th……。
数字
边集
Bitmap
0 1 2 3 4 5 6 (编号)
十六进制值
0
2,3,4,5,6,0
1 0 1 1 1 1 1
0x5f
1
3,5
0 0 0 1 0 1 0
0xa
2
2,4,1,5,0
1 1 1 0 1 1 0
0x76
3
2,4,1,6,0
1 1 1 0 1 0 1
0x75
4
3,1,4,6
0 1 0 1 1 0 1
0x2d
5
2,3,1,6,0
1 1 1 1 0 0 1
0x79
6
2,3,1,5,6,0
1 1 1 1 0 1 1
0x7a
7
2,4,6
0 0 1 0 1 0 1
0x15
8
1,2,3,4,5,6,0
1 1 1 1 1 1 1
0x7f
9
2,3,4,1,6,0
0 1 1 1 1 0 1
0x3d
这样用一个数组就可以表示所有数字的边集。

char num_edges[10]={0x5f,0xa,0x76,0x75,0x2d,0x79,0x7a,0x15,0x7f,0x3d}

2.知道了边集的bitmap,我们怎么知道3th是不是要显示呢?

由于采用了bitmap方式,那个边的编号要和bitmap中的bit位进行匹配。所以我们还需要一个数组来表示边的编码:

边的编号
Bitmap中边的编号
十六进制值
0
1000000
0x40
1
0100000
0x20
2
0010000
0x10
3
0001000
0x8
4
0000100
0x4
5
0000010
0x2
6
0000001
0x1
char edge_pos[7]={0x40,0x20,0x10,0x8,0x4,0x2,0x1}

知道了边集的bitmap和边的bitmap编号,拿两者做&运算,结果为true时,则我们就知道要显示那条边。例如:数字4:num_edges[4]& edge_pos[1]运算结果为0100000,结果为true,显示第1th边。而num_edges[4]& edge_pos[0]结果是0,0th是不显示的。

3.接下还有很让我头痛的问题。就是怎么那字符来拼凑那个8字。我的大概想法是这样:

_

| |

_

| |

_

很勉强我也知道。但这种方法简单。

为了使用字符输出的方式,那么各个边的输出顺序是一定的——2,3,4,1,5,6,0。我们要调整edge_pos的顺。edge_pos[1]将不再是1th,而是3th。新的edge_pos如下。

edge_pos[7]={0x10,0x8,0x4,0x20,0x2,0x1,0x40}。

代码实现

#include<stdio.h>

void show(char);

int main()
{
//将要现示1,2,3,4,5,这五个數字
char input[5] = {1,2,3,4,5};
char num_egdes[10] = {0x5f,0xa,0x76,0x75,0x2d,0x79,0x7a,0x15,0x7f,0x3d};
int i;
for(i=0; i<=4; ++i){
if(input[i]<0 || input[i]>9){
printf("input is wrong!");
break;
}
show(num_egdes[input[i]]);
printf("--input%d\n",input[i]);
}
return 0;
}

void show(char number)
{
char edge_pos[7] = {0x10,0x8,0x4,0x20,0x2,0x1,0x40};
char letter[7] = {'_','|','|','_','|','|','_'};
char position[7] = {'\n',' ','\n','\n',' ','\n','\n'};
int j;
for(j=0; j<=6; ++j){
if(edge_pos[j]&number){
//printf("%d",segment[j]);
//printf("%d",j);
printf("%c",letter[j]);
}
printf("%c",position[j]);
}
printf("over%d",number);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: