【编程珠玑】第二章 二分查找的巧妙应用
2012-07-13 14:34
381 查看
题目:编写一个"banner"函数,该函数的输入为大写字母,输出为一个字符数组,该数组以图像化的方式表示该字母。
以下内容转自http://www.haogongju.net/art/994660
《编程珠玑》上提到当要输入的数据很多,且没有规律时,可以考虑编写一个格式信函发生器(form
letter generator)用于解析格式信函模板(form
letter schema)。将数据从控制层分离的好处在于:避免每次针对不同的数据编写不同的代码;当需要改变一些公用文本的输出方式时,直接编辑模板即可,并不需要对数据进行修改。
题目要求:输入一个字母,输出一个字符数组,该数组要以图像的方式将该字母的大写打印出来。
对于26个字母,每个字母的外形并没有必然规律可循,最直接的方法是编写26个函数,针对特定的字母编写特定的打印程序,这是个体力活,代码数量将非常巨大。联想上面的格式信函编程,可以考虑为字母的外形设计一个定制模板,自己规定一套模板编写的格式,然后写一个解析程序,每次打印字母时,只需解析字母对应的模板即可,这样主要的工作量就花在每个字母模板的编写上,当然模板的编写是相当简单的,将字母图形转化为相应的模板格式即可。例如:
一个字母可以利用length = 12, width = 9的矩阵来表示
[align=center] [/align]
[align=center] [/align]
任何字母都可以在这张表示出来,每个点就像一个像素点。下面就对字母I和L进行模板编码,编码要求
(1)用尽可能简单的方式表示上面的图像;(2)方便程序解析;(3)必须适用于所有的情况
根据书上给出的编码结构,上图可表示为:
编码规则: 第一列表示要打印的行数,,后面的数字代表每行要打印的字符个数,个数后面紧跟要打印的字符,并用空格隔开。这里字母b表示空格。根据上述规则,字母L编码如下:
那么下一步就是按照规则编写能解析该编码模板的程序,为方便执行下面解码程序直接写在主函数里面。
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string line;
const string tag("
");
int numRow = 0;
int rowIdx = 0;
char cMatrix[12][9];
char cArry[9];
while(getline(cin, line)){
int numCln = 0;
int clnIdx = 0;
string::size_type begIdx, endIdx;
begIdx = line.find_first_of(tag);
numRow = atoi((line.substr(0,begIdx)).c_str());
begIdx = line.find_first_not_of(tag, begIdx);
while(begIdx < line.length() - 1)
{
endIdx = line.find_first_of(tag, begIdx);
if(endIdx == string::npos)
endIdx = line.length();
numCln = atoi((line.substr(begIdx,endIdx - begIdx)).c_str());
begIdx = line.find_first_not_of(tag, endIdx);
char val = line[begIdx];
for(int j
= clnIdx; j < clnIdx + numCln; j++){
cArry[j] = val;
}
clnIdx += numCln;
if(begIdx < line.length() - 1)
begIdx = line.find_first_not_of(tag, ++begIdx);
}
for(int i
= rowIdx; i < rowIdx + numRow; i++){
for(int j
= 0; j < 9; j++)
cMatrix[i][j] = cArry[j];
}
rowIdx += numRow;
}
for(int i
= 0; i < 12; i++){
for(int j
= 0; j < 9; j++){
if(cMatrix[i][j] == 'b')
cout << " " ;
else
cout << cMatrix[i][j];
}
cout << endl;
}
}
程序读入上面的编码模板,就可以将打印出来。由于是while方式读入,要用F6加回车来结束输入。
以下内容转自http://www.haogongju.net/art/994660
《编程珠玑》上提到当要输入的数据很多,且没有规律时,可以考虑编写一个格式信函发生器(form
letter generator)用于解析格式信函模板(form
letter schema)。将数据从控制层分离的好处在于:避免每次针对不同的数据编写不同的代码;当需要改变一些公用文本的输出方式时,直接编辑模板即可,并不需要对数据进行修改。
题目要求:输入一个字母,输出一个字符数组,该数组要以图像的方式将该字母的大写打印出来。
对于26个字母,每个字母的外形并没有必然规律可循,最直接的方法是编写26个函数,针对特定的字母编写特定的打印程序,这是个体力活,代码数量将非常巨大。联想上面的格式信函编程,可以考虑为字母的外形设计一个定制模板,自己规定一套模板编写的格式,然后写一个解析程序,每次打印字母时,只需解析字母对应的模板即可,这样主要的工作量就花在每个字母模板的编写上,当然模板的编写是相当简单的,将字母图形转化为相应的模板格式即可。例如:
一个字母可以利用length = 12, width = 9的矩阵来表示
x | x | x | x | x | x | x | x | x |
x | x | x | x | x | x | x | x | x |
x | x | x | x | x | x | x | x | x |
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | x | x | x | x | x | x |
x | x | x | x | x | x | x | x | x |
x | x | x | x | x | x | x | x | x |
[align=center] [/align]
任何字母都可以在这张表示出来,每个点就像一个像素点。下面就对字母I和L进行模板编码,编码要求
(1)用尽可能简单的方式表示上面的图像;(2)方便程序解析;(3)必须适用于所有的情况
根据书上给出的编码结构,上图可表示为:
3 9 x |
6 3 b 3 x 3 b |
3 9 x |
9 3 x 6 b |
3 9 x |
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | ||||||
x | x | x | x | x | x | x | x | x |
x | x | x | x | x | x | x | x | x |
x | x | x | x | x | x | x | x | x |
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string line;
const string tag("
");
int numRow = 0;
int rowIdx = 0;
char cMatrix[12][9];
char cArry[9];
while(getline(cin, line)){
int numCln = 0;
int clnIdx = 0;
string::size_type begIdx, endIdx;
begIdx = line.find_first_of(tag);
numRow = atoi((line.substr(0,begIdx)).c_str());
begIdx = line.find_first_not_of(tag, begIdx);
while(begIdx < line.length() - 1)
{
endIdx = line.find_first_of(tag, begIdx);
if(endIdx == string::npos)
endIdx = line.length();
numCln = atoi((line.substr(begIdx,endIdx - begIdx)).c_str());
begIdx = line.find_first_not_of(tag, endIdx);
char val = line[begIdx];
for(int j
= clnIdx; j < clnIdx + numCln; j++){
cArry[j] = val;
}
clnIdx += numCln;
if(begIdx < line.length() - 1)
begIdx = line.find_first_not_of(tag, ++begIdx);
}
for(int i
= rowIdx; i < rowIdx + numRow; i++){
for(int j
= 0; j < 9; j++)
cMatrix[i][j] = cArry[j];
}
rowIdx += numRow;
}
for(int i
= 0; i < 12; i++){
for(int j
= 0; j < 9; j++){
if(cMatrix[i][j] == 'b')
cout << " " ;
else
cout << cMatrix[i][j];
}
cout << endl;
}
}
程序读入上面的编码模板,就可以将打印出来。由于是while方式读入,要用F6加回车来结束输入。
相关文章推荐
- 【编程珠玑】第二章 二分查找的巧妙应用
- 编程珠玑中关于二分查找的使用
- 二分查找另类--【编程珠玑第四章】
- 二分查找递归实现--【编程珠玑】
- [编程珠玑]-第二章:二分及标识
- 二分查找非递归实现--【编程珠玑】
- 由July师兄二分查找代码及编程珠玑有感:循环不变性(断言)证明程序的正确性及发现bug
- 编程珠玑之第二章习题1
- 程序员编程艺术:第二章、字符串是否包含及匹配/查找/转换/拷贝问题
- 编程珠玑 第二章 习题5
- 二分查找突破上下限,树状数组的三种应用。
- 程序员编程艺术第二十五章:Jon Bentley:90%无法正确实现二分查找
- Spark中ip映射数据应用库,二分查找省份,将结果写入mysql
- practical of programming 第二章 排序和二分查找
- 关于二分查找的应用拓展
- 二分查找的变形应用
- 【编程珠玑】第十五章--字符串:用后缀数组查找最长不重叠的重复子串
- 二分查找应用-旋转数组
- 程序员编程艺术第二十五章:Jon Bentley:90%无法正确实现二分查找