C++: Multiplication Tables

Bjarne-stroustrup
 


Produce a formatted 12×12 multiplication table of the kind memorised by rote when in primary school.

Only print the top half triangle of products.

This is a slightly more-generalized version that takes any minimum and maximum table value, and formats the table columns.

#include <iostream>
#include <iomanip>
#include <cmath> // for log10()
#include <algorithm> // for max()

size_t get_table_column_width(const int min, const int max)
{
	unsigned int abs_max = std::max(max*max, min*min);

	// abs_max is the largest absolute value we might see.
	// If we take the log10 and add one, we get the string width
	// of the largest possible absolute value.
	// Add one for a little whitespace guarantee.
	size_t colwidth = 1 + std::log10(abs_max) + 1;

	// If only one of them is less than 0, then some will
	// be negative.
	bool has_negative_result = (min < 0) && (max > 0);

	// If some values may be negative, then we need to add some space
	// for a sign indicator (-)
	if(has_negative_result)
	colwidth++;

	return colwidth;
}

void print_table_header(const int min, const int max)
{
	size_t colwidth = get_table_column_width(min, max);

	// table corner
	std::cout << std::setw(colwidth) << " ";

	for(int col = min; col <= max; ++col)
	{
		std::cout << std::setw(colwidth) << col;
	}

	// End header with a newline and blank line.
	std::cout << std::endl << std::endl;
}

void print_table_row(const int num, const int min, const int max)
{
	size_t colwidth = get_table_column_width(min, max);

	// Header column
	std::cout << std::setw(colwidth) << num;

	// Spacing to ensure only the top half is printed
	for(int multiplicand = min; multiplicand < num; ++multiplicand)
	{
		std::cout << std::setw(colwidth) << " ";
	}

	// Remaining multiplicands for the row.
	for(int multiplicand = num; multiplicand <= max; ++multiplicand)
	{
		std::cout << std::setw(colwidth) << num * multiplicand;
	}

	// End row with a newline and blank line.
	std::cout << std::endl << std::endl;
}

void print_table(const int min, const int max)
{
	// Header row
	print_table_header(min, max);

	// Table body
	for(int row = min; row <= max; ++row)
	{
		print_table_row(row, min, max);
	}
}

int main()
{
	print_table(1, 12);
	return 0;
}
Output:
       1   2   3   4   5   6   7   8   9  10  11  12

   1   1   2   3   4   5   6   7   8   9  10  11  12

   2       4   6   8  10  12  14  16  18  20  22  24

   3           9  12  15  18  21  24  27  30  33  36

   4              16  20  24  28  32  36  40  44  48

   5                  25  30  35  40  45  50  55  60

   6                      36  42  48  54  60  66  72

   7                          49  56  63  70  77  84

   8                              64  72  80  88  96

   9                                  81  90  99 108

  10                                     100 110 120

  11                                         121 132

  12                                             144

SOURCE

Content is available under GNU Free Documentation License 1.2.