0

输出应该是这种方式

I
IN
IND
INDI
INDIA
INDIA
INDI
IND
IN
I

我想知道是否有办法让我的程序更短。

也许使用 2 个while循环或 2 个for循环而不是 4 个。

#include<iostream>
#include<conio.h>
using namespace std;
void main()
{
    char a[]={'I','N','D','I','A'};
    int r,c;
    for(r=1;r<=5;r++)
    {
        for(c=0;c<r;c++)
            cout<<a[c]<<" ";
        cout<<endl;
    }

    for(r=5;r>=0;r--)
    {
        for(c=0;c<r;c++)
            cout<<a[c]<<" ";
        cout<<endl;
    }
    _getch();
}
4

8 回答 8

10

如果你有 C++11,这很好很简短:

#include <stdio.h>
#include <initializer_list>
int main() {
    for (int i : {1,3,5,7,9,9,7,5,3,1})
        printf ("%.*s\n", i, "I N D I A") ;
}

我把它放在这个链接的ideone上。

于 2013-03-28T17:47:20.860 回答
2

“作弊” ;-) 但很短的解决方案是

#include <cstdio>
int main() {
    puts("I\nIN\nIND\nINDI\nINDIA\nINDIA\nINDI\nIND\nIN\nI\n");
}

基于TonyK的绝妙想法的另一个解决方案(适用于 C 和 C++):

#include <stdio.h>
int main() {
    for (int i = 1; i < 11; ++i)
        printf("%.*s\n", i < 6 ? i : 11 - i, "INDIA") ;
}

更新:(在 TonyK 发表评论后):

如果你想要空格,然后printf用这个替换上面的

printf("%.*s\n", 2*(i < 6 ? i : 11 - i), "I N D I A ");

更新:没有循环的解决方案:

#include <stdio.h>
int main(int i, char**) {
    return printf("%.*s\n", i < 6 ? i : 11 - i, "INDIA") - 1 && main(i + 1, 0);
}

以下为初学者的利益的详细解释。

最重要的一点是,这是一个“学术”练习。代码晦涩难懂,应该避免编写这样的严肃代码。

该标准没有为 function 修复特定的签名main。它只是说它必须返回一个int并且编译器必须接受两种特定的形式:

  1. int main();
  2. int main(int argc, char** argv);

我正在使用第二个。更流行的形式int main(int argc, char* argv[])等价于(2)。实际上,通常,用作函数参数的 T 数组被隐式转换为指向 T的指针。在这个例子中,是一个指向 charchar* argv[]的指针数组,它变成了指向 char的指针。上面的程序虽然没有使用第二个参数(它要么被忽略,要么被赋予 NULL,即 0 值)。

程序不是循环,而是main递归调用。实际上,这是非法的,但主要编译器对此视而不见(如果您要求它使用选项 -Wpedantic 迂腐,最多 GCC 会发出警告)。当从没有参数的命令行调用程序时,操作系统调用main传递1(即1+ 参数的数量)和指向 char 的指针的指针,如前所述,该程序将忽略该指针。因此,i = 1在第一次通话时。

随后,每次都main可能称自己为递增。i总而言之,main依次调用ibeing 1, 2, 3, 4, ...

很容易看出,对于 的这个值序列i,表达式的计算i < 6 ? i : 11 - i结果为1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, ...保存一行;-) 这些数字是每次应显示的“印度”字符数5.5 - abs(5.5 - i)#include <cmath>

调用printf("%.s\n", j, "INDIA"),其中j = i < 6 ? i : 11 - i,显示j“印度”的第一个字符,后跟一个新行,并返回有效打印的字符数(包括新行),即j + 1。带走1收益j

a && b我们现在回忆一下, 对于整数a和的语义的一个重要点b。如果a == 0b 则不计算。否则,b被评估。对我们来说,a = printf("%.*s\n", j, "INDIA") - 1(即a = j)和b = main(i + 1, 0)

现在,让我们把这些部分放在一起。

1.最初,i = 1j = 1。调用printf输出 "I\n" 并返回2. 带走1,给a = 1 != 0。因此,b = main(2, 0)被评估(main(2, 0)即被调用)。

2.好吧,对于第二次调用main,我们有i = 2j = 2printf显示“IN\n”,a = 2 != 0并被b = main(3, 0)评估。

重复这个论点,每次调用main我们都有:

3. i = 3 , j = 3, "IND\n" 被打印,a = 3 != 0并被main(4, 0)调用。

4. i = 4 , j = 4, "INDI\n" 被打印,a = 4 != 0并被main(5, 0)调用。

5. i = 5 , j = 5, "INDIA\n" 被打印,a = 5 != 0并被main(6, 0)调用。

6. i = 6 , j = 5, "INDIA\n" 被打印,a = 5 != 0并被main(7, 0)调用。

7. i = 7 , j = 4, "INDI\n" 被打印,a = 4 != 0并被main(8, 0)调用。

...

10. i = 10 , j = 1, "I\n" 被打印,a = 1 != 0并被main(11, 0)调用。

11. i = 11 , j = 0, "\n" 被打印出来, a = 0. 现在main(12, 0)不执行,main返回

请注意,main在第 1 步中调用第 2 步,main在第 2main步中调用3,...main在第 11 步中调用。因此,main在第 11 步中返回到main第 10 步,main在第 9 步中返回,...,在第 9 步中main返回步骤1。最后,main在步骤1中返回操作系统。

如果您对更加模糊的代码感兴趣,请查看IOCCC的现在和过去的获奖者。享受!

于 2013-03-28T18:04:31.060 回答
1

更短。

#include <iostream>
#include <cmath>

int main()
{
    char a[]={'I','N','D','I','A'};
    for(int r=1;r<=10;r++)
    {
        int c = 5.5 - std::abs(5.5 - r);
        std::cout << std::string(a, 0, c) << std::endl;
    }
}
于 2013-03-28T17:51:34.820 回答
0

你可以使用substr

此外,如果您想在字符之间添加空格(因为它现在在您的代码中),您可以对整个单词执行一次,然后处理修改后的字符串:

input = "INDIA";
modifiedInput = ...; // Figure out a way to get "I N D I A " here
for (int i = 1; ...)
    cout << substr(modifiedInput, 0, 2 * i) << endl;
...
于 2013-03-28T17:41:47.620 回答
0

像这样的smth:无论如何,2个循环很难)

 int i=1;
bool ind=0;
     for(r=0;r<10;r++)
      {
if (ind == 0){
          for(c=0;c<i;c++)
              cout<<a[c]<<" ";
    i++; }


    if (ind == 1){
          for(c=0;c<i;c++) cout<<a[c]<<" ";
    i--;
        }
    if (i % 5 == 0) ind=1;
        cout<<endl;
      }
于 2013-03-28T17:44:17.367 回答
0

这是一个使用两个循环的示例:

#include<iostream>

using namespace std;
int main()
{
  char a[]={'I','N','D','I','A'};
  int arr_length=5;
  bool two_times=false;//if you want to output INDIA twice
  for(int i=2*arr_length-1; i>=1; i--)
  {
      for(int j=0; j<arr_length-abs(arr_length-i); j++)
      {
            cout << a[j];
      }
      if(i==arr_length && !two_times){ two_times=true; i++;}//if you want to output INDIA twice
      cout << endl;
  }
  return 0;
}

输出:

I
IN
IND
INDI
INDIA
INDIA
INDI
IND
IN
I
于 2013-03-28T17:49:10.507 回答
0

你可以这样做:

void main()
{
  char a[]={'I','N','D','I','A'};
  int r,c;

  int x = 0;  // initially x is 0 
  int l = 5;
  for(r=1;r<= 11 ;r++)  //loop runs for 5*2 + 1 times
  {
     if(r>=6){
       x = l - r % 6;  //set x to remaining length 
       l--;
     }
     for(c=0;c< (r % 6) + x; c++)  // add x 
         cout<<a[c]<<" ";
     cout<<endl;
  }
}

你可以在这里找到它。

于 2013-03-28T18:12:21.303 回答
0

基于 TonyK 的答案的另一种解决方案。您可以输入所需的字符串。

#include <stdio.h>
#include <string.h>
int main() {
    char s[100];
    gets(s);
    for (int i = 0; i < strlen(s) * 2; i++)
        printf ("%.*s\n", i < strlen(s) ? i + 1: 2 * strlen(s) - i, s);
}

http://ideone.com/Zsg5Lu

于 2013-03-28T19:52:40.907 回答