代码对齐[UVA1593]

UVA1593 , ACM ICPC 2010 NEERC (Northeastern European Regional Contest)

https://vjudge.net/problem/UVA-1593

书上的习题5-1,按照个人的惯例,书上有的题目(主要是由简短中文翻译)就不贴问题描述了。可以在上面的链接中进入Vjudge查看详细的问题描述。作者把问题放在第五章C++和STL中,主要是要会灵活使用STL来提高解题效率。

题目要求每个单词左对齐,且要求单词之间至少空一格。其实不难看出,问题的关键在于确定每一列的列宽度。确定列宽度也不难思考,只要遍历所有数据,取最长的那个单词的长度,再加上1,即可得到该列的长度。按照这个思路,想在一次循环中边输入边处理是不大可能的,因此我使用了一个数组nlength来存放每一列最长的字符串的长度,并保存每一行的输入。第一次循环相当于预处理步骤,整个复杂度是输入的行数的线性函数关系$O(n)$。从而在第二次循环时,只需要根据已经确定好的表(维度:maxline * nlengthcount),来逐行打印输出即可(也是$O(n)$复杂度)。

对于输出时,如何从一行字符串的输入分割出单词的列,可以使用stringstream类的>>运算符。缺点是开销较大;优点就是不用手写分割函数,出错的几率小。具体什么时候用这些C++的库,我也一时拿不准,只能说凭感觉了。

除此之外,输出时我也定义了一个string临时变量,在输出时,按照行优先规则先循环mlinetext,然后循环nlength,先输出单词,然后填补需要的空格,接着转向下一列,直到ssstringstream)碰到结束为止(或者也可以在表上做标记,因为单词长度不可能为0,表可以初始化为0,因此读到0即该行结束)。注意每一行后可能会有多余的空格,而这时题目不允许的。因此可以使用string类本身的pop_back()函数,逐个剔除空格。虽然这样删除空格效率可能有点低,但是容易实现,且对本题的输入数据来说已经足够。

最后附上我的C++实现:(freopen忘记删了,注意一下。)

 

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<sstream>
 4 using namespace std;
 5 string mlinetext[1000];
 6 size_t nlength[200];
 7 int nlengthcount;
 8 int main()
 9 {
10     using namespace std;
11     freopen("input.txt", "r", stdin);
12     char buf[201];
13     string s;
14     int maxline = 0;;
15     while (cin.getline(buf, 200))
16     {
17         mlinetext[maxline] = buf;
18         stringstream ss(buf);
19         int i = 0;
20         while (ss >> s)
21         {
22             nlength[i] = max(s.length(), nlength[i]);
23             i++;
24             nlengthcount = max(i, nlengthcount);
25         }
26         maxline++;
27     }
28     string tmpline;
29     for (int n = 0; n < maxline; n++)
30     {
31         tmpline.clear();
32         stringstream ss(mlinetext[n]);
33         int m = 0;
34         while (ss >> s && m < nlengthcount)
35         {
36             tmpline.append(s);
37             if (nlength[m] == s.length())
38             {
39                 tmpline.push_back(' ');
40             }
41             else
42             {
43                 tmpline.append(nlength[m] - s.length() + 1, ' ');
44             }
45             m++;
46         }
47         while (tmpline.back() == ' ')
48             tmpline.pop_back();
49         cout << tmpline << endl;
50     }
51     return 0;
52 }
原文地址:https://www.cnblogs.com/ggggg63/p/6601918.html