68. Text Justification

本文介绍了一种文本排版算法,用于处理给定单词数组和最大宽度的格式化问题,确保每行文字达到指定宽度并实现左右对齐。讨论了贪婪算法的应用,详细解释了如何在单词间均匀分布空白字符,以及在最后一行进行左对齐的特殊情况。

68. Text Justification


Given an array of words and a width maxWidth, format the text such that each line has exactly maxWidth 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 maxWidth 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.

Note:

A word is defined as a character sequence consisting of non-space characters only.
Each word’s length is guaranteed to be greater than 0 and not exceed maxWidth.
The input array words contains at least one word.
Example 1:

Input:
words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
Output:
[
   "This    is    an",
   "example  of text",
   "justification.  "
]

Example 2:

Input:

words = ["What","must","be","acknowledgment","shall","be"]
maxWidth = 16
Output:
[
  "What   must   be",
  "acknowledgment  ",
  "shall be        "
]
Explanation: Note that the last line is "shall be    " instead of "shall     be",
             because the last line must be left-justified instead of fully-justified.
             Note that the second line is also left-justified becase it contains only one word.

Example 3:

Input:
words = ["Science","is","what","we","understand","well","enough","to","explain",
         "to","a","computer.","Art","is","everything","else","we","do"]
maxWidth = 20
Output:
[
  "Science  is  what we",
  "understand      well",
  "enough to explain to",
  "a  computer.  Art is",
  "everything  else  we",
  "do                  "
]

方法1:

喜刷刷:http://bangbingsyb.blogspot.com/2014/11/leetcode-text-justification.html

思路:

class Solution {
public:
    vector<string> fullJustify(vector<string>& words, int maxWidth) {
        int start = 0, end = -1, totLen = 0;
        bool isLast = false;
        vector<string> result;
        int i = 0;
        while (i < words.size()) {
            if (words[i].size() > maxWidth) return result;
            int newLen = totLen + (end - start + 1) + words[i].size();
            if (newLen <= maxWidth) {
                end = i;
                totLen += words[i].size();
                i++;
            }
            else {
                string line = createLine(words, maxWidth, start, end, totLen, false);
                result.push_back(line);
                start = i;
                end = i - 1;
                totLen = 0;
            }
        }
        
        string lastLine = createLine(words, maxWidth, start, end, totLen, true);
        result.push_back(lastLine);
        return result;
    }
    
    string createLine(vector<string> & words, int L, int start, int end, int totLen, bool isLast) {
        string ret;
        if (start < 0 || end >= words.size() || start > end) return ret;
        ret.append(words[start]);
        int n = end - start + 1;
        
        if (n == 1 || isLast) {
            for (int i = start + 1; i<= end; i++) {
                ret += " " + words[i];
            }
            int j = L -totLen - (n - 1);
            ret += string(j, ' ');
            return ret;
        }
        
        
        int k = (L - totLen) / (n - 1), m = (L - totLen) % (n - 1);
        for (int i = start + 1; i <= end; i++) {
            int nspace = i - start <= m ? k + 1 : k;
            ret += string(nspace, ' ');
            ret += words[i];
        }
        return ret;
    }
};

submission:
num:向前累计本行能放下的单词,len:本行累加的总单词长度。words[i + num].size() + len <= L - num, 这里是 左边是之前总长+新单词长 ,右边是maxWidth - num,去掉中间至少一个的空格条件下所允许的最长字符限制。如果成立,可以再多放一个单词,并且将长度累计,index前进。

出循环后已经收集了应该本行的单词范围,在 i 到 i + num这个区间内,首先tmp放入第一个单词words[i],接下来需要计算单词间应该有多少个空格。(L - len) / (num - 1) 是每个单词间应该至少插入的空格数,除此之外,前 m = (L - len) % (num - 1) 个间隔应该

class Solution {
public:
   vector<string> fullJustify(vector<string> &words, int L) {
    vector<string> ans;
    const int n = words.size();
    for (int i = 0; i < n;) {
        int num = 0, len = 0;
        while (i + num < n && words[i + num].size() + len <= L - num) {
            len += words[i + num].size();
            ++num;
        }
        string tmp = words[i];
        for (int j = 1; j < num; ++j) {
            if (i + num >= n) tmp += " ";
            else tmp += string((L - len) / (num - 1) + (j  <= (L - len) % (num - 1)), ' ');
            tmp += words[i + j];
        }
        tmp += string(L - tmp.size(), ' ');
        ans.push_back(tmp);
        i += num;
    }
    return ans;
}

};

https://www.tianmaying.com/tutorial/LC68

class Solution {
    string getALine(vector<string>& words, int maxWidth, int start, int end) {

        // 处理words.size() = 0的情况
        if (start > end) return string(maxWidth, ' ');    

        // 只有1个单词的情况
        if (start == end) return words[ start ] + string(maxWidth - words[ start ].size(), ' ');    

        string ret = "";
        int totLen = 0;
        // 统计单词长度
        for (int i = start; i <= end; ++i)
            totLen += words[i].size();

        // 计算间隔
        int space = (maxWidth - totLen) / (end - start);
        int rest  = (maxWidth - totLen) % (end - start);

        // 如果是最后一行特殊处理
        if (end == words.size() - 1) space = 1, rest = 0;

        // 处理出该行字符串
        ret += words[ start ];

        for (int i = start + 1; i <= end; ++i) {
            ret += string(space, ' ');
            if (i - start <= rest) ret += ' ';
            ret += words[i];
        }
        
        // 最后一行的特殊处理
        ret += string(maxWidth - ret.size(), ' ');
        return ret;
    }
public:
    vector<string> fullJustify(vector<string>& words, int maxWidth) {
        int prev = 0; // 表示该行起点的位置
		int len = -1; // 方便处理第一次计算
		for (int i = 0; i < words.size(); ++i) {
		   if (len + 1 + words[i].size() <= maxWidth)
  		      	len += 1 + words[i].size();    // 在紧凑放置的情况下仍然不超过 L
 		   else {
    		    ret.push_back( getALine(words, maxWidth, prev, i - 1) ); // 处理prev到i-1这一行
	
        		// 新的一行
        		len = words[i].size();
        		prev = i;
    		}
		}
        ret.push_back( getALine(words, maxWidth, prev, words.size() - 1) );
        return ret;
    }
};
import PySimpleGUI as sg layout1 = [ [sg.T("请输入挡土墙参数",text_color="red",size=30,font=10,justification="center",pad=(10))], [sg.Text('内斜坡高度(m)',size=30),sg.InputText(size=5,key="a")],[sg.Text('挡土墙顶部到墙趾高度(m)',size=30), sg.InputText(size=5,key="b")], [sg.Text('顶面荷载边缘距离内边坡的水平距离(m)',size=30), sg.InputText(size=5,key="c")],[sg.Text('内边坡宽度(m)',size=30), sg.InputText(size=5,key="d")], [sg.Text('列车荷载分布宽度(m)',size=30), sg.InputText(size=5,key="e")],[sg.Text('墙背倾角(°)',size=30), sg.InputText(size=5,key="f")], [sg.Text('墙底倾斜角度(°)',size=30), sg.InputText(size=5,key="g")],[sg.Text('墙背与土体摩擦角(°)',size=30), sg.InputText(size=5,key="h")], [sg.Text('挡土墙底部水平宽度(m)',size=30), sg.InputText(size=5,key="i")],[sg.Text('挡土墙重度(γ/m³)',size=30), sg.InputText(size=5,key="j")], [sg.Text('基底摩擦系数设计值',size=30),sg.InputText(size=5,key="k")] ] layout2=[ [sg.T('请输入随机变量统计特征',text_color="red",font=10,justification="center",size=30,pad=(10,10))], [sg.Text('土体重度平均值',size=30),sg.InputText(size=5)],[sg.Text('土体重度标准差',size=30),sg.InputText(size=5)],[sg.Text('土体内摩擦角平均值',size=30),sg.InputText(size=5)], [sg.Text('土体内摩擦角标准差',size=30),sg.InputText(size=5)],[sg.Text('列车荷载等效土柱高度平均值',size=30),sg.InputText(size=5)],[sg.Text('列车荷载等效土柱高度标准差',size=30),sg.InputText(size=5)] ] layout3=[[sg.T("结果分析",text_color="red",font=10)], [sg.Output(size=(80,15),key="jieguo")], [sg.Button('计算'), sg.Button('关闭')] ] layout=[ [sg.Column(layout1),sg.Column(layout2)], [layout3] ] # 创造窗口 window = sg.Window('Window Title', layout,finalize=True) while True: event, values = window.read() if event == "计算" : a=values["a"] b=values["b"] appl=a/b print('-----------------失效概率抽样计算结果-------------') print("失效概率:",appl) if event == "关闭": break window.close()
07-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值