0

出力はこのようになっているはずです

I
IN
IND
INDI
INDIA
INDIA
INDI
IND
IN
I

とにかくプログラムを短くする方法があるかどうか疑問に思っていました。

4 ループの代わりに2whileループまたは 2ループを使用することもできます。for

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

初心者向けの詳細な説明が続きます。

最も重要な点は、これが「アカデミック」な演習であるということです。コードはわかりにくく、このような深刻なコードを書くことは控えるべきです。

標準は、関数の特定の署名を修正しませんmainintを返す必要があり、コンパイラは 2 つの特定の形式を受け入れる必要があることのみを示しています。

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

私は2番目のものを使用しています。より一般的な形式int main(int argc, char* argv[])は (2) と同等です。実際、一般に、関数の引数として使用されるT の配列は、暗黙的に T へのポインターに変換されます。この例では、 は char へのポインタへのポインタになるchar へchar* argv[]のポインタの配列です。ただし、上記のプログラムは 2 番目のパラメーターを使用していません (無視されるか、NULL、つまり値 0 が指定されます)。

ループを実行する代わりに、プログラムはmain再帰的に呼び出します。実際、これは違法ですが、主要なコンパイラはこれに目をつぶっています (オプション -Wpedantic でペダンティックにするように要求した場合、GCC はせいぜい警告を出します)。引数なしでコマンドラインからプログラムが呼び出されると、オペレーティングシステムは、main引き渡し1( 1+ 引数の数) と、前述のように、このプログラムによって無視されるchar へのポインターへのポインターを呼び出します。したがって、i = 1最初の呼び出しで。

その後、main潜在的に自分自身をi毎回インクリメントして呼び出します。要約すると、、 、、、 ...mainと順次呼び出されiます。1234

この の一連の値についてi、式が, , , , , , , , , ...とi < 6 ? i : 11 - i評価されることは簡単にわかります (これはDrew Dorman のソリューションに従って表現することもできますが、三項演算子を使用すると必要がなくなります行を保存する ;-) これらの数値は、毎回表示される "INDIA" の文字数です。123455432105.5 - abs(5.5 - i)#include <cmath>

呼び出しprintf("%.s\n", j, "INDIA")は、 "INDIA"j = i < 6 ? i : 11 - iの最初のj文字とそれに続く改行を表示し、(改行を含めて) 有効に印刷された文字数、つまり を返しますj + 11利回りを奪うj

a && bここで、整数aおよびに対するのセマンティクスの重要な点を思い出してbください。a == 0の場合b は評価されません。それ以外の場合bは評価されます。私たちにとって、a = printf("%.*s\n", j, "INDIA") - 1(つまりa = j) とb = main(i + 1, 0).

では、これらのパーツを組み合わせてみましょう。

1.最初に、i = 1およびj = 1. への呼び出しはprintf"I\n" を出力し、 を返します2。奪う1、与えるa = 1 != 0。したがって、b = main(2, 0)が評価されます (つまり、main(2, 0)呼び出されます)。

2.この 2 回目の呼び出しmainではi = 2、がありj = 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 = 11j = 0、「\n」が印刷されa = 0ます。現在main(12, 0)は実行されておらず、main返品

mainステップ 1mainではステップ 2 が呼び出さmainれ、ステップ 113では ... が呼び出されることに注意してくださいmain。したがって、mainステップ 11 では に戻りmain、ステップ 10 では に戻りmain、ステップ 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

2 つのループを使用した例を次に示します。

#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

substrを使用できます。

さらに、文字間にスペースを追加したい場合 (現在のコードにあるように)、単語全体に対して 1 回実行してから、その変更された文字列で作業することができます。

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

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 に答える
0

こんな感じ:とにかく、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

次のようにできます。

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 に答える