68. 文本左右对齐
office word开发既视感
思路没啥复杂的,就是模拟,但是调试过程会比较烦人
思路
每次往里面塞,记录当前塞进去的 单词数 和 长度
如果发现往下塞下一个单词的时候,长度超过这一行了,停止塞了。
计算一下每个单词的空格数=(本行的长度-塞进去的单词长度)/单词数
循环上面过程,直到塞进当前的这个是结尾了,直接把前面的一股脑塞进去
/*
思路:模拟
每次往里面塞,记录当前塞进去的 单词数 和 长度
如果发现往下塞下一个单词的时候,长度超过这一行了,停止塞了。
计算一下每个单词的空格数=(本行的长度-塞进去的单词长度)/单词数
循环上面过程,直到塞进当前的这个是结尾了,直接把前面的一股脑塞进去
*/
class Solution {
public:
vector<string> fullJustify(vector<string>& words, int maxWidth) {
//正常情况
//每个单词看
vector<string> result;
//words可能为空
if (words.empty()) {
return result;
}
int begin = 0;
int len = 0;//记录已塞进去的单词总长度
deque<string> q;//记录塞进去的单词
for (int i = 0; i < words.size(); i++) {
if (len + words[i].size()<= maxWidth) {
//可以往里面塞
q.push_back(words[i]);
len += words[i].size() + 1;//将这个单词 word 和空格合并,看成一个长度
}
else {
i--;
//这个单词不能塞了,把前面的都放进去
len--;//把最后一个的空格去掉
int num = q.size();//可以塞的单词总个数
//计算空格分配
string temp = "";
if (num == 1) {
//只有一个单词
int num = q.size();//可以塞的单词总个数
//塞进去最后不带空格的
temp += q.front() + string(maxWidth - len, ' ');
q.pop_front();
}
else {
//多个单词分配空格
int aveBlank = (maxWidth - len) / (num - 1);//平均每个单词分到的空格数
int remain = (maxWidth - len) % (num - 1);//剩下的空格数
for (int j = 0; j < num - 1; j++) {
if (remain > 0) {
temp += q.front() + string(aveBlank + 2, ' ');
remain--;
}
else {
temp += q.front() + string(aveBlank + 1, ' ');
}
q.pop_front();//删掉第一个
}
temp += q.front();
q.pop_front();
}
result.push_back(temp);
len = 0;
}
}
//把里面剩下的都塞成最后一行即可
if (!q.empty()) {
len--;
int num = q.size();//可以塞的单词总个数
string temp = "";
//塞进去前面带空格的
for (int j = 0; j < num - 1; j++) {
temp += q.front() + " ";
q.pop_front();
}
//塞进去最后不带空格的
temp += q.front()+string(maxWidth - len,' ');
q.pop_front();
result.push_back(temp);
}
return result;
}
};
改进
发现自己写的代码一大坨,虽然最终完成了需求,但是思路和函数功能上,并不是特别清晰,而且代码重复性很大
其实我们可以通过进一步分析发现,可以将往里面塞字符串,看成一个单独的功能,封装成一个子函数会更好一些
这样明确了单元测试,功能更加独立
class Solution {
public:
string pushnum(vector<string>& words, int start, int end, int maxWidth, int len,bool isEnd) {
string ans = "";
//如果只有一个字符要塞的
if (start == end) {
return words[start]+string(maxWidth-len,' ');
}
//如果是最后一行
if (isEnd) {
for (int i = start; i < end; i++) {
ans += words[i] + " ";
}
ans += words[end];
return ans + string(maxWidth - len, ' ');
}
//多个
int spaceNum = maxWidth - len;//要分配的空格数
int aveSpace = spaceNum / (end - start);//平均每个字符后面跟着的空格
int reserve = spaceNum % (end - start);//余下的需要分配的空格
for (int i = start; i < end; i++) {
if (reserve > 0) {
ans += words[i] + string(aveSpace + 2, ' ');
reserve--;
}
else {
ans += words[i] + string(aveSpace + 1, ' ');
}
}
ans += words[end];
return ans;
}
vector<string> fullJustify(vector<string>& words, int maxWidth) {
int sysmbleCount = 0;//符号计数
int start = 0;
vector<string> ans;
for (int i = 0; i < words.size() - 1; i++) {
sysmbleCount += words[i].size()+1;//把这个数塞进去
//如果把下一数塞进去算上就超了,那么把这一行整理一下塞进结果
if (sysmbleCount + words[i + 1].size() > maxWidth) {
ans.push_back(pushnum(words,start,i,maxWidth,sysmbleCount-1,0));
start = i + 1;
sysmbleCount = 0;
}
}
sysmbleCount += words.back().size() + 1;//把最后的数塞进去
ans.push_back(pushnum(words, start, words.size() - 1, maxWidth, sysmbleCount - 1, 1));
return ans;
}
};