Отправлено: 26.06.18 00:35. Заголовок: Вывод на консоль изображения фигуры (шаблона), состоящего из цифр и звездочек
Одна из многочисленных задач, задаваемых начинающим программистам, состоит в написании программы выводы на консоль того или иного изображения фигуры, состоящего из звездочек или других символов, как, например, вывод пирамид, треугольников и прочих фигур.
Вот одна из таких задач вывода изображения фигуры, с которой мне ранее не приходилось встречаться. Эта задача сформулирована в следующем вопросе на Stackoverflow How can I solve the following pattern in c++? (Возможно, ссылка может стать недействительной в виду удаления указанного вопроса)
1 2 3 4 5
1 2 3 4 *
1 2 3 * * *
1 2 * * * * *
1 * * * * * * *
Данная фигура состоит из пяти строк. Возникает вопрос, как выводить числа, если число строк превышает 9, То есть в общем случае могут появиться двухзначные и даже многозначные числа. В связи с этим фигура не будет выглядеть выравненной. Поэтому для вывода фигуры лучше использовать только цифры 1-9 даже для большого числа заданных пользователем строк, либо использовать цифры 0-9, начиная вывод с 1..
Как обычно, сначала сами попробуйте написать соответствующую программу.
Ниже приведено мое решение данной задачи. В приведенной программе для вывода чисел используются цифры 1-9. Если вы хотите включить в вывод также цифру 0, то первый вложенный цикл следует заменить на более простой цикл
for ( unsigned int k = 0; k < n - i; ++k ) std::cout << ( k + 1 ) % Base << ' ';
Вот сама программа.
#include <iostream>
int main() { const unsigned int Base = 10; const char c = '*';
while ( true ) { std::cout << "Enter a non-negative number (0 - exit): "; unsigned int n;
if ( not ( std::cin >> n ) or ( n == 0 ) ) break;
std::cout << '\n'; for ( unsigned int i = 0, j = 0; i < n; i++, j = 2 * i - 1 ) { for ( unsigned int k = 0, digit = 0; k < n - i; ++k ) { if ( ++digit == Base ) digit = 1; std::cout << digit << ' '; } for ( unsigned int k = 0; k < j; ++ k ) std::cout << c << ' '; std::cout << '\n'; } std::cout << '\n'; } }
Вывод программы на консоль может выглядеть, к примеру, следующим образом:
Отправлено: 05.07.18 15:35. Заголовок: Наверное самая часто..
Наверное самая часто встречающаяся фигура в подобных заданиях - это треугольник. Обычно требуется вывести треугольник, состоящий из звездочек, но, бывает, что задание усложняется выводом других символов, которые варьируются в зависимости от позиции в треугольнике, как показано в следующем вопросе на Stackoverflow What loop to use to generate the pattern below using C (Возможно, ссылка может стать недействительной в виду удаления указанного вопроса) В этом вопросе спрашивается, как вывести треугольник, состоящий из чисел, следующего вида
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 9
На самом деле данное задание ненамного сложнее задания вывода треугольника, состоящего из звездочек.
Для начала я покажу, как может выглядеть программа на C для вывода треугольника, состоящего из звездочек.
#include <stdio.h>
int main( void ) { const char c = '*';
while ( 1 ) { printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( ( scanf( "%u", &n ) != 1 ) || ( n == 0 ) ) break;
putchar( '\n' ); for ( unsigned int i = 0; i < n; i++ ) { for ( unsigned int j = 0; j < i + 1; j++ ) printf( "%c ", c ); putchar( '\n' ); } putchar( '\n' ); } }
Требуется незначительные изменения, чтобы программа выводила треугольник из чисел. Очевидно, что в измененной программе не требуется объявлять переменную, которая содержит символ вывода. Второе изменение связано с тем, что требуется определить ширину макисмального выводимого числа, чтобы выровнять вывод по колонкам.
Ниже показана измененная программа.
#include <stdio.h>
int main( void ) { const unsigned int Base = 10;
while ( 1 ) { printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( ( scanf( "%u", &n ) != 1 ) || ( n == 0 ) ) break;
int len = 1;
for ( unsigned int tmp = n; tmp /= Base; ) ++len;
putchar( '\n' ); for ( unsigned int i = 0; i < n; i++ ) { for ( unsigned int j = 0; j < i + 1; j++ ) printf( "%*u ", len, j + 1 ); putchar( '\n' ); } putchar( '\n' ); } }
Отправлено: 24.07.18 12:05. Заголовок: Чтобы вывести указан..
Чтобы вывести указанные выше изображения фигур треугольников симметрично отраженные относительно вертикальной оси, то единственное существенное изменение состоит в том, что первый символ в строке выводится в поле с соответственно вычисленной шириной поля.
Ниже показаны демонстрационные программы вывода симметрично отраженных треугольников.
#include <stdio.h>
int main( void ) { const char c = '*';
while ( 1 ) { printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( ( scanf( "%u", &n ) != 1 ) || ( n == 0 ) ) break;
putchar( '\n' ); for ( unsigned int i = 0; i < n; i++ ) { printf( "%*c ", ( int )( 2 * ( n - i ) - 1 ), c ); for ( unsigned int j = 1; j < i + 1; j++ ) printf( "%c ", c ); putchar( '\n' ); } putchar( '\n' ); } }
Вывод программы на консоль может выглядеть следующим образом:
while ( 1 ) { printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( ( scanf( "%u", &n ) != 1 ) || ( n == 0 ) ) break;
int len = 1;
for ( unsigned int tmp = n * ( n + 1 ) / 2; tmp /= Base; ) ++len;
putchar( '\n' ); for ( unsigned int i = 0; i < n; i++ ) { unsigned int value = ( n - i ) * ( n - i + 1 ) / 2; printf( "%*u ", ( int )( ( len + 1 ) * i + len ), value-- ); for ( unsigned int j = i + 1; j < n; j++ ) printf( "%*u ", len, value-- ); putchar( '\n' ); } putchar( '\n' ); } }
Вывод программы на консоль может выглядеть следующим образом:
Отправлено: 04.09.19 17:31. Заголовок: Вот еще одно аналоги..
Вот еще одно аналогичное задание, появившееся на Stackoverflow, по выводу изображения на консоль, с видом которого я еще не встречался. What Is The Logic Of This Pattern?
Ниже представлено мною написанное решение этого задания.
#include <stdio.h>
int main(void) { const char c = '*';
while ( 1 ) { printf( "Enter a non-negative integer (0 - exit): " );
int n;
if ( scanf( "%d", &n ) != 1 || n <= 0 ) break;
putchar( '\n' );
for ( int i = 0; i < n; i++ ) { printf( "%*c ", 2 * ( n - i * ( i % 2 == 0 ) ), c ); for ( int j = 0; j < i; j++ ) printf( "%c ", c ); putchar( '\n' ); }
putchar( '\n' ); }
return 0; }
Вывод программы на консоль может выглядеть, к примеру, следующим образом:
Отправлено: 07.09.19 13:27. Заголовок: Вот еще одна интерес..
Вот еще одна интересная фигура, состоящая из чисел, которую нужно вывести на консоль. Соответствующее задание я встретил в следующем вопросе на StackoverflowAdvanced Number Pattern
Пример изображения фигуры, которую нужно вывести на консоль:
То есть числа выводятся в треугольнике по возрастанию в зигзагообразном порядке.
Возможно, что решений этой задачи существует несколько, но два принципиальных подхода - это либо каждый раз вычислять заново значение очередного выводимого числа в требуемой позиции, либо вычислять это число рекурсивно относительно значения предыдущего выведенного числа. Второй подход выглядет проще.
Ниже представлены две демонстрационные программы с моими оешениями. Первая программа вычисляет значение очередного выводимого числа рекурсивно относительно значения предыдущего выведенного числа, а потому фломула для вычисления выглядет проще.
#include <stdio.h>
int main(void) { while ( 1 ) { const unsigned int UPPER_LIMIT = 100;
printf( "Enter a non-negative number no greater than %u (0 - exit): ", UPPER_LIMIT );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
if ( !( n < UPPER_LIMIT ) ) n = UPPER_LIMIT - 1;
putchar( '\n' );
for ( unsigned int i = 0; i < n; i++ ) { unsigned int value = i + 1; for ( unsigned int j = 0; j < i + 1; j++ ) { printf( "%2u ", value ); value += j % 2 == 0 ? 2 * ( n - i ) - 1 : 2 * ( i - j ); }
putchar( '\n' ); }
putchar( '\n' ); }
return 0; }
Вывод программы на консоль может быть, к примеру, следующим:
Enter a non-negative number no greater than 100 (0 - exit): 10
Отправлено: 16.10.19 12:02. Заголовок: Встретил еще одно за..
Встретил еще одно задание по выводу изображения некоторой фигуры на консоль на Stackoverflow, но, к сожалению, не могу предоставить ссылку на соответствующий вопрос, так как он, похоже, уже удален.
Итак, требуется вывести следующую фигуру (например, для n равным 4):
1 2 1 3 2 1 4 3 2 1.
То есть фигура выводится с некоторым "наклоном".
Ранее мне не приходилось сталкиваться с таким заданием.
Ниже представлено решение на C. Высоту фигуры я ограничил числом 10Ю то есть высота фигуры должна быть меньше 10. Это ограничение введено мною для простоты, чтобы не рассчитывать максимальную ширину поля для выводимых чисел.
#include <stdio.h>
int main(void) { while ( 1 ) { const int UPPER_LIMIT = 10; const int width = 3;
printf( "Enter a non-negative number less than %d (0 - exit): ", UPPER_LIMIT );
int n;
if ( scanf( "%d", &n ) != 1 || n <= 0 ) break;
if ( !( n < UPPER_LIMIT ) ) n = UPPER_LIMIT - 1;
putchar( '\n' );
for ( int i = 0; i < n; i++ ) { int value = i + 1;
printf( "%*d", 1 + ( n - i - 1 ) * ( width + 1 ), value-- ); for ( int j = 0; j < i; j++ ) printf( "%*d", width, value-- );
putchar( '\n' ); }
putchar( '\n' ); }
return 0; }
Вывод программы на консоль может выглядеть следующим образом.
Очередное задание, приведенное на сайте Stackoverflow, на вывод на консоль изображения "песочных часов", но на этот раз с помощью рекурсивной функции Draw hourglass recursively in C.
Например, если высота фигуры задана числом 6, то фигура будет выглядеть следующим образом
***** *** * * *** *****
А для нечетного числа 5 фигура будет выглядеть как
***** *** * *** *****
Главное в решении этого задания - это вопрос о передачи значения отступа для вывода очередной строки фигуры от одного рекурсивного вызова функции к другому.
Сделать это можно по крайней мере двумя способами.
Первый способ состоит в объявлении в функции статической переменной, которая будет сохранять значение отступа от одного вызова функции к другому.
Ниже приведена соответствующая демонстрационная программа.
#include <stdio.h>
void draw_hourglass_rec( unsigned int n ) { static unsigned int offset = 0;
const char c = '*';
if ( n ) { for ( unsigned int i = 0; i < offset; i++ ) putchar( ' ' );
unsigned int k = n % 2 == 0 ? n - 1 : n;
for ( unsigned int i = 0; i < k; i++ ) putchar( c ); putchar( '\n' );
if ( ! ( n < 2 ) ) { ++offset; draw_hourglass_rec( n - 2 ); --offset; }
if ( n != 1 ) { for ( unsigned int i = 0; i < offset; i++ ) putchar( ' ' ); for ( unsigned int i = 0; i < k; i++ ) putchar( c ); putchar( '\n' ); }
} }
int main(void) { while ( 1 ) { printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
putchar( '\n' );
draw_hourglass_rec( n );
putchar( '\n' ); }
return 0; }
Вывод программы на консоль, к примеру, может выглядеть следующим образом:
Второй способ заключается в написание вспомогательной функции, которая и будет рекурсивной, и которая через дополнительный параметр будет передавать значение отступа,
Вот, соответствующая демонстрационная программа.
#include <stdio.h>
void draw_hourglass_rec_helper( unsigned int n, unsigned int offset ) { const char c = '*';
if ( n ) { for ( unsigned int i = 0; i < offset; i++ ) putchar( ' ' );
unsigned int k = n % 2 == 0 ? n - 1 : n;
for ( unsigned int i = 0; i < k; i++ ) putchar( c ); putchar( '\n' );
if ( ! ( n < 2 ) ) draw_hourglass_rec_helper( n - 2, offset + 1 );
if ( n != 1 ) { for ( unsigned int i = 0; i < offset; i++ ) putchar( ' ' ); for ( unsigned int i = 0; i < k; i++ ) putchar( c ); putchar( '\n' ); } } }
void draw_hourglass_rec( unsigned int n ) { if ( n ) { draw_hourglass_rec_helper( n, 0 ); } }
int main(void) { while ( 1 ) { printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
putchar( '\n' );
draw_hourglass_rec( n );
putchar( '\n' ); }
return 0; }
Вывод этой программы на консоль будет выглядеть идентично выводу предыдущей программы. Это тот подход к решению задания, который был обозначен в соответствующем исходном вопросе на Stackoverflow.
int main() { while ( true ) { std::cout << "Enter a non-negative number (0 - exit): ";
int n;
if ( !( std::cin >> n ) || ( n <= 0 ) ) break;
if ( std::numeric_limits<int>::max() / 2 < n ) { n = std::numeric_limits<int>::max() / 2; }
int width = 1;
for ( int tmp = n; tmp /= 10; ) ++width;
std::cout << '\n';
int m = 2 * n - 1;
for ( int i = 0; i < m; i++ ) { for ( int j = 0; j < m; j++ ) { std::cout << std::setw( width ) << std::max( std::abs( n - i - 1 ) + 1, std::abs( n - j - 1 ) + 1 ) << ' '; } std::cout << '\n'; }
std::cout << '\n'; }
return 0; }
Чтобы понять формулу std::max( std::abs( n - i - 1 ) + 1, std::abs( n - j - 1 ) + 1 ), достаточно посмотреть ее значения при граничных значениях переменных i и j.
Все даты в формате GMT
3 час. Хитов сегодня: 10
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет