Как мне изменить этот код для печати ромбовидного узора, используя буквы из заданной строки? - PullRequest
0 голосов
/ 20 февраля 2020

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

Например:

> Enter a word: hello
    h
   e e
  l   l
 l     l
o       o
 l     l
  l   l
   e e
    h

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

#include <iostream>

using namespace std;

int main()
{
int n,k,c,space=1;
cout<<"Enter the number of Rows..."<<endl;
cin>>n;
space=n-1;
    for(k=1;k<=n;k++)
    {
        for(c=1;c<=space;c++)
        {
            cout<<" ";
        }
        space--;
        for(c=1;c<=2*k-1;c++)
        {
            cout<<"*";
        }
        cout<<endl;
    }
    space=1;
    for(k=1;k<=n;k++)
    {
        for(c=1;c<=space;c++)
        {
            cout<<" ";
        }
        space++;
        for(c=1;c<=2*(n-k)-1;c++)
        {
            cout<<"*";
        }
        cout<<endl;
    }
    return 0;
}

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

1 Ответ

2 голосов
/ 20 февраля 2020

Отличный способ работы с такими проблемами - начать с рисунка, такого как тот, который вы указали в своем вопросе. Теперь, для пятибуквенного слова «Hello», вы можете видеть из рисунка, что H центрирован в позиции 4. (Помните, индексы массива и строки начинаются с 0.) Следующим шагом будет также посмотреть другие примеры. Например, давайте посмотрим, что хотел бы алмаз для трехбуквенного слова «кошка».

  c
 a a
t   t
 a a
  c

На этот раз буква «c» центрирована в позиции 2. Цель делать эти примеры, чтобы найти образец; здесь мы обнаруживаем, что шаблон состоит в том, что первая буква всегда центрирована в позиции word length - 1. Таким образом, в строке с первой буквой есть word length - 2 начальных пробелов.

Как насчет следующей строки? Обратите внимание на то, что между повторяющейся буквой меньше одного начального пробела и дополнительного пробела. Таким образом, у нас есть word length - 2 - 1 ведущих пробелов и 1 пробелов, разделяющих их.

Как насчет третьей строки? Теперь у нас есть три пробела между буквами и word length - 2 - 2 начальных пробелов. Вы начинаете видеть шаблон? Как насчет того, чтобы посмотреть на четвертую и пятую строки первого примера («Hello») и попытаться выяснить количество начальных пробелов и пробелов между буквами. Прочитайте ниже, как только вы дадите ему шанс.

Каждый раз, когда мы go опускаемся вниз, мы теряем один пробел. За исключением второй строки, каждый раз, когда мы go вниз по строке, мы также получаем два пробела между буквами. Теперь, вы можете преобразовать этот шаблон в формулу? Опять же, посмотрите, можете ли вы придумать формулу, затем продолжайте читать.

Мы узнали, что число начальных пробелов равно word length - 1 - row (где row начинается с 0 ) и количество пробелов между буквами равно row * 2 - 1. (Обратите внимание, как эта формула правильно обрабатывает регистр второй строки.)

Таким образом, ваш код должен выглядеть примерно так:

// Word of caution: I have not tested this code.
using namespace std; // Bad practice in production code; used here for simplicity.
// *snip*
string my_word;
cin >> my_word;
int middle_index = my_word.length() - 1;
for (int r = 0; r < my_word.length; ++r) {
  // This code prints the top part of the diamond.
  for (int ls = 0; ls < middle_index - r; ++ls) {
    cout << " "; // Print out the leading spaces.
  }
  cout << my_word[r]; // You can replace this with my_word.substr(r, 1)
                      // if you are unallowed to treat strings like arrays.
  // r == 0 is a special case since we only print one of those letters.
  if (r == 0) {
    continue;
  }
  // Otherwise, we simply need to print the number of spaces in-between.
  for (int bs = 0; bs < 2 * r - 1; ++bs) {
    cout << " ";
  }
  cout << my_word[r];
}

Теперь, чтобы напечатать вторую половину ромба, Вы должны сделать что-то похожее на выше. Не забудьте начать свой l oop с word length - 2 (обратитесь к своей фотографии, чтобы понять почему) и уменьшать индекс l oop каждый раз. Также не забывайте, что r == 0 все еще является особым случаем, поскольку вы печатаете его только один раз.

...