【问题标题】:Printing a right-aligned "#" staircase打印右对齐的“#”楼梯
【发布时间】:2016-12-24 19:32:52
【问题描述】:

我在 Hackerrank 中做以下问题:
https://www.hackerrank.com/challenges/staircase?h_r=next-challenge&h_v=zen

基本上,代码必须打印出由“#”字符组成的右对齐“楼梯”。所以,如果输入是6,那么输出是:

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

这是我想出的解决方案(用 C 语言):

#include <stdio.h>
#include <string.h>

int main(){
    int n,i; 
    scanf("%d",&n);
    char str[]="";
    for(i=0;i<n;i++)
        strcat(str,"#");
    for(i=0;i<n;i++)
        printf("%*.*s\n",n,i+1,str);
    return 0;
}

但这不起作用,我似乎无法弄清楚出了什么问题。我不是在寻找新的解决方案。我只想知道我的代码做错了什么。

TIA!

【问题讨论】:

  • 请阅读documentation for strcat。您的目的地需要足够的缓冲空间。
  • 你必须为 str 分配足够的内存来保存 #
  • 我不是在寻找新的解决方案。 -- 取决于您所说的“新解决方案”是什么意思。必须分配空间也可能是一种“新解决方案”,因为执行此操作的代码可能看起来与您最初编写的代码大不相同。
  • “这不起作用”:你真的应该详细说明。它编译吗?它运行吗?它是段错误还是产生不正确的输出? “不工作”有上百万种变体。

标签: c printf


【解决方案1】:
char str[]="";

您没有指定str 的长度。 做类似的事情

  char str[10]="";//where 10 is the safest number you think.You should
                  //not have more than 10 characters.

【讨论】:

  • 你是对的!有效。在接下来的 2 个小时里,我会因为我犯了如此愚蠢的错误而感到沮丧。但是,C 中有没有一种方法可以在不指定大小的情况下创建字符串?
  • 在 C 中,你总是必须指定大小。
  • 还有一件事。当我运行代码时,它正确打印了第一行。代码从第二行开始就搞砸了。这就是为什么我不认为这是数组长度分配的问题。
  • @Stack-Boi 请不要因为犯错而沮丧。 “唯一从不犯错的人是从不做任何事情的人。 - 西奥多·罗斯福
  • @Stack-Boi 问题是,很多时候,最简单的代码中都有漏洞,有时大修是唯一好的解决方案。如果您在此处或此处更改字符,请不要以为您的代码会起作用。这就是它有时在这项业务中的运作方式。
【解决方案2】:

您正在观察strcat 的这种行为:

如果目标数组不足以容纳srcdest 的内容以及终止空字符,则行为未定义。

所以,在通过strcat追加额外的字符串到目的地之前,请确保目的地的大小相应地增加/调整,以便:

destination_size >= strlen(dest)+strlen(src)+1

另一个问题是您没有为每行获得正确宽度的空格' '。您需要嵌套的 for 循环来完成此操作。

【讨论】:

    【解决方案3】:

    忽略带有多个循环、嵌套循环、复杂逻辑等的答案。

    格式化为printf 是您在单个循环中所需要的全部内容: (IDEOne code)

    (这几乎是您的解决方案,但没有strcat,只使用硬编码字符串)

    #include <stdio.h>
    
    int main(void)
    {
        int level = 6;
        for(int i=1; i<=level; ++i)
            printf("%*.*s\n", level, i, "#####################");
    
        return 0;
    }
    

    我修复了您的解决方案以使用 memset 而不是 strcat,并稍微更改了 for 循环。

    就个人而言,我仍然更喜欢"###########" 的长常量字符串而不是memset-array。

    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
        int n,i; 
        char str[50];
    
        scanf("%d\n",&n);
    
        memset(str, '#', sizeof(str));
    
        for(i=1;i<=n;i++)
            printf("%*.*s\n",n,i,str);
    
        return 0;
    }
    

    【讨论】:

    • 谢谢! memset() 正是我想要的。
    • "我个人还是更喜欢长的常量字符串"。使用 memset() 不是比使用非常大的字符串更有效吗?
    • 高效在什么意义上?您可能会节省一些字节,但我认为 50 个字符的硬编码数组不会对您的计算机造成负担,而且我认为它使代码更加明显。
    【解决方案4】:

    给定五个正整数,找出可以通过将五个整数中的四个恰好相加来计算的最小值和最大值。然后将各自的最小值和最大值打印为一行,由两个空格分隔的长整数组成。

    这是一个 C# 解决方案:

        int n = 6;
        for (int i = 0; i <= n; i++)
        {
            string step = "";
            for (int k = 0; k < n - i; k++)
            {
                step += " ";
            }
            for (int j = 0; j < i; j++)
            {
                step += "#";
            }
            if (i > 0)
            {
                Console.WriteLine(step);
            }
        }
    

    【讨论】:

      【解决方案5】:
      #include <stdio.h>
      void repeat (char input , int count ){
          for (int i=0; i != count; i++ ) {
              printf("%c", input);
          }
      }
      int main(){
          int n;
          scanf("%d",&n);
          int temp1=1, temp=n-1;
          for(int i=0; i<n; i++){
              repeat(' ',temp);
              repeat('#',temp1);
              temp--;
              temp1++;
              printf("\n");
          }
      }
      

      【讨论】:

        【解决方案6】:

        请看这个:-

        #include <stdio.h>
        #include <string.h>
        
        int main(){
            int n,i,j,k; 
            scanf("%d",&n);
            for(k=0;k<n;k++)
            {
            for(i=n-1;i>k;i--)
            {
              printf(" ");
            } 
            for(j=0;j<k+1;j++)
            printf("*");
            printf("\n");
            }   
            return 0;
        }
        

        【讨论】:

        • OP:我不是在寻找新的解决方案。
        【解决方案7】:
        #include<stdio.h>
        int main(){
        
            int main(){
            int n;
            scanf("%d",&n);
            for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
            if(i+j<=n-1)
            printf("#");
            else
            printf(" ");
            }
            printf("\n");
            }
            return 0;
        }
        

        【讨论】:

        • OP 明确表示:“我不是在寻找新的解决方案。”
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-25
        • 2012-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-08
        • 1970-01-01
        相关资源
        最近更新 更多