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."]
L: 16
.
Return the formatted lines as:
[ "This is an", "example of text", "justification. " ]
Note: Each word is guaranteed not to exceed L in length.
In this case, that line should be left-justified.
I cannot find a smart approach to solve this problem. Just do it step by step. If current line can accept one more word, push the word into current line. Otherwise push current line into final result and create a new line, then put the word into the new line.
C++ Code:
/* * func: push_back_line * goal: construct line into one string and push into vector * @param line: line vector * @param result: result vector * return: */ void push_back_line(vector<string>& line, vector<string> &result){ string word_line = ""; for(const auto &it : line){ word_line += it; } result.emplace_back(word_line); } /* * func: line_processing * goal: processing the current line, add spaces to make it fit the requirement * @param remaining: the number of spaces to be fit * @param line: word vector * return: */ void line_processing(int remaining, vector<string>& line){ //If there is only one word in the line if(line.size() == 1){ while(remaining > 0){ line[0] += ' '; --remaining; } }else{ //Evenly distribute space int each = remaining / (line.size()-1); for(int m = 1; m<line.size(); ++m){ for(int j=0; j < each; j++){ line[m] = ' ' + line[m]; } } remaining %= (line.size()-1); int it = 1; while(remaining > 0){ line[it] = ' ' + line[it]; ++it; --remaining; } } } /* * func: full_justify * goal: format the text such that each line has exactly L characters * @param words: vector of words * @param L: maximum length of each line * return: vector of strings */ vector<string> full_justify(const vector<string> &words, int L){ int max_length = 0; for(const auto &it : words){ max_length = std::max(static_cast<int>(it.length()), max_length); } if(max_length > L){ return vector<string>(); } vector<string> line; vector<string> result; int length = 0; for(int i=0; i < words.size(); ++i){ if(length == 0){ line.emplace_back(words[i]); length = words[i].length(); }else{ if( length + words[i].length() + 1> L){ line_processing(L - length, line); push_back_line(line, result); line.clear(); length = 0; --i; }else{ line.emplace_back(' '+ words[i]); length += words[i].length() + 1; } } } //Deal with the last line int remaining = L - length; //If there is only one word in the line while(remaining > 0){ line[line.size()-1] += ' '; --remaining; } push_back_line(line, result); return result; }
Python Code:
# func: format the text such that each line has exactly L characters # @param words: list of words # @param L: the length # @return: list of lines after justification def full_justify(words, L): max_len = len(max(words, key=len)) if max_len > L: return [] result = [] words_line = [] length = 0 i = 0 while i < len(words): if not words_line: words_line.append(words[i]) length = len(words[i]) i += 1 else: if length + len(words[i]) + 1 <= L: words_line.append(' '+words[i]) length += len(words[i]) + 1 i += 1 else: #We have to push current line into result spaces = L - length #If there is only one word in words_line, append all space to the end if len(words_line) == 1: words_line[0] += ' ' * spaces else: #spaces evenly assign to each word each_word_space = spaces / (len(words_line) - 1) for k in xrange(1, len(words_line)): words_line[k] = ' ' * each_word_space + words_line[k] #Assigning remaining spaces remaining_spaces = spaces % (len(words_line) - 1) space_i = 1 while remaining_spaces > 0: words_line[space_i] = ' ' + words_line[space_i] space_i += 1 remaining_spaces -= 1 #Construct current line and push it into result result.append(''.join(word for word in words_line)) words_line = [] length = 0 #Append last line spaces = L - length result.append((''.join(word for word in words_line)) + (' ' * spaces)) return result
No comments:
Post a Comment