Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: My C++ exercise for today

36 views
Skip to first unread message

Chris M. Thomasson

unread,
Mar 24, 2017, 4:31:51 PM3/24/17
to
On 3/24/2017 1:13 PM, Stefan Ram wrote:
> I read a question in a newsgroup today about adjusting columns.
> So I wanted to implement this in C++ as a small exercise.
>
> I wanted to get from
>
> ::std::string source = R"(
> Alpha Beta Gamma Delta Epsilon
> Zeta Eta Theta Iota Kappa
> Lambda My Ny Xi Omikron
> Pi Rho Sigma Tau Ypsilon
> Phi Chi Psi Omega
> )";
>
> to
>
> Alpha Beta Gamma Delta Epsilon
> Zeta Eta Theta Iota Kappa
> Lambda My Ny Xi Omikron
> Pi Rho Sigma Tau Ypsilon
> Phi Chi Psi Omega
[...]

I guess just taking any given column; find the largest word in it, and
use that length for the space of a differential from every "smaller"
word in said column would allow for the + 1 space that should give the
effect of your table spacing.

So, lets say we take column 3 [0...3]

We notice the largest number of characters are in the words Epsilon,
Omikron and Ypsilon. We take that 7 as a max base. Well, we know that
Kappa has less characters than 7, so we have a differential. Knowing the
maxima of the word Epsilon, we know to add 2 spaces to Kappa in col 3,
along with an extra space to provide the separation of 1 between the
columns in the table. Assuming you wanted to add an extra column...

Sorry if I missed something here Stefan!

;^o

Ben Bacarisse

unread,
Mar 24, 2017, 5:58:50 PM3/24/17
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> I read a question in a newsgroup today about adjusting columns.
> So I wanted to implement this in C++ as a small exercise.
>
> I wanted to get from
>
> ::std::string source = R"(
> Alpha Beta Gamma Delta Epsilon
> Zeta Eta Theta Iota Kappa
> Lambda My Ny Xi Omikron
> Pi Rho Sigma Tau Ypsilon
> Phi Chi Psi Omega
> )";
>
> to
>
> Alpha Beta Gamma Delta Epsilon
> Zeta Eta Theta Iota Kappa
> Lambda My Ny Xi Omikron
> Pi Rho Sigma Tau Ypsilon
> Phi Chi Psi Omega

Maybe:

#include <sstream>
#include <iomanip>
#include <vector>
#include <algorithm>

std::string align_columns(const std::string &str)
{
std::vector<std::string::size_type> widths;
std::istringstream is(str);
std::string word;

for (unsigned col = 0; is >> word; col = is.peek() == '\n' ? 0 : col+1)
if (col >= widths.size())
widths.push_back(word.length());
else widths[col] = std::max(widths[col], word.length());

is.clear();
is.seekg(0);

std::ostringstream os;
os << std::left;

for (unsigned col = 0; is >> word; col = is.peek() == '\n' ? 0 : col+1)
os << std::setw(widths[col]) << word << (char)is.peek();

return os.str();
}

#include <iostream>

int main()
{
std::string source = R"(
Alpha Beta Gamma Delta Epsilon
Zeta Eta Theta Iota Kappa
Lambda My Ny Xi Omikron
Pi Rho Sigma Tau Ypsilon
Phi Chi Psi Omega
)";

std::cout << align_columns(source);
}

<snip>
> I also read a book recently about programming style. It
> suggested to write small functions with readable names
> and to prefer functions with no parameters.

What extraordinary advice! What's the book?

<snip>
--
Ben.

Chris M. Thomasson

unread,
Mar 24, 2017, 6:09:49 PM3/24/17
to
What about this logic wrt building a table on the fly:

24 words in your sample data

columns = ceil(sqrt(24)) = 5

Fill in the table using the 24 [0...23] words with five columns. Table
using integer indices for the words:
_________________________
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23
_________________________

index 4 would map to Epsilon
index 9 would map to Kappa
index 14 would map to Omikron
index 19 would map to Ypsilon

index 24 is "non-existent", except for a filler to make a 5x5 lattice.

is this kosher for your exercise?

Chris M. Thomasson

unread,
Mar 24, 2017, 6:15:09 PM3/24/17
to
On 3/24/2017 1:31 PM, Chris M. Thomasson wrote:
> On 3/24/2017 1:13 PM, Stefan Ram wrote:
>> I read a question in a newsgroup today about adjusting columns.
>> So I wanted to implement this in C++ as a small exercise.
>>
>> I wanted to get from
>>
>> ::std::string source = R"(
>> Alpha Beta Gamma Delta Epsilon
>> Zeta Eta Theta Iota Kappa
>> Lambda My Ny Xi Omikron
>> Pi Rho Sigma Tau Ypsilon
>> Phi Chi Psi Omega
>> )";
>>
>> to
>>
>> Alpha Beta Gamma Delta Epsilon
>> Zeta Eta Theta Iota Kappa
>> Lambda My Ny Xi Omikron
>> Pi Rho Sigma Tau Ypsilon
>> Phi Chi Psi Omega
> [...]
>
> I guess just taking any given column; find the largest word in it, and
> use that length for the space of a differential from every "smaller"
> word in said column would allow for the + 1 space that should give the
> effect of your table spacing.
>
> So, lets say we take column 3 [0...3]

YIKES! That would be column 4 [0...4] with the words Epsilon, Kappa,
Omikron and Ypsilon.

Sorry for that non-sense. ;^o

Chris M. Thomasson

unread,
Mar 24, 2017, 6:41:56 PM3/24/17
to
Works like a charm.

James Lothian

unread,
Mar 29, 2017, 11:03:19 AM3/29/17
to
Stefan Ram wrote:
> I read a question in a newsgroup today about adjusting columns.
> So I wanted to implement this in C++ as a small exercise.
>
> I wanted to get from
>
> ::std::string source = R"(
> Alpha Beta Gamma Delta Epsilon
> Zeta Eta Theta Iota Kappa
> Lambda My Ny Xi Omikron
> Pi Rho Sigma Tau Ypsilon
> Phi Chi Psi Omega
> )";
>
> to
>
> Alpha Beta Gamma Delta Epsilon
> Zeta Eta Theta Iota Kappa
> Lambda My Ny Xi Omikron
> Pi Rho Sigma Tau Ypsilon
> Phi Chi Psi Omega
>

Just for entertainment, I did it like this:

----------------------------------------

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <sstream>

std::vector<std::string> split(const std::string &input)
{
std::istringstream buff(input);
std::vector<std::string> r;
std::string blah;
while(buff >> blah) {
r.push_back(blah);
}
return r;
}

std::vector<size_t> getColWidths(const std::vector<std::string> &strings,
size_t colCount)
{
std::vector<size_t> widths(colCount, 0);
for(size_t i = 0; i < strings.size(); ++ i) {
size_t col = i % colCount;
size_t length = strings[i].size();
if(length > widths[col]) {
widths[col] = length;
}
}

return widths;
}

void writeStrings(const std::vector<std::string> &strings,
const std::vector<size_t> &widths,
size_t colCount)
{
for(size_t i = 0; i < strings.size(); ++ i) {
std::string s = strings[i];
size_t width = widths[i % colCount] + 1;
std::cout << std::setw(width) << std::left << s;
if((i + 1) % colCount == 0) {
std::cout << std::endl;
}
}
std::cout << std::endl;
}

int main(int argc, char* argv[])
{
std::string input = "Alpha Beta Gamma Delta Epsilon"
" Zeta Eta Theta Iota Kappa"
" Lambda My Ny Xi Omikron"
" Pi Rho Sigma Tau Ypsilon"
" Phi Chi Psi Omega";

std::vector<std::string> strings = split(input);
std::vector<size_t> widths = getColWidths(strings, 5);
writeStrings(strings, widths, 5);

return 0;
}




--
---------------------------------------------
demangle my email address in the obvious way.
0 new messages