简体   繁体   English

有什么方法可以缩短时间?

[英]Any ways to make this shorter?

The output is supposed to be in this fashion 输出应该以这种方式

I
IN
IND
INDI
INDIA
INDIA
INDI
IND
IN
I

I was wondering if there is anyway to make my program shorter. 我想知道是否有什么可以使我的程序更短。

Maybe use 2 while loops or 2 for loops instead of 4. 也许使用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();
}

This is nice and short, if you have C++11: 如果您使用的是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") ;
}

I put it on ideone at this link . 将此链接放在ideone上。

The "cheating" ;-) but very short solution is “作弊” ;-)但很短的解决方案是

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

Yet another solution based on TonyK 's beautiful idea (works in C and C++): 基于TonyK美好想法的另一种解决方案(可在C和C ++中使用):

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

Update: (After TonyK's comment): 更新:(在TonyK评论后):

If you want spaces, then replace the printf above with this 如果需要空格,则用此替换上面的printf

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

Update: A solution with no loop: 更新:无循环的解决方案:

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

Detailed explanations for the benefit of beginners follow. 以下是对初学者有利的详细说明。

The most important point is that this is an "academic" exercise. 最重要的一点是,这是一次“学术”练习。 The code is obscure and one should refrain from writing serious code like this. 该代码是晦涩的,应该避免编写像这样的严肃代码。

The standard doesn't fix a particular signature for the function main . 该标准并未为main函数修复特定签名。 It only says that it must return an int and the compiler must accept two particular forms: 它仅表示必须返回一个int ,并且编译器必须接受两种特殊形式:

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

I'm using the second one. 我正在使用第二个。 The more popular form int main(int argc, char* argv[]) is equivalent to (2). 更加流行的形式int main(int argc, char* argv[])等效于(2)。 Indeed, in general, an array of T used as a function argument is implicitly converted to pointer to T . 实际上,通常,将用作函数参数的T数组隐式转换为指向T的指针 In this example, char* argv[] is an array of pointer to char which becomes a pointer to pointer to char . 在此示例中, char* argv[]指向char指针的数组,该数组变为指向 char指针的指针 The above program is not using the second parameter though (it's either ignored or given a NULL, ie 0 value). 上面的程序虽然没有使用第二个参数(它要么被忽略,要么被赋予NULL,即0值)。

Instead of doing a loop, the program calls main recursivelly. 该程序没有进行循环,而是递归调用main Actually, this is illegal but the major compilers turn a blind eye to it (at most GCC gives a warning if you ask it to be pedantic with option -Wpedantic). 实际上,这是非法的,但是主要的编译器对此视而不见(如果您要求使用选项-Wpedantic对其进行窃,则至多GCC都会发出警告)。 When the program is called from the command line with no arguments the operating system calls main passing 1 (which is 1 + the number of arguments) and a pointer to pointer to char which, as said, is ignored by this program. 当从命令行中不带参数的情况下调用该程序时,操作系统将调用main传递1 (即1 +参数的数量)和指向char指针的指针 ,正如所指出的那样,此程序会忽略它。 Hence, i = 1 at the first call. 因此,在第一次通话时, i = 1

Subsequently, main potentially calls itself incrementing i each time. 随后, main可能会调用每次递增i自身。 In summary, main is sequentially called with i being 1 , 2 , 3 , 4 , ... 总之, main被顺序调用i1234 ,...

It's easy to see that for this sequence of values for i , the expression i < 6 ? i : 11 - i 很容易看出,对于i这个值序列,表达式i < 6 ? i : 11 - i i < 6 ? i : 11 - i evaluates to 1 , 2 , 3 , 4 , 5 , 5 , 4 , 3 , 2 , 1 , 0 , ... (This can also be expressed by 5.5 - abs(5.5 - i) as per Drew Dorman's solution but using the ternary operator avoids the need to #include <cmath> which saves a line ;-) These numbers are the quantity of characters of "INDIA" that should be displayed at each time. i < 6 ? i : 11 - i计算结果为12345543210 ,...(这也可被表示为5.5 - abs(5.5 - i)按德鲁Dorman的解决方案但使用三元运算符避免了需要#include <cmath> ,这节省了一行;-)这些数字是每次应显示的“ INDIA”字符数。

The call printf("%.s\\n", j, "INDIA") , where j = i < 6 ? i : 11 - i 调用printf("%.s\\n", j, "INDIA") ,其中j = i < 6 ? i : 11 - i j = i < 6 ? i : 11 - i , displays the first j characters of "INDIA" followed by a new line and returns the number of characters effectivelly printed (including the new line), ie j + 1 . j = i < 6 ? i : 11 - i ,显示“ INDIA”的前j字符,后跟新行,并返回有效打印的字符数(包括新行),即j + 1 Taking away 1 yields j . 拿走1产生j

We recall now an important point of the semantics of a && b , for integers a and b . 现在我们回想起a && b的语义对于整数ab的重要意义。 If a == 0 , then b is not evaluated . 如果a == 0则不评估 b Otherwise, b is evaluated. 否则,将评估b For us, a = printf("%.*s\\n", j, "INDIA") - 1 (ie a = j ) and b = main(i + 1, 0) . 对于我们来说, a = printf("%.*s\\n", j, "INDIA") - 1 (即a = j )和b = main(i + 1, 0)

Now, let's put these pieces together. 现在,让我们将这些片段放在一起。

1. Initially, i = 1 and j = 1 . 1.最初, i = 1j = 1 The call to printf outputs "I\\n" and returns 2 . printf的调用输出“ I \\ n”并返回2 Taking away 1 , gives a = 1 != 0 . 拿走1 ,得到a = 1 != 0 Therefore, b = main(2, 0) is evaluated (that is, main(2, 0) is called). 因此,对b = main(2, 0)进行求值(即,调用main(2, 0) )。

2. Well, for this second call to main , we have i = 2 , j = 2 , printf displays "IN\\n", a = 2 != 0 and b = main(3, 0) is evaluated. 2.好吧,对于第二次调用main ,我们有i = 2j = 2printf显示“ IN \\ n”, a = 2 != 0b = main(3, 0)

Repeating this argument, at each call to main we have: 重复此参数,在每次调用main我们都有:

3. i = 3 , j = 3 , "IND\\n" is printed, a = 3 != 0 and main(4, 0) is called. 3. i = 3j = 3 ,打印“ IND \\ n”, a = 3 != 0并调用main(4, 0)

4. i = 4 , j = 4 , "INDI\\n" is printed, a = 4 != 0 and main(5, 0) is called. 4. i = 4j = 4 ,打印“ INDI \\ n”, a = 4 != 0并调用main(5, 0)

5. i = 5 , j = 5 , "INDIA\\n" is printed, a = 5 != 0 and main(6, 0) is called. 5. i = 5j = 5 ,打印“ INDIA \\ n”, a = 5 != 0并调用main(6, 0)

6. i = 6 , j = 5 , "INDIA\\n" is printed, a = 5 != 0 and main(7, 0) is called. 6. i = 6j = 5 ,打印“ INDIA \\ n”, a = 5 != 0并调用main(7, 0)

7. i = 7 , j = 4 , "INDI\\n" is printed, a = 4 != 0 and main(8, 0) is called. 7. i = 7j = 4 ,打印“ INDI \\ n”, a = 4 != 0并调用main(8, 0)

... ...

10. i = 10 , j = 1 , "I\\n" is printed, a = 1 != 0 and main(11, 0) is called. 10. i = 10j = 1 ,打印“ I \\ n”, a = 1 != 0并调用main(11, 0)

11. i = 11 , j = 0 , "\\n" is printed, a = 0 . 11. i = 11j = 0 ,打印“ \\ n”, a = 0 Now main(12, 0) is not exectued and the main returns 现在main(12, 0) 12,0 main(12, 0)不执行, main返回

Notice that main in step 1 calls main in step 2, which calls main in step 3 , ... which calls main in step 11. Therefore, main in step 11 returns to main in step 10, which returns to main in step 9, ..., which returns to main in step 1. Finally, main in step 1 returns to the operating system. 请注意, main在步骤1调用main在步骤2中,它调用main在步骤3 ,...它调用main在步骤11中。因此, main在步骤11返回到main在步骤10中,其返回到main步骤9中, ...,它返回到步骤1中的main 。最后,步骤1中的main返回到操作系统。

If you are interested in even more obfuscated code, see present and past winners of the IOCCC . 如果您对更多混淆的代码感兴趣,请参阅IOCCC的现有和过去获奖者。 Enjoy! 请享用!

Shorter. 短一点

#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;
    }
}

You could use substr . 您可以使用substr

Additionally, if you want to add spaces between the characters (as it's in your code right now) you could do that once for the whole word and then work on that modified string: 另外,如果要在字符之间添加空格(如现在的代码所示),则可以对整个单词执行一次操作,然后对修改后的字符串进行处理:

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;
...

smth like this: Anyway, 2 loops is hard thing) 像这样:无论如何,很难做到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;
      }

Here is an example using two loops: 这是使用两个循环的示例:

#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;
}

Output: 输出:

I
IN
IND
INDI
INDIA
INDIA
INDI
IND
IN
I

You can do like this: 您可以这样:

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;
  }
}

and you can find it working here. 您可以在这里找到它的工作方式。

Another solution based on TonyK's answer. 基于TonyK答案的另一种解决方案。 You can enter your desired string. 您可以输入所需的字符串。

#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 http://ideone.com/Zsg5Lu

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM