Генератор шаблонов

#c #loops #nested

#c #циклы #вложенный

Вопрос:

Я новичок в C , и я должен написать программу для генератора шаблонов, которая печатает 2 разных символа с разной частотой (вводится пользователем). Количество строк и столбцов также определяется пользователем.

Например, ‘*’ должно повторяться три раза, а ‘ ’ дважды в 4 строках по 21 столбцу, шаблон должен выглядеть следующим образом:

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

Однако мой вывод дает мне 21 столбец и 20 строк, что, я думаю, делает переменную ‘rows’ в моем коде ниже бесполезной, но я не уверен, почему это происходит.

Мой вывод:

 ***  ***  ***  ***  *
**  ***  ***  ***  **
*  ***  ***  ***  ***
  ***  ***  ***  *** 
 ***  ***  ***  ***  
***  ***  ***  ***  *
**  ***  ***  ***  **
*  ***  ***  ***  ***
  ***  ***  ***  *** 
 ***  ***  ***  ***  
***  ***  ***  ***  *
**  ***  ***  ***  **
*  ***  ***  ***  ***
  ***  ***  ***  *** 
 ***  ***  ***  ***  
***  ***  ***  ***  *
**  ***  ***  ***  **
*  ***  ***  ***  ***
  ***  ***  ***  *** 
 ***  ***  ***  ***  
  
 #include <iostream>
using namespace std;

int main()
{
    char a, b;
    int n,                  // number of times char a is repeated
        m,                  // number of times char b is repeated
        rows,               // number of rows
        columns,            // number of columns
        sumCharInRow = 0;
        
    cout << "Please input your first character: ";
    cin >> a;
    cout << "How many times should this character be repeated?: ";
    cin >> n;
    
    cout << "Please input your second character: ";
    cin >> b;
    cout << "How many times should this character be repeated?: ";
    cin >> m;
    
    cout << "Please input the number of rows: ";
    cin >> rows;
    cout << "Please input the number of columns: ";
    cin >> columns;
    
    
    for (int i = 0; i < rows; i  ) {
        
        for (int j = 0; j < columns; j  ) {
            
            for (int k = 0; k < n; k  ) {
                cout << a;      
                sumCharInRow  ; 
                
                if (sumCharInRow >= columns) {
                    cout << "n";
                    sumCharInRow = 0;
                }
            }
            
            for (int l = 0; l < m; l  ) {
                cout << b;
                sumCharInRow  ;
                
                if (sumCharInRow >= columns) {
                    cout << "n";
                    sumCharInRow = 0;
                }
            }
        }
    }
    
    return 0;
}
  

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

Редактировать: я понимаю, что «использование пространства имен std» является преступлением на C , но ради удобства чтения этой простой программы мой лектор настаивает на том, чтобы мы использовали это.

Комментарии:

1. Два наиболее вложенных цикла вместе выводят n m символы. Это повторяется columns * rows дважды двумя внешними циклами для общего количества (n m)*colums*rows напечатанных символов (не считая разрывов строк). В то время как предполагается, что вы должны печатать только colums*rows символы в целом. Вот так вы получаете в 5 раз больше строк, чем ожидали — 5 == 2 3

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

3. @IgorTandetnik спасибо за ваше объяснение. Могу ли я получить представление о том, как я могу это исправить? Это как-то связано с приращением j ?

Ответ №1:

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

Вы можете выбрать, какой символ печатать, чтобы сохранить ваши 2 цикла:

 void print_pattern(int col, int row, char c1, char c2, int n1, int n2)
{
    int counter = 0;
    for (int j = 0; j != row;   j) {
        for (int i = 0; i != col;   i) {
            std::cout << (counter < n1 ? c1 : c2);
            if (  counter == n1   n2) {
                counter = 0;   
            }
        }
        std::cout << std::endl;
    }
}
  

ДЕМОНСТРАЦИЯ

Комментарии:

1. Здравствуйте, большое спасибо за ваш ответ. Однако могу ли я спросить, как это counter < n1 ? c1 : c2 работает?

2. cond ? value1: value2 является троичным оператором , похожим на if / else .

3. counter это переменная для отслеживания того, где мы находимся в шаблоне.

Ответ №2:

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

     for (int i = 0; i < rows;) {
        for (int k = 0; k < n; k  ) {
            cout << a;      
            sumCharInRow  ; 
            
            if (sumCharInRow >= columns) {
                cout << "n";
                i  ;
                sumCharInRow = 0;
                break;
            }
        }

         if (sumCharInRow >= columns)
             continue;
        
        for (int l = 0; l < m; l  ) {
            cout << b;
            sumCharInRow  ;
            
            if (sumCharInRow >= columns) {
                cout << "n";
                i  ;
                sumCharInRow = 0;
                break;
            }
        }
    }

    return 0;
}
  

Комментарии:

1. Спасибо за ваш ответ, я протестировал ваш код, но результат, который я получил *** *** *** ***

2. Каково значение переменной columns ??

3. 21, я использовал то же, что и в примере (4 строки, 21 столбец)

4. Извините, я отредактировал сообщение, и объявление переменной sumCharInRow внутри цикла for было большой ошибкой. Мне очень жаль

5. continue; поскольку последний оператор цикла бесполезен (вы продолжаете внутренний цикл, а не внешний), и если вы оставите внутренний цикл (с break ), вы потеряете количество для шаблона.