代码对齐[UVA1593]

本文解决UVA1593题目,重点介绍如何利用C++ STL高效处理表格输出,包括确定列宽、使用stringstream进行字符串分割等技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值