算法竞赛 例题5-8 Unix ls命令(Unix Is,UVa 400)
程序员文章站
2022-07-13 17:48:24
...
题目要求:
输入正整数N以及N个文件名,排序后按列优先的方式左对齐输出。假设最长文件名有M个字符,则最右列有M个字符,其他列都是M+2个字符,不够的则在末尾补空格字符。要求输出的每行的总字符数不超过60,且行数最小。
求行数和列数:
由于每行最多60个字符,输入的文件名最长字符为M个,最右列是M个字符,其余的每列都是M+2个字符,所以列数为cols=(60-M)/(M+2)+1;行数是总的个数除以列数+1,rows=(n-1)/cols+1;
思路:
给输入的文件名排序,存在数组里,如果是横向输出,可以跳着输出,例如列为4的时候,先输出filenames[0],然后输出filenames[4],filenames[8]…如果是纵向输出,需要两个for循环,先for循环列,里边嵌套for循环行。
C++代码
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
const int maxcol=60;//每行最多60个字符
const int maxn=100+5;
string filenames[maxn];//文件名数组
//输出字符s,长度不足len时,用字符extra补齐
void print(const string& s,int len,char extra){
cout<<s;
for(int i=0;i<len-s.length();i++){
cout<<extra;
}
}//s 文件名,len是M+2,len-s.length()是需要输出的空格,extra是符号。
int main()
{
int n;
while(cin>>n){
int M=0;
for(int i=0;i<n;i++){
cin>>filenames[i];
M=max(M,(int)filenames[i].length());//最长文件名
}
//计算列数cols和行数rows
int cols=(maxcol-M)/(M+2)+1;
int rows=(n-1)/cols+1;
print("",60,'-');
cout<<"\n";
sort(filenames,filenames+n);
for(int r=0;r<rows;r++){
for(int c=0;c<cols;c++){
int a=c*rows+r;
if(a<n)
print(filenames[a],c==cols-1?M:M+2,' ');
//若为最后一列是M个字符,若不是最后一列是M+2个字符
}
cout<<"\n";
}
}
return 0;
}
结果:
错误:最后出来一点小问题,最后一列还是按照M+2个字符输出,如果把cols-1改为cols-2就可以了,但是不太理解为什么?哪位大佬看到,帮忙解答一下, 谢谢!