编程珠玑之第三章习题5
来源:互联网 发布:c语言做游戏 编辑:程序博客网 时间:2024/05/17 06:32
问题描述:
5. 本习题处理英语中的一小部分连字符问题。下面所示的规则描述了以字母“c”结尾的单词的一些合法的连字符现象:
et-ic al-is-tic s-tic p-tic -ly-ic an-tic c-tic at-ic h-nic n-ic m-ic l-lic -clic l-ic h-ic f-ic d-ic -bic a-ic-mac i-ac
规则的应用必须按照上述顺序进行;因此,有连字符“eth-nic”(由规则“h-nic”捕获)和“clin-ic”(前一测试失败,然后满足“n-ic”).如何用函数来表达该规则?要求函数的输入为单词,返回值必须是后缀连字符。
问题解析:
1、对于给定的规则,要求按照顺序去遍历后缀连字符序列去查找后缀字符串,找到就返回,查找结束,不再往下进行。
2、查找规则的匹配,需要从右往左查找,在忽略连字符'-'的情况下如果后缀字符串完全匹配,则找到!
3、这里我将各个后缀字符串之间的空格换成了‘#’, 方便区分!
解决方案:
1、我从文件读取给定的规则,代码如下:
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <iostream>
#include <cstdio>
#include <cstdlib> // exit()
#include <cassert>
#include <cstring> // memset()
#include <cctype> // strlen()
const int WORD_LENGTH = 30;
const int DEFAULT_CAPACITY = 1024;
#define error( str ) fatal_error( str )
#define fatal_error( str ) fprintf( stderr, "%s\n", str ), exit( 1 )
using namespace std;
/************************************************************************/
// 函数名称:create_postfix_lists
// 函数目的:创建后缀字符字符串序列
// 函数参数:fp指向文件的指针
// 函数返回:创建的字符串序列
// 使用条件:
/************************************************************************/
char* create_postfix_lists(FILE * fp)
{
static char postfix_lists[DEFAULT_CAPACITY];
int index = 0;
while ( (postfix_lists[index] = getc(fp)) != EOF ){
if ( isspace(postfix_lists[index]) ) {
postfix_lists[index] = '#'; // 将空字符换成'#'
}
index++;
}
return postfix_lists;
}
/************************************************************************/
// 函数名称:myslice
// 函数目的:从给定的数组中获取后缀字符
// 函数参数:arr:要切割的数组 arraysize:数组长度 index_a\index_b:数组索引
// 函数返回:后缀字符
// 使用条件:
/************************************************************************/
char* myslice(const char* postfix_lists, int postfixlists_size, int index_a, int index_b)
{
assert(index_a >= 0 && (index_b-index_a) >= 0 && index_b < postfixlists_size);
static char postfix_chars[WORD_LENGTH];
memset(postfix_chars, '\0', WORD_LENGTH);
int index = 0;
for (int i = index_a; i < index_b; i++){
postfix_chars[index++] = postfix_lists[i];
}
//cout << postfix_chars << endl;
return postfix_chars;
}
/************************************************************************/
// 函数名称:is_postfix_chars
// 函数目的:判断是否是后缀字符字符串
// 函数参数:word 单词 postfix_chars 一个后缀字符字符串
// 函数返回:如果是,返回true
// 使用条件:
/************************************************************************/
bool is_postfix_chars(const char* word, const char *postfix_chars)
{
int i = strlen(word) -1;
int j = strlen(postfix_chars) -1;
while ( i >= 0 && j >= 0){
if (postfix_chars[j] == '-'){ // '-'连字符的
j--; continue;
}
if ( word[i] == postfix_chars[j] ){ i--; j--; }
else { break; }
}
if (strlen(postfix_chars) > 0 && j == -1) {
return true;
}
return false;
}
/************************************************************************/
// 函数名称:find_postfix
// 函数目的:从后缀字符字符串序列中查找给定单词的后缀字符串
// 函数参数:word 单词 postfix_chars 一个后缀字符字符串
// 函数返回:如果找到返回后缀字符串,如果找不到,返回NULL
// 使用条件:
/************************************************************************/
char* find_postfix(const char* word, const char *postfix_lists)
{
size_t index_a = 0, index_b = 0;
while (index_b < strlen(postfix_lists)){
if (postfix_lists[index_b] == '#' || index_b == strlen(postfix_lists)-1 ) {
char* postfix_chars = myslice(postfix_lists, strlen(postfix_lists), index_a, index_b);
if (is_postfix_chars(word, postfix_chars)){ return postfix_chars; }
index_a = index_b + 1;
}
index_b++;
}
return NULL;
}
int main()
{
FILE* rfile = fopen("postfix_lists.txt", "r");
if (NULL == rfile){ fatal_error("不能打开postfix_lists.txt文件!\n"); }
char* arr_lists = create_postfix_lists(rfile);
fclose(rfile);
cout << "给定的后缀连字符串序列是:" << arr_lists << endl;
cout << "请输入单词: ";
char word[WORD_LENGTH];
while (cin >> word){
char* postfix_chars = find_postfix(word, arr_lists);
cout << "单词" << word << "对应的后缀连字符是:" ;
if (postfix_chars != NULL)
cout << postfix_chars << endl;
else
cout <<"对不起,没找到!" << endl;
memset(word, '\0', sizeof(word));
cout << "请输入单词: ";
}
return 0;
}
#include <cstdio>
#include <cstdlib> // exit()
#include <cassert>
#include <cstring> // memset()
#include <cctype> // strlen()
const int WORD_LENGTH = 30;
const int DEFAULT_CAPACITY = 1024;
#define error( str ) fatal_error( str )
#define fatal_error( str ) fprintf( stderr, "%s\n", str ), exit( 1 )
using namespace std;
/************************************************************************/
// 函数名称:create_postfix_lists
// 函数目的:创建后缀字符字符串序列
// 函数参数:fp指向文件的指针
// 函数返回:创建的字符串序列
// 使用条件:
/************************************************************************/
char* create_postfix_lists(FILE * fp)
{
static char postfix_lists[DEFAULT_CAPACITY];
int index = 0;
while ( (postfix_lists[index] = getc(fp)) != EOF ){
if ( isspace(postfix_lists[index]) ) {
postfix_lists[index] = '#'; // 将空字符换成'#'
}
index++;
}
return postfix_lists;
}
/************************************************************************/
// 函数名称:myslice
// 函数目的:从给定的数组中获取后缀字符
// 函数参数:arr:要切割的数组 arraysize:数组长度 index_a\index_b:数组索引
// 函数返回:后缀字符
// 使用条件:
/************************************************************************/
char* myslice(const char* postfix_lists, int postfixlists_size, int index_a, int index_b)
{
assert(index_a >= 0 && (index_b-index_a) >= 0 && index_b < postfixlists_size);
static char postfix_chars[WORD_LENGTH];
memset(postfix_chars, '\0', WORD_LENGTH);
int index = 0;
for (int i = index_a; i < index_b; i++){
postfix_chars[index++] = postfix_lists[i];
}
//cout << postfix_chars << endl;
return postfix_chars;
}
/************************************************************************/
// 函数名称:is_postfix_chars
// 函数目的:判断是否是后缀字符字符串
// 函数参数:word 单词 postfix_chars 一个后缀字符字符串
// 函数返回:如果是,返回true
// 使用条件:
/************************************************************************/
bool is_postfix_chars(const char* word, const char *postfix_chars)
{
int i = strlen(word) -1;
int j = strlen(postfix_chars) -1;
while ( i >= 0 && j >= 0){
if (postfix_chars[j] == '-'){ // '-'连字符的
j--; continue;
}
if ( word[i] == postfix_chars[j] ){ i--; j--; }
else { break; }
}
if (strlen(postfix_chars) > 0 && j == -1) {
return true;
}
return false;
}
/************************************************************************/
// 函数名称:find_postfix
// 函数目的:从后缀字符字符串序列中查找给定单词的后缀字符串
// 函数参数:word 单词 postfix_chars 一个后缀字符字符串
// 函数返回:如果找到返回后缀字符串,如果找不到,返回NULL
// 使用条件:
/************************************************************************/
char* find_postfix(const char* word, const char *postfix_lists)
{
size_t index_a = 0, index_b = 0;
while (index_b < strlen(postfix_lists)){
if (postfix_lists[index_b] == '#' || index_b == strlen(postfix_lists)-1 ) {
char* postfix_chars = myslice(postfix_lists, strlen(postfix_lists), index_a, index_b);
if (is_postfix_chars(word, postfix_chars)){ return postfix_chars; }
index_a = index_b + 1;
}
index_b++;
}
return NULL;
}
int main()
{
FILE* rfile = fopen("postfix_lists.txt", "r");
if (NULL == rfile){ fatal_error("不能打开postfix_lists.txt文件!\n"); }
char* arr_lists = create_postfix_lists(rfile);
fclose(rfile);
cout << "给定的后缀连字符串序列是:" << arr_lists << endl;
cout << "请输入单词: ";
char word[WORD_LENGTH];
while (cin >> word){
char* postfix_chars = find_postfix(word, arr_lists);
cout << "单词" << word << "对应的后缀连字符是:" ;
if (postfix_chars != NULL)
cout << postfix_chars << endl;
else
cout <<"对不起,没找到!" << endl;
memset(word, '\0', sizeof(word));
cout << "请输入单词: ";
}
return 0;
}
心得疑惑:
1、处理本题给定的问题关键是字符串划分.。
2、抱歉代码写的有点杂乱,有待优化!
0 0
- 编程珠玑之第三章习题5
- 编程珠玑之第三章习题1
- 编程珠玑之第三章习题2
- 编程珠玑之第三章习题3
- 编程珠玑之第三章习题4
- 编程珠玑之第三章习题6
- 编程珠玑之第三章习题7
- 编程珠玑之第三章习题8
- 编程珠玑第三章习题
- 编程珠玑之第二章习题5
- 编程珠玑第三章习题3.7(5-8)
- 编程珠玑第三章课后习题
- 编程珠玑第三章习题答案
- 编程珠玑第三章习题1
- 编程珠玑之第二章习题1
- 编程珠玑之第二章习题2
- 编程珠玑之第二章习题3
- 编程珠玑之第二章习题4
- 驯服腾讯的QQ(在此我谴责一下国内的软件制造商)
- android 日记
- USACO5.3.2 Window Area(window)
- 后缀数组(不相同的子串个数)——SPOJ 705
- Hadoop中Partitioner解析
- 编程珠玑之第三章习题5
- 关于正则表达式的常规用法
- Unity3D_IOS研究院之构建游戏框架与导出IOS项目(一)
- BASIC-20 数的读法
- Machine Learning - III. Linear Algebra Review线性代数 (Week 1, Optional)
- C Socket Programming server client
- 统揽《运筹学基础》
- MRF,马尔科夫随机场
- spring 依赖注入注解配置原理解析