文本布局调整 Text Justification

142 篇文章 20 订阅
45 篇文章 0 订阅

问题:Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.

You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters.

Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.

For the last line of text, it should be left justified and no extra space is inserted between words.

For example,
words["This", "is", "an", "example", "of", "text", "justification."]
L16.

Return the formatted lines as:

[
   "This    is    an",
   "example  of text",
   "justification.  "
]

Note: Each word is guaranteed not to exceed L in length.

思路:算法上没有什么技巧,主要是细节流程处理。

对每一行的布局是这样的。

第一步,选词。尽量多选词,但是不能超过L长度,两个词之间至少留一个空格。

第二步,布局,根据多出的空位置,将空格平均分布到单词夹缝中。如果就只有一个单词,全放左边就行。如果是最后一行,也全部放左边。

注意如何平均分配空格:

1、总空格数/总间隙数 = 每个间隙的基本空格数

2、总空格数%总间隙数 = 多出来的空格数。那么这些做出来的空格,从左边的间隙开始一个间隙放一个,就达到题目的平均分配要求了。

class Solution {
public:
    vector<string> fullJustify(vector<string> &words, int L) {
        vector<string> re;
        int n = words.size();
        if(n == 0 ||L == 0 || words[0].size() == 0) //输入检查
        {
            string line = "";
            for(int i=0;i<L;i++)
                line += " ";
            re.push_back(line);
            return re;
        }
        
        int left, right, count;
        left = 0;
        count = words[0].size(); //count记录不调整布局时的长度
        int i = 0;
        while(i < n)
        {
            while(i < n-1 && count + words[i+1].size() + 1 <= L)
            {
                count += words[i+1].size() + 1; //选词:判断i+1要不要选。
                i++;
            }
            right = i;
            // words[left] ~ words[right] 做布局
            int wordnum = right - left + 1;
            if(wordnum == 1) //只有一个单词的情况
            {
                string line = words[left];
                for(int i=line.size();i<L;i++)
                    line += " ";
                re.push_back(line);
            }
            else if(right + 1 == n) //最后一行的情况
            {
                string line = words[left];
                int spacenum = L - count;
                for(int i=left+1;i<=right;i++)
                {
                    line += " " + words[i];
                }
                for(int i=0;i<spacenum;i++)
                    line += " ";
                re.push_back(line);
            }
            else //多个单词的情况, 平均插入多余的空格
            {
                int spacenum = L - count + wordnum - 1; //总空格数
                int everyslot = spacenum / (wordnum - 1);
                int addone = spacenum % (wordnum - 1); //mod运算多出的空格左边开始一人给一个
                string line = words[left];
                for(int i=left+1;i<=right;i++)
                {
                    for(int j=0;j<everyslot;j++)
                        line += " ";
                    if(addone > 0)
                    {
                        line += " ";
                        addone--;
                    }
                    line += words[i];
                }
                re.push_back(line);
            }
    
            left = i+1;
            if(left < n) //如果后面还有词的话,继续开始计数
                count = words[left].size();
            i++;
        }
        return re;
    }
};




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值