Напишите рекурсивную функцию
DrawTriangle()
, которая выводит строки'*'
, образуя равнобедренный треугольник с правой стороной вверх. ФункцияDrawTriangle()
имеет один параметр — целое число, представляющее длину основания треугольника. Предположим, что базовая длина всегда нечетна и меньше 20. Для правильного форматирования выведите 9 пробелов перед первым'*'
в первой строке.Подсказка: количество
'*'
увеличивается на 2 с каждой нарисованной линией.Пример: Если на входе программы: 3, функция
DrawTriangle()
выводит:* ***
Пример: Если на входе программы: 19, функция
DrawTriangle()
выводит:* *** ***** ******* ********* *********** ************* *************** ***************** *******************
Примечание. Пробел перед первым
'*'
в последней строке не выводится, если базовая длина равна 19.
Мне удалось правильно построить треугольник с помощью следующей рекурсивной функции:
void DrawTriangle(int baseLength, int spaces = 0) {
if (baseLength <= 0){
return;
}
DrawTriangle(baseLength - 2, spaces + 1);
for(int i = 0; i < spaces; i++){
cout << ' ';
}
for(int i = 0; i < baseLength; i++){
cout << '*';
}
cout << endl;
}
Проблема, с которой я столкнулся, заключается в том, что я понятия не имею, как получить правильное требуемое расстояние, то есть 9 пробелов перед единственной звездой.
Кажется, ваш код работает согласно вашему описанию (демо ). Что, по вашему мнению, именно неверно в выводе? Примечание: В чем проблема с «использованием пространства имен std;»?.
«Перед первым символом «*» в последней строке пробел не выводится» — вы имеете в виду, что хотите «сдвинуть» весь треугольник на 1 пробел вправо? Просто добавьте еще один std::cout << ' ';
перед первой петлей.
Вы должны использовать тот факт, что baseLength / 2
не превышает 9.
Поскольку первая строка всегда должна начинаться с 9 пробелов, независимо от того, что такое baseLength
, вам следует немного изменить логику.
Чтобы исправить свой код с небольшими изменениями, вы можете добавить этот оператор в начало вашей функции:
if (spaces == 0) spaces = 9 - baseLength / 2;
Это говорит о том, что если это был первый вызов (spaces == 0
), то в нижней строке вывода должно быть 9 - baseLength / 2
пробелов.
Это даст желаемый результат, но выглядит сложнее, чем должно быть.
Количество пробелов для печати напрямую связано со значением baseLength
, поэтому вы можете обойтись без параметра spaces
.
Кроме того, вы можете заменить циклы i
и использовать std::cout для печати символа N раз:
void DrawTriangle(int baseLength) {
if (baseLength <= 0) {
return;
}
DrawTriangle(baseLength - 2);
std::cout << std::string(9 - baseLength/2, ' ') << std::string(baseLength, '*') << std::endl;
}
Рекурсия здесь кажется излишним: вместо этого вы можете сделать это с помощью цикла, который создает одну строку за итерацию, начиная сверху.
void DrawTriangle(int baseLength) {
for (int stars = 1; stars <= baseLength; stars+=2) {
std::cout << std::string(9 - stars/2, ' ') << std::string(stars, '*') << std::endl;
}
}
По крайней мере, это не рекурсивная функция isEven
@bobobobo, о боже ;-)
Спасибо за вашу помощь, я тоже считаю, что рекурсия излишня, но я забыл упомянуть, что задание, к сожалению, требует рекурсии.
Рекурсия не подходит для этой проблемы. Я бы просто использовал циклы, если это не требуется заданием.