I have to read in an integer which will be the length of the succeeding lines. (The lines of text will never be longer than the length provided).
I then have to read in each line of text and convert the spaces to an underscore as evenly as possible. For example:
I would enter the line length of 30. Then a line of text Hello this is a test string
. Then all of the spaces will be converted to underscores and padded out so that the text fills the given line length like so: Hello__this__is__a_test_string
. As you can see, the original text had a length of 27 characters, so to pad it out to 30 characters I had to add 3 extra spaces to the original text and then convert those spaces to the underscore character.
Please can you advise a way that I can go about this?
What I do is split the sentence in to words. Then figure out how many spaces need to be added. Then iterate over the words and add a space to each one until you run out of spaces to add. If you have enough spaces where you need to add more than one to the words (like you have 5 words, but need to add 13 spaces), simply divide the number of spaces left by the number of words, and add that number to each word first. Then you can take the remainder and iterate across the words adding a space until you're done. Also make sure that you only add spaces to all but the last word in the sentence.
I wrote a simple method to justify text. Its not 100% accurate, but works for the most part (since it ignores punctuations completely, and there might be some edge cases missing too). Also, Word justifies text in a richer manner (by not adding spaces to fill up the gap, but evenly distributing the width of a whitespace, which is tricky to do here).
The hardest thing about this problem is defining "as evenly as possible".
Your example:
... makes all the longer gaps be at the left. Wouldn't:
... fit the imprecise description of the problem better, with the longer gaps spread evenly through the output string?
However, let's solve it so it gives the sample answer.
numNewChars
==lengthWanted
minusinputString.length()
numGaps
-- it's the number of words minus one.n
orn+1
new spaces.n
isnumNewChars / numGaps
-- integer division; rounds down.n+1
new spaces instead ofn
? It's the remainder:plusOnes = numNewChars % numGaps
That's all the numbers you need. Now using whatever method you've been taught (since this is evidently a homework problem, you don't want to use language features or libraries that haven't been covered in your lessons), go through the string:
plusOnes
spaces, insertn+1
spaces, in addition to the space that's already there.n
spaces.One very basic method would be as follows:
The way I would go about this is to use a loop with regular-expression replacements.
After you do the initial replacement, I'd suggest you use a while loop, bounded on the length of the string being less than the target size. Initialize
int numUnderscores = 1;
outside of the while. Then the steps inside the loop will be:"/[^_](_{" + numUnderscores + "})[^_]/"
which says "any char that is not an underscore, followed by numUnderscores instances of the underscore char, followed by any char that is not an underscore".ReplaceFirst()
to perform the replacementnumUnderscores
Obviously, since this is a homework problem, I'm leaving the actual process of writing the code as an exercise. If you have specific questions about some piece of it, or about some component of the logic structure I described, just ask in comments!
The benefit of doing things this way is that it will work for any size string, and is very configurable for different situations.
I followed Shahroz Saleem's answer (but my rep is too low to comment :/) - however, I needed one minor change as it does not take into account words longer than the line length (such as URL's in the text.)
Note I also commented out the spaces padding for the last line of each paragraph (in getLeftJustifiedLine) and made the methods static..
The First part of this presentation contains a Dynamic Programming Algorithm for Justification of Text.