Почему мой C-код не печатает # в шаблоне лестницы, это из hackerrank, я не прошел все тестовые случаи, но я не могу указать почему?

#c #for-loop #if-statement

#c #для цикла #if-statement

Вопрос:

Напишите программу, которая печатает лестницу размером n.

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

Это мой код:

 void staircase(int n) {
    char a[n][n];
    for(int i = 0; i < n; i  ) {
        for(int j = 0; j < n; j  ) {
            if((i   j) > ((n / 2)   1)) {
                a[i][j] = '#';
                printf("%c", a[i][j]);
            } else {
                printf(" ");
            }
        }
        printf("n");
    }
}
  

Учитывая входные данные
6
Ожидаемый результат

      #
    ##
   ###
  ####
 #####
######
  

Объяснение:

Лестница выровнена по правому краю, состоит из символов # и пробелов и имеет высоту и ширину n=6 .

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

1. Пожалуйста, предоставьте ожидаемый результат и выходные данные вашей программы здесь.

2. Если вы используете язык C, кого вы помечаете C ?

3. Какой тестовый пример вы провалили

4. testcase с n == 1 должен печатать пробел или восьмиугольник?

5. @Tarik Это скрытые тестовые случаи, в которых произошел сбой кода. Видимые тестовые примеры пройдены.

Ответ №1:

Проблема в условии

 if((i   j) > ((n / 2)   1))
  

Это должно быть

 if(j >= n - i - 1)    // or   if(i   j >= n - 1)
  

Чтобы упростить это, я бы создал вспомогательную функцию. Кроме того, нет необходимости в VLA a[n][n] , который вы даже ни для чего не используете.

 void repeat_char(int x, char ch) {
    for(int i=0; i < x;   i) putchar(ch);
}

void staircase(int n) {
    for(int i = 1; i <= n;   i) {        
        repeat_char(n - i, ' ');   // or  printf("%*s", n - i, "");
        repeat_char(i, '#');
        putchar('n');
    }
}
  

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

1. Спасибо, условие было ошибочным. Ваше предложение помогло 🙂

2. Код, который вы написали, намного проще, но я новичок и думаю, что потребуется время, чтобы написать такие чистые и простые коды.

3. @sb7 Может потребоваться некоторое время, чтобы определить, какие части вы можете выделить и поместить в простые функции, которые выполняют всего одну маленькую вещь, такую как repeat_char функция, но всегда будьте в поиске этих частей. 🙂

Ответ №2:

Вам не нужна ваша a переменная, чтобы делать то, что вам нужно. Вот пример достижения того, чего вы хотите:

 void staircase(unsigned n)
{
        for (unsigned i = 0; i < n;   i) {
                for (unsigned j = 0; j < (n - i - 1);   j)
                        printf(" ");
                for (unsigned j = 0; j < (i   1);   j)
                        printf("#");
                printf("n");
        }
}
  

Первый цикл предназначен для покрытия каждой строки, затем внутри него вы создаете цикл, который обрабатывает пробелы перед фактическими # символами, и, наконец, вы создаете цикл, обрабатывающий отображение символов.

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

1. просто замечание: использовать printf для вывода одного символа стоит зря, иначе вы можете попросить printf вывести ожидаемый отступ для первого #, а не делать это самостоятельно

2. Спасибо за замечание, однако разве любой современный компилятор не сделал бы оптимизацию самостоятельно?

3. на этом уровне это не «оптимизация», вы просите слишком многого 😉

4. Вы были бы удивлены! Просто проверил сам, и кажется, что 9.3 делает это! Вот процесс компиляции и результат сборки: paste.ubuntu.com/p/zCzyNPCvQP ; В строках 148, 158 и 165 C-код printf заменен на putchar ‘s

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

Ответ №3:

Есть гораздо более простой способ сделать это, чем то, что вы пытаетесь сделать:

 #include <malloc.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    const int n = 6;
    char* str = malloc(sizeof(*str)*(n   1));
    if (str == NULL) {
        printf("Somthing wrong with memory!n");
        return 1;
    }
    memset(str, ' ', n);
    str[n] = '';
    for(int i = n - 1; i > -1; i--) {
        str[i] = '#';
        puts(str); //or maybe printf who cares
    }
    free(str);
    return 0;
}