紫书第五章习题 5-1 代码对齐 (Alignment of Code, ACM/ICPC NEERC 2010, UVa 1593)

You are working in a team that writes Incredibly Customizable Programming Codewriter (ICPC) which is basically a text editor with bells and whistles. You are working on a module that takes a piece of code containing some definitions or other tabular information and aligns each column on a fixed vertical position, while keeping the resulting code as short as possible, making sure that only whitespaces that are absolutely required stay in the code. So, that the first words on each line are printed at position p1 = 1; the second words on each line are printed at the minimal possible position p2, such that all first words end at or before position p2 − 2; the third words on each line are printed at the minimal possible position p3, such that all second words end at or before position p3 − 2, etc.
For the purpose of this problem, the code consists of multiple lines. Each line consists of one or more words separated by spaces. Each word can contain uppercase and lowercase Latin letters, all ASCII punctuation marks, separators, and other non-whitespace ASCII characters (ASCII codes 33 to 126 inclusive). Whitespace consists of space characters (ASCII code 32).

Input

The input file contains one or more lines of the code up to the end of file. All lines (including the last one) are terminated by a standard end-of-line sequence in the file. Each line contains at least one word, each word is 1 to 80 characters long (inclusive). Words are separated by one or more spaces. Lines of the code can have both leading and trailing spaces. Each line in the input file is at most 180 characters long. There are at most 1000 lines in the input file.

Output

Write to the output file the reformatted, aligned code that consists of the same number of lines, with
the same words in the same order, without trailing and leading spaces, separated by one or more spaces such that i-th word on each line starts at the same position pi .
Note for the Sample:
The ‘⊔’ character in the example below denotes a space character in the actual files (ASCII code 32).

Sample Input

␣␣start:␣␣integer;␣␣␣␣//␣begins␣here
stop:␣integer;␣//␣␣ends␣here
␣s:␣␣string;
c:␣␣␣char;␣//␣temp

Sample Output

start:␣␣integer;␣//␣begins␣here
stop:␣␣integer;␣//␣ends␣␣␣here
s:␣␣␣␣␣␣string;
c:␣␣␣␣␣␣char;␣␣␣␣//␣temp

题意:输入若干行代码,要求各列单词的左边界对齐且尽量靠左。单词之间要求至少空一格。每个单词不超过80个字符,每行不超过180个字符,一共最多1000行。

思路:我们首先要找出每一竖列应该所占的字符长度,这就需要找出每一列的单词中最长的那个单词的长度,然后其他行的对应列也占用这么多的长度。

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
#include<bits/stdc++.h>
using namespace std;
vector<string> code[1005];//存入每一行的单词
int maxlen[1005]={0};//每一列的最长字符长度
int main()
{
int hang=0,lie=0;
string line,b;
while(getline(cin,line))//这个地方用来录入整个字符串,包括空格,让他们都存入line这一个串。
{
istringstream a(line);//istringstream类用于执行C++风格的串流的输入操作。
while(a>>b)//配合上一行可以实现将line中的每一个单词从头到尾依次提取出,并传递给b,a为空时退出循环。
{
maxlen[lie]=max(maxlen[lie],(int)b.size());//寻找每一列最长的字符长度
code[hang].push_back(b);//将每个单词分别压入code
lie++;//继续下一个单词
}
lie=0;
hang++;//下一行
}
cout << setiosflags(ios::left);//输出左对齐操作
for(int k=0;k<hang;k++)//每一行
{
int l;
for(l=0;l<code[k].size()-1;l++)//每行的每一个单词,code[k].size()表示的是单词的个数。
{
cout<<setw(maxlen[l]+1)<<code[k][l];//setw(int n)用来控制输出间隔,即这个单词所占字符长度
}
cout<<code[k][l]<<endl;//最后一个不需要空格,直接左对齐就可以
}
return 0;

}

这个题没有独自做出来,用了十分麻烦的方法,后来参考了其他博客,发现看不懂,很多没有接触过的新东西,下面我将一一列举我认为重要的点。

NO1:

1
2
3
4
5
vector<string> code[1005];/*
它的意义一开始很不理解,其实vector<string> code 表示的是由字符串组成的序列
而vector<string> code[1005] 表示的是字符串组成序列的序列,,,序列的序列,那不就是二维的吗?
也就是说vector<string> code 用来储存这一行的单词
那么vector<string> code[1005] 就是有这么多行。*/

NO2:

1
2
getline(cin,line)
如果光使用cin的话,空格是无法录入字符串的,所以我们用了这个操作。

NO3:

1
istringstream a(line);

他的作用是: 类用于执行C++风格的串流的输入操作,可以将一个字符串中的空格隔开的不同字符串,按顺序录入另一个字符串.

NO4:

1
2
setw(maxlen[l]+1)
我觉得他有点类似于printf("%5d",x);中那个5的作用。

这一个题收获了很多不知道的东西,尤其是对STL的理解与使用方面。

坚持原创技术分享,您的支持也将成为我的动力!
-------------本文结束感谢您的阅读-------------
undefined