When you find yourself doing the same thing over and over, that is a hint that you are working too hard.
Let’s look at a simplified exemplar of the problem: justifying a line to 20 characters.
01234567890123456789
Hello! 'Sup yo?
(1)
Make sure that punctuation marks have TWO spaces following.
THINK:
Obviously, we don't want to add spaces after things like
'
in
don't
.
Also, when we are done, we DON'T want to see:
01234567890123456789
H... ...yo?
^^ not justified!
We DO want to see:
01234567890123456789
H... ...yo?
^ yay! justified!
The easiest way already suggests itself.
Find a punctuation mark that is ALREADY followed by a space.
01234567890123456789
Hello! 'Sup yo?
^this X: not this, there is not any space after this
(there shouldn't be, anyway)
Hmm... We might want to trim() our string before doing anything else.
Okay, so far, our algorithm is:
(1) trim the string of leading and trailing whitespace
(2) replace <punct><space> with <punct><space><space>
Great!
01234567890123456789
Hello! 'Sup yo?
Now we want to RANDOMLY widen spaces until we make the line exactly
20 characters long.
There are quite a few ways to do this, but I will suggest something
exceedingly simple: Get a random number to ANY element of the string,
and if that element is a space, then make it two spaces.
1 2 3 4
|
while (s.length < max length):
n ← get a random number in the range 0..(s.length - 1)
if s[n] is a space:
insert an additional space before s[n]
|
Let's see it in action:
01234567890123456789
Hello! 'Sup yo?
↑ nope
01234567890123456789
Hello! 'Sup yo?
↑ nope
01234567890123456789
Hello! 'Sup yo?
↑ yeah!
01234567890123456789
Hello! 'Sup yo?
↑ nope
01234567890123456789
Hello! 'Sup yo?
↑ yeah!
01234567890123456789
Hello! 'Sup yo?
<skip some steps>
01234567890123456789
Hello! 'Sup yo?
|
Yeah!
So or revised algorithm is:
(1) trim the string of leading and trailing whitespace
(2) replace <punct><space> with <punct><space><space>
(3) do our cool random space insert loop
The trick, now that you have a working algorithm, is to translate it to code.
For part (1), make yourself a function that looks like this:
1 2 3 4 5 6
|
std::string trim( const std::string& s )
{
string result;
// what goes here? //
return result;
}
|
Part (2) will require a loop: look at each character of the string until you find a punctuation character.
std::ispunct()
from
#include <cctype>
will help you here. If the very next character is a space, then add a space:
1 2 3 4 5
|
for (int n = 0; n < (s.size() - 1); n++)
{
if (std::ispunct( s[n] ) && std::isspace( s[n+1] ))
s.insert( n+1, 1, ' ' );
}
|
There's a freebie for you.
Finally, for part (3) you will need to implement the pseudo-code algorithm I gave you above.
Hope this helps.