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

编程珠玑第三章有真么一道练习题: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);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值