编程珠玑之第二章习题6
来源:互联网 发布:域名备案批量查询 编辑:程序博客网 时间:2024/05/16 17:19
问题描述:
20世纪70年代末期,贝尔实验室开发出了“用户操作的电话号码簿辅助程序”,该程序允许雇员使用标准按键电话在公司电话号码簿中查找电话号码。要查找该系统设计者的名字Mike Lesk,可以按“LESK*M*”(也就是“5375*6*”),随后,系统会输出他的电话号码。这样的服务现在随处可见。该系统中出现的一个问题是,不同的名字有可能具有相同的按键编码。在Lesk的系统中发生这种情况时,系统会询问用户更多的信息。给定一个大的名字文件(例如标识的大城市电话号码簿),如何定位这些“错误匹配”呢?(当Lesk在这种规模的电话号码簿上做实验时,他发现错误匹配发生的概率仅仅是0.2%。)如何实现一个以名字的按键编码为参数,并返回所有可能匹配名字的函数?
问题解析:
1、标准的按键电话中,按键与字母是一对多的映射关系(如:2——>A B C) 那么以按键作为标识,对电话簿中的人名进行标识,那么每个人名就有了一个唯一的标识。
2、有了标识,那么就可以创建对应的结构了,诸如:(标识, 用户文件(用户名,电话,地址等)); 这里标识——用户文件是一对多的关系。
3、所有的用户文件加入到该结构中后,依标识排序(用户名排序),排好序就可以在用户输入时,采取二分搜索来查找对应的用户文件了。
解答方案:
不完整解决方案:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <cstdio>
#include <cstdlib> // qsort
#include <cctype> // toupper\tolower
#include <cstring> // strlen
#include <cassert> // assert
#define MAXUSERNUM 1000 // 用户数
#define WORDMAX 100 // 姓名最大长度
#define MAXNUMBER 10 // 标识相同的用户数
#define PHONELEN 11 // 电话长度
#define error( str ) fatal_error( str )
#define fatal_error( str ) fprintf( stderr, "%s\n", str ), exit( 1 )
/************************************************************************/
// 函数名称:chartonum
// 函数目的:获取对应字符的标识
// 函数参数:字符ch
// 函数返回:字符ch对应的标识
// 使用条件:
/************************************************************************/
char chartonum(char ch)
{
if (!isalpha(ch)) return '0';
switch(toupper(ch)){
case 'A': case 'B': case 'C': return '2';
case 'D': case 'E': case 'F': return '3';
case 'G': case 'H': case 'I': return '4';
case 'J': case 'K': case 'L': return '5';
case 'M': case 'N': case 'O': return '6';
case 'P': case 'Q': case 'R': case 'S': return '7';
case 'T': case 'U': case 'V': return '8';
case 'W': case 'X': case 'Y': case 'Z': return '9';
default: break;
}
return '0';
}
/************************************************************************/
// 函数名称:getsign
// 函数目的:获得输入姓名对应的标识
// 函数参数:sign:姓名标识 fullname:姓名
// 函数返回:姓名标识
// 使用条件:fullname格式为由两个单词组成,姓在前,名在后,中间用空格隔开
// 比如:Hu Johnny 、Green Jim、Lesk Mike
/************************************************************************/
char* getsign(char* sign, char* fullname)
{
while (isspace(*fullname)) { fullname++; } // 先去除前面的空格
bool bspace = false;
while (*fullname != '\0'){
if (bspace == true) {
if (isspace(*fullname)) { fullname++; continue; }
else {
*sign++ = chartonum(*fullname); *sign++ = '*';
fullname++; break;
}
}
if (isspace(*fullname)) {
bspace = true; *sign++ = '*';
fullname++; continue;
}
if (isalpha(*fullname)){ *sign++ = chartonum(*fullname);}
fullname++;
}
*sign = '\0';
return sign;
}
int main()
{
char fullname[WORDMAX], sign[WORDMAX];
printf("please input a fullname:\n");
while (fgets(fullname, WORDMAX, stdin) != NULL && fullname[0] != '\n'){
char* ch= strchr(fullname, '\n'); // 查找换行符
if (ch) { *ch = '\0'; } // 删除换行符
getsign(sign, fullname);
printf("fullname--->sign: %s--->%s\n", fullname, sign);
printf("please input a fullname:\n");
}
#include <cstdlib> // qsort
#include <cctype> // toupper\tolower
#include <cstring> // strlen
#include <cassert> // assert
#define MAXUSERNUM 1000 // 用户数
#define WORDMAX 100 // 姓名最大长度
#define MAXNUMBER 10 // 标识相同的用户数
#define PHONELEN 11 // 电话长度
#define error( str ) fatal_error( str )
#define fatal_error( str ) fprintf( stderr, "%s\n", str ), exit( 1 )
/************************************************************************/
// 函数名称:chartonum
// 函数目的:获取对应字符的标识
// 函数参数:字符ch
// 函数返回:字符ch对应的标识
// 使用条件:
/************************************************************************/
char chartonum(char ch)
{
if (!isalpha(ch)) return '0';
switch(toupper(ch)){
case 'A': case 'B': case 'C': return '2';
case 'D': case 'E': case 'F': return '3';
case 'G': case 'H': case 'I': return '4';
case 'J': case 'K': case 'L': return '5';
case 'M': case 'N': case 'O': return '6';
case 'P': case 'Q': case 'R': case 'S': return '7';
case 'T': case 'U': case 'V': return '8';
case 'W': case 'X': case 'Y': case 'Z': return '9';
default: break;
}
return '0';
}
/************************************************************************/
// 函数名称:getsign
// 函数目的:获得输入姓名对应的标识
// 函数参数:sign:姓名标识 fullname:姓名
// 函数返回:姓名标识
// 使用条件:fullname格式为由两个单词组成,姓在前,名在后,中间用空格隔开
// 比如:Hu Johnny 、Green Jim、Lesk Mike
/************************************************************************/
char* getsign(char* sign, char* fullname)
{
while (isspace(*fullname)) { fullname++; } // 先去除前面的空格
bool bspace = false;
while (*fullname != '\0'){
if (bspace == true) {
if (isspace(*fullname)) { fullname++; continue; }
else {
*sign++ = chartonum(*fullname); *sign++ = '*';
fullname++; break;
}
}
if (isspace(*fullname)) {
bspace = true; *sign++ = '*';
fullname++; continue;
}
if (isalpha(*fullname)){ *sign++ = chartonum(*fullname);}
fullname++;
}
*sign = '\0';
return sign;
}
int main()
{
char fullname[WORDMAX], sign[WORDMAX];
printf("please input a fullname:\n");
while (fgets(fullname, WORDMAX, stdin) != NULL && fullname[0] != '\n'){
char* ch= strchr(fullname, '\n'); // 查找换行符
if (ch) { *ch = '\0'; } // 删除换行符
getsign(sign, fullname);
printf("fullname--->sign: %s--->%s\n", fullname, sign);
printf("please input a fullname:\n");
}
这里我只实现了怎样将姓名与标识进行映射,其他的还来得及实现,所有电话用户信息的存储可以创建一个结构体,之后可以用C++的map来完成该存储、排序等操作,如果使用纯的C语言,可以自己实现List进行存储,以后有时间在说!
心得疑惑:
1、怎样改用散列来实现该程序?数据库系统呢?
1 0
- 编程珠玑之第二章习题6
- 编程珠玑之第二章习题1
- 编程珠玑之第二章习题2
- 编程珠玑之第二章习题3
- 编程珠玑之第二章习题4
- 编程珠玑之第二章习题5
- 编程珠玑之第二章习题7
- 编程珠玑之第二章习题8
- 编程珠玑之第二章习题9
- 编程珠玑之第二章习题10
- 编程珠玑 第二章 习题6~9
- 编程珠玑第二章习题
- 编程珠玑之第三章习题6
- 《编程珠玑》 第二章 算法 习题
- 编程珠玑第二章习题2
- 编程珠玑第二章习题3
- 编程珠玑 第二章 习题2
- 编程珠玑 第二章 习题5
- 试题总结
- SQLite3源码在Windows及WinCE平台下的编译方法
- DAO层与Service业务逻辑层的解耦实现之Factory工厂模式
- OpenCV学习笔记一 OpenCV 2.49 + Eclipse 配置教程
- 函数strcmp的实现
- 编程珠玑之第二章习题6
- WPF的Image控件BitmapImage以及Uri的资源占用问题
- 华为机试—逆序链表输出
- 第一到九章所有的思维导图
- 数据结构课程设计
- scanf gets fgets
- 华为机试—物品放箩筐(高级题160分,含体积价值:贪心算法)
- 堆管理算法中的Buddy System(伙伴系统)算法
- ubuntu sublime支持中文