On-line: гостей 1. Всего: 1 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 30.09.15 13:54. Заголовок: Вывод елочки на консоль


Часто начинающим программистам дают задание написать программу, которая выводит на консоль изображение той или иной фигуры, составленной из какого-нибудь символа или символов, как, например, звездочка '*'.

На днях мне встретилось такое задание на сайте ru.stackoverflow

Задача состоит в том, чтобы вывести изображение "елочки", или, по-другому, равнобедренных треугольников один под другим, увеличивая при этом размер высоты треугольника от 1 до заданного значения. Например, для n равным 3 "рисунок" будет выглядеть следующим образом:
 
*
*
***
*
***
*****

Как видно из рисунка (Более наглядный рисунок представлен по указанной мной ссылке), для n равным 3 сначала выводится "треугольник" с высотой, равной 1, затем с высотой, равной 2, и, наконец, с высотой, равной 3.

Решение должно быть оформлено на языке программирования C#.

Хотя я сам не успел принять участие в решении этого задания, тем не менее я решил восполнить этот пробел в данной теме и к тому же ознакомить вас с теми решениями, которые предлагаются на указанном сайте вопросов и ответов.

Если посмотреть предлагаемые решения, то общий подход состоит в том, что строится строка, которая предоставляет требуемый шаблон для вывода. Эта строка в свою очередь образуется за счет по крайней мере конкатенации двух строк (а иногда даже и трех строк): строки, состоящей из ведущих пробелов, и строки со звездочками.

На мой взгляд это не совсем удачные решения, так как в C# создается в этом случае множество строк в виду того, что строки в C# не изменяемые.

Проще было бы просто выводить отдельные символы пробела и звездочки в цикле. В этом случае никакие строки не создавались бы.

Хотя такой подход и содержит больше циклов, но на самом деле он более эффективный.

Вот решение этого задания с использованием описанного мною подхода:
 
using System;

namespace New_Year_Tree
{
class Program
{
static void Main(string[] args)
{
Console.Title = "New Year's Tree";
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Green;

Console.Clear();

while (true)
{
Console.Write("Enter a non-negative number (0 - exit): ");

int n;

if (!Int32.TryParse(Console.ReadLine(), out n) || n <= 0) break;

Console.WriteLine();

for ( int i = 0; i < n; i++ )
{
for ( int j = 0; j < i + 1; j++ )
{
for ( int k = 0; k < n - j; k++ ) Console.Write( ' ' );
for ( int k = 0; k < 2 * j + 1; k++ ) Console.Write( '*' );
Console.WriteLine();
}
}

Console.WriteLine();
}
}
}
}


c# имеет класс Console, который позволяет настраивать консоль, чем я и воспользовался в своей программе, сделав цвет изображения зеленым, как это показано в изображении фигуры в исходном вопросе.

Если вы хотите сократить число циклов, то тогда не обойтись без генерации строк. Тем не менее здесь тоже можно "сэкономить", так как совсем не обязательно строить результирующую одну строку.

Вот подход с использованием строк:
 
using System;

namespace New_Year_Tree
{
class Program
{
static void Main(string[] args)
{
Console.Title = "New Year's Tree";
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Green;

Console.Clear();

while (true)
{
Console.Write("Enter a non-negative number (0 - exit): ");

int n;

if (!Int32.TryParse(Console.ReadLine(), out n) || n <= 0) break;

Console.WriteLine();

for (int i = 0; i < n; i++)
{
for (int j = 0; j < i + 1; j++)
{
Console.WriteLine( "{0}{1}", new string( ' ', n - j ), new string( '*', 2 * j + 1 ) );
}
}

Console.WriteLine();
}
}
}
}

Как видно из текста программы, количество создаваемых строк ограничено за счет использования двух элементов формата.

Например, при n, равным 5, вывод на консоль будет выглядеть как
Enter a non-negative number (0 - exit): 5 

*
*
***
*
***
*****
*
***
*****
*******
*
***
*****
*******
*********

Enter a non-negative number (0 - exit): 0
Для продолжения нажмите любую клавишу . . .

А как сделать то же самое на языке программирования C++?

При использовании C++ вывод на консоль можно упростить и не строить шаблонные строки благодаря возможности указать для вывода данных символ-заполнитель.
Вот как может выглядеть соответствующая программа на C++:
 
#include <iostream>
#include <iomanip>

int main()
{
while ( true )
{
std::cout << "Enter an unsigned number (0 - exit): ";

unsigned int n = 0;
std::cin >> n;

if ( !n ) break;

std::cout << std::endl;

for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < i + 1; j++ )
{
std::cout << std::setfill( ' ' ) << std::setw( n - j ) << '*';
std::cout << std::setfill( '*' ) << std::setw( 2 * j + 1 ) << '\n';
}
}

std::cout << std::endl;
}
}

В этой программе вся работа по выводу n-ого числа символов делегирована самому стандартному потоку вывода. Никакие строки, что занимает ресурсы программы, не строятся. Поэтому это самое эффективное решение из всех здесь представленных решений.



Спасибо: 0 
ПрофильЦитата Ответить
Новых ответов нет


Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 18
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет