例题5-8 UVA400 Unix ls(28行AC代码)

紫书刷题进行中,题解系列【GitHub|CSDN

例题5-8 UVA400 Unix ls(28行AC代码)

题目大意

给若干文件名,按字典序排列后,按列输出。其中每行60个字符,假设文件名最长长度为len,最后一列所占宽度为len,其余列占宽度为len+2,要求行数尽可能少。

思路分析

使用set<string>_set可自动按字典序排列

本题关键在于计算输出的行列数,假设文件名中最长长度为len,n为列数,那么总行列宽计算公式如下:

总列宽=(len+2)*(n-1)+len=(len+2)*n-2
行宽= ceil(n/列宽) // 向上取整
  • 可用%-len来控制输出对齐格式

注意点

  • 最后一列对齐宽度为最大长度,其余列需+2
  • 左对齐,按列输出

AC代码(C++11,按列输出,行列计算)

#include<bits/stdc++.h>
using namespace std;
int n;
string s, format;
int main() {
    while (cin >>n) {
        int maxlen=-1, len, colNum=1, rowNum;
        set<string> _set;
        for (int i = 0; i < n; i ++) {
            cin >>s; _set.insert(s);
            maxlen = max(maxlen, (int)s.size()); // 最长长度
        }
        while ((maxlen+2)*colNum-2 <= 60) colNum++; // 列数
        colNum --; rowNum = (int)ceil((float)n / colNum); // 行数
        vector<string> fnames;
        fnames.insert(fnames.begin(), _set.begin(), _set.end()); // set转为vector
        printf("%s\n", string(60,'-').c_str()); // 60个-
        for (int i = 0; i < rowNum; i ++) { // 遍历输出
            for (int j = 0; j < colNum && j*rowNum+i < n; j ++) {
                len = (j == colNum-1) ? maxlen : maxlen+2; // 最后一列对其宽度为maxlen
                format = "%-"+to_string(len)+"s"; // 输出格式
                printf(format.c_str(), fnames[j*rowNum+i].c_str());
            }
            puts("");
        }
    }
    return 0;
}

版权声明:本文为qq_40738840原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。