扩展一个C数组


36

在C编程语言中,数组的定义如下:

int foo[] = {4, 8, 15, 16, 23, 42};      //Foo implicitly has a size of 6

数组的大小是从初始化元素推断出来的,在这种情况下为6。您还可以以这种方式编写C数组,显式调整其大小,然后按顺序定义每个元素:

int foo[6];        //Give the array an explicit size of 6
foo[0] = 4;
foo[1] = 8;
foo[2] = 15;
foo[3] = 16;
foo[4] = 23;
foo[5] = 42;

挑战

您必须编写将数组从第一种方式扩展到第二种方式的程序或函数。由于您正在编写使代码更长的程序,并且您很讽刺,因此必须使代码尽可能短。

输入将是代表原始数组的字符串,而输出将是扩展的数组定义。您可以放心地假设输入将始终如下所示:

<type> <array_name>[] = {<int>, <int>, <int> ... };

“ Type”和“ array_name”将完全由字母字符和下划线组成_。列表中的元素将始终是-2,147,483,648到2,147,483,647之间的数字。不需要处理任何其他格式的输入。

尽管允许使用尾随换行符,但输出中的空格必须与测试输出中的空格完全匹配。

测试IO:

#in
short array[] = {4, 3, 2, 1};

#out
short array[4];
array[0] = 4;
array[1] = 3;
array[2] = 2;
array[3] = 1;


#in
spam EGGS[] = {42};

#out
spam EGGS[1];
EGGS[0] = 42;


#in
terrible_long_type_name awful_array_name[] = {7, -8, 1337, 0, 13};

#out
terrible_long_type_name awful_array_name[5];
awful_array_name[0] = 7;
awful_array_name[1] = -8;
awful_array_name[2] = 1337;
awful_array_name[3] = 0;
awful_array_name[4] = 13;

鼓励您以任何语言提交论文,但如果可以使用 C 语言,则可以加分。

排行榜:

以下是排行榜,显示了最重要的答案:


2
数组索引,等号和输出中所需的值之间是否存在空格?例如,foo[0]=1;可以接受吗?
Mego

@Mego那是不可接受的。空格是必需的。我会编辑英寸
DJMcMayhem

允许尾随换行符?
Luis Mendo

是否允许功能?
Mego

是否可以返回输出而不是打印输出?(如果有功能)
Vault

Answers:


12

Pyth,44个字节

++Khcz\]lJ:z"-?\d+"1"];"VJs[ecKd~hZ"] = "N\;

测试套件

正则表达式和字符串斩波。不太聪明。

说明:

++Khcz\]lJ:z"-?\d+"1"];"VJs[ecKd~hZ"] = "N\;
                                                Implicit: z = input()
    cz\]                                        Chop z on ']'
   h                                            Take string before the ']'
  K                                             Store it in K
 +                                              Add to that
         :z"-?\d+"1                             Find all numbers in the input
        J                                       Store them in J
       l                                        Take its length.
+                  "];"                         Add on "];" and print.
                       VJ                       For N in J:
                         s[                     Print the following, concatenated:
                            cKd                 Chop K on spaces.
                           e                    Take the last piece (array name)
                               ~hZ              The current interation number
                                  "] = "        That string
                                        N       The number from the input
                                         \;     And the trailing semicolon.

这个答案是我这边的荆棘。我以为我可以在vim中获胜,但是为了我一生,我无法摆脱最后的2-3个字节。= D好答案!
DJMcMayhem

28

Vim,54、52、49 47击键


2wa0<esc>qqYp<c-a>6ldf @qq@q$dT]dd:%norm dwf{xwC;<CR>gg"0P

说明:

2wa0<esc>                     'Move 2 words forward, and insert a 0.
         qq                   'Start recording in register Q
           Yp                 'Duplicate the line
             <c-a>6l          'Increment the next number then move 6 spaces right
                    df        'Delete until the next space
                       @qq@q  'Recursively call this macro

现在我们的缓冲区看起来像这样:

int foo[0] = {4, 8, 15, 16, 23, 42};
int foo[1] = {8, 15, 16, 23, 42};
int foo[2] = {15, 16, 23, 42};
int foo[3] = {16, 23, 42};
int foo[4] = {23, 42};
int foo[5] = {42};
int foo[6] = {42};

而我们的光标在最后一行。

下半场:

$                           'Move to the end of the line
 dT]                        'Delete back until we hit a ']'
    dd                      'Delete this whole line.
      :%norm         <CR>   'Apply the following keystrokes to every line:
             dw             'Delete a word (in this case "int")
               f{x          '(f)ind the next '{', then delete it.
                  wC;       'Move a word, then (C)hange to the end of this line, 
                            'and enter a ';'

现在一切看起来都不错,我们只需要添加原始的数组声明即可。因此,我们这样做:

gg        'Move to line one
  "0P     'Print buffer '0' behind us. Buffer '0' always holds the last deleted line,
          'Which in this case is "int foo[6];"

3
每当我阅读vim-golf时,我就会意识到我所做的所有编码(主要是我的其他GUI编辑器中的键盘命令)看起来都像这样,并且我的头脑有点弯曲(Vim只是在变完整(并且更酷))。 :P

我无法正常工作-当我输入第一个“ @q”(@@ qq @ q)时,宏就会运行,并且运行得比预期的还要远,得到类似的结果int foo[6] = {并以int foo[12(cursor on “ 2”)
LordAro

@LordAro我可能应该提到过。这是因为q中已经有一个宏,并且在您录制时运行并将其弄乱。我在这里解释了如何解决该问题:codegolf.stackexchange.com/a/74663/31716
DJMcMayhem

1
@LordAro哦,我不知道是什么原因造成的。我更改df<space>dW保存一个字节,但是我忘记了这df<space>将打破第6行的宏,但dW事实并非如此。我将回滚修订。感谢您指出了这一点!
DJMcMayhem

1
虽然这不是最短的答案,但迄今为止却是最令人印象深刻的。
isaacg '16

10

视网膜,108个 104 100 69字节

字节数假定为ISO 8859-1编码。

].+{((\S+ ?)+)
$#2];$1
+`((\w+\[).+;(\S+ )*)(-?\d+).+
$1¶$2$#3] = $4;

击败这个,PowerShell ...

代码说明

第一行: ].+{((\S+ ?)+)

首先,我们需要保留类型,数组名称和左括号(节省一个字节),因此我们不匹配它们。因此,我们匹配了右括号,任意数量的字符和左花括号:].+{。然后我们匹配号码列表。到目前为止,我能找到的最短的是:((\S+ ?)+)。我们匹配任意数量的非空格字符(包括数字,可能的负号和可能的逗号),然后匹配一个空格,该空格可能存在也可能不存在:\S+ ?。然后根据需要(\S+ ?)+将这组字符重复多次:并放入较大的捕获组中。请注意,我们不匹配右花括号或分号。第三行说明了原因。

第二行: $#2];$1

由于我们仅匹配输入的一部分,因此不匹配的部分仍将存在。因此,我们将列表的长度放在了不匹配的开头括号之后:$#2。replace修饰符#可以帮助我们解决这个问题,因为它可以为我们提供特定捕获组进行的匹配次数。在这种情况下,捕获组2。然后,我们放在一个结束括号和一个分号,最后是整个列表。

使用input short array[] = {4, 3, 2, 1};,替换后的内部表示为:

短数组[4]; 4,3,2,1};

(注意右花括号和分号)

第三行: +`((\w+[).+;(\S+ )*)(-?\d+).+

这是一个循环的部分。这意味着它将一直运行,直到循环中的任何阶段都没有更改输入。首先,我们匹配数组名称,然后是左括号:(\w+\[)。然后是任意数量的任意字符和一个分号:.+;。然后,我们再次匹配列表,但是这次只有数字和每个数字后面的逗号,它们之间有一个空格:(\S+ )*。然后,我们捕获列表中的最后一个数字:(-?\d+)及其后面的所有剩余字符:.+

第四行: $1¶$2$#3] = $4;

然后,我们将其替换为数组名称和列表,后跟换行符:$1¶。接下来,我们把数组名,其次是先前匹配列表的长度,而最后一个元素(基本list.length - 1): $2$#3。后跟一个带空格的右括号和赋值运算符,然后是数字列表的最后一个元素:] = $4;

第一次替换后,内部表示形式如下所示:

short array[4];4, 3, 2, 
array[3] = 1;

注意,由于.+第三行的末尾,右花括号和分号消失了。再进行三次替换后,内部表示如下:

short array[4];
array[0] = 4;
array[1] = 3;
array[2] = 2;
array[3] = 1;

由于第三行不再需要匹配,因此第四行不会替换任何内容,并且会返回字符串。

TL; DR:首先,我们稍微更改int列表格式。然后,我们获取列表的最后一个元素和名称,并将它们放在数组初始化之后。我们这样做直到int列表为空。然后,我们将更改后的代码返回。

在线尝试!


有人殴打了我。...:(
CalculatorFeline

M!`G`相似,但不完全相同。小心。
CalculatorFeline

第三行的解释使我感到困惑。第一项是唯一没有空格的项目,而不是最后一项。
CalculatorFeline

@CatsAreFluffy我刚刚尝试更改措辞。我的意思是在数字后面而不是前面的空格。我想我还没有完全意识到“背后”的含义。我真的不应该在凌晨2点写代码说明。
daavko '16

@daavko在口语中,“ Behind”通常是指“ after”,即“ following”。你还好
Nic Hartley

9

V,37字节

2Eé0òYp6ldf ò$dT]ddÎdwf{xwC;
gg"1P

V是我编写的一种2D,基于字符串的高尔夫语言,是基于vim设计的。从提交17开始生效

说明:

这几乎是我的vim答案的直接翻译,尽管简短得多。

2E                               "Move to the end of 2 words forward.
  é0                             "Insert a single '0'
    ò       ò                    "Recursively do:
     Yp6ldf                      "Yank, paste, move 6 right, delete until space.
             $dT]                "Move to the end of line, delete backwards until ']'
                 dd              "Delete this line
                   Î             "Apply the following to every line:
                    dwf{xwC;<\n> "Delete word, move to '{' and delete it, Change to end of line, and enter ';'

然后我们有:

gg"1P     "Move to line 1, and paste buffer '1' behind us.

由于这种Unicode疯狂行为很难输入,因此您可以使用以下可逆的十六进制转储创建文件:

00000000: 3245 e930 f259 7001 366c 6466 20f2 2464  2E.0.Yp.6ldf .$d
00000010: 545d 6464 ce64 7766 7b78 7743 3b0d 6767  T]dd.dwf{xwC;.gg
00000020: 2231 500a                                "1P.

这可以通过安装V并键入以下命令来运行:

python main.py c_array.v --f=file_with_original_text.txt

1
Designed off of vim.2个注意事项:1.大多数人from不说off of,并且2.为什么不存在。+1
Rɪᴋᴇʀ

8

C,215字节,196字节

@tucuxi节省了19个字节!

打高尔夫球:

char i[99],o[999],b[99],z[99];t,x,n,c;main(){gets(i);sscanf(i,"%s %[^[]s",b,z);while(sscanf(i+t,"%*[^0-9]%d%n",&x,&n)==1)sprintf(o,"%s[%d] = %d;\n",z,c++,x),t+=n;printf("%s %s[%d];\n%s",b,z,c,o);}

取消高尔夫:

/*
 *  Global strings:
 *   i: input string
 *   o: output string
 *   b: input array type
 *   z: input array name
*/
char i[ 99 ], o[ 999 ], b[ 99 ], z[ 99 ];

/* Global ints initialized to zeros */
t, x, n, c;

main()
{
    /* Grab input string from stdin, store into i */
    gets( i );

    /* Grab the <type> <array_name> and store into b and z */
    sscanf( i, "%s %[^[]s", b, z );

    /* Grab only the int values and concatenate to output string */
    while( sscanf( i + t, "%*[^0-9]%d%n", &x, &n ) == 1 )
    {
        /* Format the string and store into a */
        sprintf( o, "%s[%d] = %d;\n", z, c++, x );

        /* Get the current location of the pointer */
        t += n;
    }

    /* Print the <type> <array_name>[<size>]; and output string */
    printf( "%s %s[%d];\n%s", b, z, c, o );
}

链接:

http://ideone.com/h81XbI

说明:

要获取<type> <array_name>sscanf()格式字符串是这样的:

%s          A string delimited by a space
    %[^[]   The character set that contains anything but a `[` symbol
         s  A string of that character set

为了从字符串中提取int值int foo[] = {4, 8, 15, 16, 23, 42};,我基本上使用以下函数将字符串标记化:

while( sscanf( i + t, "%*[^0-9]%d%n", &x, &n ) == 1 )

哪里:

  • i是输入字符串(a char*
  • t 是指针位置的偏移量 i
  • xint从字符串中实际解析出来的
  • n 是消耗的总字符,包括找到的数字

sscanf()格式字符串含义:

%*            Ignore the following, which is..
  [^0-9]      ..anything that isn't a digit
        %d    Read and store the digit found
          %n  Store the number of characters consumed

如果将输入字符串可视化为char数组:

int foo[] = {4, 8, 15, 16, 23, 42};
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
00000000001111111111222222222233333
01234567890123456789012345678901234

并将int 4其位于索引13,8索引16等,这就是循环中每次运行的结果:

Run 1)  String: "int foo[] = {4, 8, 15, 16, 23, 42};"
        Starting string pointer: str[ 0 ]
        Num chars consumed until after found digit: 14
        Digit that was found: 4
        Ending string pointer: str[ 14 ]

Run 2)  String: ", 8, 15, 16, 23, 42};"
        Starting string pointer: str[ 14 ]
        Num chars consumed until after found digit: 3
        Digit that was found: 8
        Ending string pointer: str[ 17 ]

Run 3)  String: ", 15, 16, 23, 42};"
        Starting string pointer: str[ 17 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 15
        Ending string pointer: str[ 21 ]

Run 4)  String: ", 16, 23, 42};"
        Starting string pointer: str[ 21 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 16
        Ending string pointer: str[ 25 ]

Run 5)  String: ", 23, 42};"
        Starting string pointer: str[ 25 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 23
        Ending string pointer: str[ 29 ]

Run 6)  String: ", 42};"
        Starting string pointer: str[ 29 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 42
        Ending string pointer: str[ 33 ]

1
您可以通过串联osprintf 来避免使用strcat %s。这应该刮掉大约7个字符。
tucuxi

@tucuxi啊,很好。谢谢!
homersimpson

7

C,195180字节

195字节原件:

打高尔夫球:

char*a,*b,*c,*d;j;main(i){scanf("%ms %m[^]]%m[^;]",&a,&b,&c);
for(d=c;*d++;i+=*d==44);printf("%s %s%d];\n",a,b,i);
for(d=strtok(c,"] =,{}");j<i;j++,d=strtok(0," ,}"))printf("%s%d] = %s;\n",b,j,d);}

松散:

char*a,*b,*c,*d;
j;
main(i){
    scanf("%ms %m[^]]%m[^;]",&a,&b,&c); // m-modifier does its own mallocs
    for(d=c;*d++;i+=*d==44);            // count commas
    printf("%s %s%d];\n",a,b,i);        // first line
    for(d=strtok(c,"] =,{}");j<i;j++,d=strtok(0," ,}"))
        printf("%s%d] = %s;\n",b,j,d);  // each array value
}

这两个快捷方式是使用m修饰符获取scanf %s来分配其自己的内存(节省声明char数组),并使用strtok(默认情况下也可用,不包含include)执行数字解析部分。


180字节更新:

char*a,*b,*c,e[999];i;main(){scanf("%ms %m[^]]%m[^}]",&a,&b,&c);
for(c=strtok(c,"] =,{}");sprintf(e,"%s%s%d] = %s;\n",e,b,i++,c),
c=strtok(0," ,"););printf("%s %s%d];\n%s",a,b,i,e);}

松散:

char*a,*b,*c,e[999];
i;
main(){
    scanf("%ms %m[^]]%m[^}]",&a,&b,&c);
    for(c=strtok(c,"] =,{}");sprintf(e,"%s%s%d] = %s;\n",e,b,i++,c),c=strtok(0," ,"););
    printf("%s %s%d];\n%s",a,b,i,e);
}

使用bnf679的附加到字符串想法,以避免必须计算逗号。


6

Python 3.6(预发布),133

m,p=str.split,print;y,u=m(input(),'[');t,n=m(y);i=m(u[5:-2],', ')
l=len(i);p(t,n+f'[{l}];')
for x in range(l):p(n+f'[{x}] = {i[x]};')

大量使用f弦

非高尔夫版本:

y, u = input().split('[')
t, n = y.split()
i = u[5:-2].split(', ')
l = len(i)
print(t, n + f'[{l}];')
for x in range(l):
    print(n + f'[{x}] = {i[x]};')

1
哇,我忘记了F弦 这些将对高尔夫超级有用!
Morgan Thrapp '16

我认为您可以通过使用列表理解而不是常规循环来保存一个字节
someonewithpc '16

@someonewithpc:不,它实际上会增加1个额外的字节
vaultah '16

5

Ruby,127 110 108 99 88字节

具有单个参数作为输入的匿名函数。完整程序,从STDIN读取输入。(如果通过管道传输文件,则尾随的换行符是可选的。)返回打印输出字符串。

@TimmyD吹牛他们的解决方案击败所有其他非esolangs作为挑战,并最终克服了(在撰写本文时)他们发布的114字节Powershell解决方案。奥伯奇科(CᴏɴᴏʀO'Bʀɪand)的诀窍是分拆]并拼接下半场以得到帮助。

我需要更多使用splat运算符。太有用了!

从@尼尔的JavaScript ES6答案通过扫描的话,而不是使用以节省更多的字节借用一招gsubsplit..

t,n,*l=gets.scan /-?\w+/;i=-1
puts t+" #{n}[#{l.size}];",l.map{|e|n+"[#{i+=1}] = #{e};"}

AFAICT的任务是编写完整的程序。
vaultah '16

@vaultah代码高尔夫的默认值是程序或功能
Mego

@Mego:OP说“您必须编写程序”
vaultah '16

@vaultah通常我会说代码高尔夫允许我使用一个函数,但是完整的程序为我节省了2个字节,所以为什么不呢?
价值墨水

糟糕...我认为PowerShell无法做到这一点。拥有+1
AdmBorkBork

4

05AB1E52 50 47字节

码:

… = ¡`¦¨¨ð-',¡©gr¨s«„];«,®v¹ð¡¦¬s\¨N"] = "y';J,

使用CP-1252编码。在线尝试!


1
我已经跳过所有其他答案,只是寻找您的05AB1E答案。语言绝对让我着迷。
WorseDoughnut

1
@WorseDoughnut谢谢!有人对我说过关于05AB1E :)的最好的事情!
阿德南

4

JavaScript(ES6),100字节

(s,[t,n,...m]=s.match(/-?\w+/g))=>t+` ${n}[${m.length}];`+m.map((v,i)=>`
${n}[${i}] = ${v};`).join``

由于只有单词很重要,因此可以通过匹配原始字符串中的所有单词,加上前导减号来工作,然后构建结果。(我本来以为我会用,replace但结果是红鲱鱼。)


[t,n,...m]几乎是一个神秘的视觉
edc65 '16


4

48 47字节

qR`(\S+)(. = ).(.+)}`{[b#Yd^k']';.n.b.,#y.c.y]}

从stdin接受输入并打印到stdout。

说明

Tl; dr:使用捕获组和回调函数构造结果来进行正则表达式替换。

q特殊变量读取一行的输入。正则表达式为(\S+)(. = ).(.+)},它匹配类型(包括尾随空格)和最后一个分号以外的所有内容。利用问题的第一个例子中,捕获组获得foo[] = 4, 8, 15, 16, 23, 42

替换是未命名函数的返回值,该函数{[b#Yd^k']';.n.b.,#y.c.y]}以整个匹配项加上捕获组作为参数来调用。因此,在函数内,b获取捕获组1,c获取组2和d获取组3。

我们构建了一个列表,前三个项目,其中将是"foo["6"]"。要获得6,我们将d内置变量k= 拆分", "Y将所得的整数列表添加到y变量中以备将来使用,并采用长度(#)。']是字符文字。

剩下的就是构造一系列形式的字符串";\nfoo[i] = x"。为此,我们将以下各项连接起来:';n(换行符的内置功能),b(第一个捕获组),,#y(等效于Python range(len(y))),c(第二个捕获组)和y。串联在列表和范围上逐项进行,因此结果是一个字符串列表。将所有内容放在一起,函数的返回值将是一个像这样的列表:

["foo[" 6 "]"
 [";" n "foo[" 0 "] = " 4]
 [";" n "foo[" 1 "] = " 8]
 [";" n "foo[" 2 "] = " 15]
 [";" n "foo[" 3 "] = " 16]
 [";" n "foo[" 4 "] = " 23]
 [";" n "foo[" 5 "] = " 42]
]

由于此列表用于字符串R放置,因此将其隐式转换为字符串。Pip中默认的列表到字符串转换是连接所有元素:

"foo[6];
foo[0] = 4;
foo[1] = 5;
foo[2] = 15;
foo[3] = 16;
foo[4] = 23;
foo[5] = 42"

最后,将自动打印结果(包括类型和最后的分号(与正则表达式不匹配,因此保持不变))。


4

Perl 5.10的,73 72 68 66 + 1(对于-n开关)= 67字节

perl -nE '($t,$n,@a)=/[-[\w]+/g;say"$t $n".@a."];";say$n,$i++,"] = $_;"for@a'

对于Perl来说,这是一个不错的挑战,也是迄今为止通用语言中最短的一种。相当于

($t, $n, @a) = /[-[\w]+/g;
say "$t $n" . @a . "];";
say $n, $i++, "] = $_;" for @a;

4

PowerShell v2 +,114105字节

$a,$b,$c,$d=-split$args-replace'\[]';"$a $b[$(($d=-join$d|iex|iex).length)];";$d|%{"$b[$(($i++))] = $_;"}

接受输入字符串$args,不-replace带方括号s,然后-split在空格上执行。我们存储所述第一位进入$a,第二位成$b,在=进入$c和数组元素进入$d。对于下面的例子中,此存储foo$abar进入$b,并且所有的数组转换成的$d

然后,我们输出我们的第一线"$a ...",并在中间变换$d从形式的字符串数组{1,2,...... 100};通过正常的int数组-join荷兰国际集团一起合并为一个字符串,然后通过运行它iex两次(类似eval)。$d在调用该.length方法以[]在输出行中的之间填充适当的数字之前,我们将结果数组存储回去。

然后,我们$d通过与发送循环|%{...}。每次迭代时,输出"$b..."的计数器变量$i都括在方括号中,并包含当前值$_。该$i变量开始未初始化(等于$null),但++会将其强制转换int为输出之前的,因此它将在开始下一次的输出0,然后再递增$i以进行下一个循环迭代。

所有输出线都留在管道上,并且在程序终止时隐式输出到终端。

PS C:\Tools\Scripts\golfing> .\expand-a-c-array.ps1 "foo bar[] = {1, 2, 3, -99, 100};"
foo bar[5];
bar[0] = 1;
bar[1] = 2;
bar[2] = 3;
bar[3] = -99;
bar[4] = 100;

ew!通过将您的评论打败其他非以eolangs作为挑战,我设法使Ruby的答案超越了您!不错,但是+1。
价值墨水

@KevinLau谢谢!现在回到105。;-)
AdmBorkBork 2016年

我给您打电话给105,给您提高99!:D
价值墨水

不再因击败视网膜而关闭。
CalculatorFeline

3

C,278280字节

打高尔夫球:

x,e,l,d;char *m,*r,*a;char i[999];c(x){return isdigit(x)||x==45;}main(){gets(i);m=r=&i;while(*r++!=32);a=r;while(*++r!=93);l=r-a;d=r-m;for(;*r++;*r==44?e++:1);printf("%.*s%d];\n",d,m,e+1);r=&i;while(*r++){if(c(*r)){m=r;while(c(*++r));printf("%.*s%d] = %.*s;\n",l,a,x++,r-m,m);}}}

松散:

/* global ints
 * x = generic counter
 * e = number of elements
 * l = length of the array type
 * d = array defination upto the first '['
 */
x,e,l,d;
/* global pointers
 * m = memory pointer
 * r = memory reference / index
 * a = pointer to the start of the array type string
 */
char *m,*r,*a;
/* data storage for stdin */
char i[999];
c(x){return isdigit(x)||x=='-';}
main(){
    gets(i);
    m=r=&i;
    while(*r++!=32);                // skip first space
    a=r;
    while(*++r!=93);                // skip to ']'
    l=r-a;
    d=r-m;
    for(;*r++;*r==44?e++:1);        // count elements
    printf("%.*s%d];\n",d,m,e+1);   // print array define
    r=&i;
    while(*r++) {                   // print elements
        if(c(*r)) {                 // is char a - or a digit?
            m=r;
            while(c(*++r));         // count -/digit chars
            printf("%.*s%d] = %.*s;\n",l,a,x++,r-m,m);
        }
    }
}

在进行此操作时,有人发布了一个使用sscanf进行解析的较短版本,而不是使用数据指针...不错!

更新:在元素打印(IDE在线链接)中发现等号周围缺少空格:http : //ideone.com/KrgRt0。请注意,此实现确实支持负数...


2

Awk,101个字节

{FS="[^[:alnum:]_-]+";printf"%s %s[%d];\n",$1,$2,NF-3;for(i=3;i<NF;i++)printf$2"[%d] = %d;\n",i-3,$i}

更具可读性:

{
FS="[^[:alnum:]_-]+"
printf "%s %s[%d];\n", $1, $2, NF - 3
for (i=3; i < NF; i++)
    printf $2"[%d] = %d;\n", i-3, $i
}
  • 我将字段分隔符设置为除字母,数字,下划线和以外的所有内容-。因此,这些字段将是类型名称,变量名称和数字。
  • 字段数将是1(对于类型)+1(对于名称)+ N(数字)+1(在结尾处为空字段};)。因此,数组的大小为NF - 3
  • 然后,它只是为声明打印一行,然后遍历数字。
  • 应该FS在调用awk时(使用-F)或在一个BEGIN块中进行分配。为了简洁起见,……。

1
实际上,FS必须使用分配BEGIN或使用分配,-F否则它将不会用于拆分第一行,并且由于只有一行输入内容...
罗伯特·本森

@RobertBenson您说得对,所以命令将是awk '-F[^[:alnum:]_-]+' '{printf"%s %s[%d];\n",$1,$2,NF-3;for(i=3;i<NF;i++)printf$2"[%d] = %d;\n",i-3,$i}',这是102个字节,不计算awk自身。嗯 我可以排除报价吗?
muru

是的,您可以排除引号。有时您将其列为C+O bytes位置,C并分别O代表代码和选项中的字节。当然,我通常只使用一个BEGIN块,所以我不必考虑它。:p
罗伯特·本森

2

JavaScript的ES6,134个 132 130 129字节

感谢Neil,节省了1个字节。

x=>(m=x.match(/(\w+) (\w+).+{(.+)}/),m[1]+` `+(q=m[2])+`[${q.length-1}];
`+m[3].split`, `.map((t,i)=>q+`[${i}] = ${t};`).join`
`)

`[${i}] = `+t+";"应该`[${i}] = ${t};`吗?
尼尔

@尼尔,谢谢,保存了一个字节!
Conor O'Brien

2

bash中,133个 129字节

read -a l
d="${l[@]:0:2}"
e=("${l[@]:3}")
echo "${d%?}${#e[@]}];"
for i in "${!e[@]}"
{
echo "${l[0]}[$i] = ${e[$i]//[!0-9]/};"
}

首次尝试,请确保使其更短。


2

D,197、188字节

import std.array,std.stdio;void main(){string t,n,e;readf("%s %s] = {%s}",&t,&n,&e);auto v=e.replace(",","").split;writeln(t,' ',n,v.length,"];");foreach(i,c;v)writeln(n,i,"] = ",c,";");}

或未打高尔夫球:

import std.array, std.stdio;

void main() {
    string type, nameAndBracket, elems;
    readf("%s %s] = {%s}", &type, &nameAndBracket, &elems);

    // remove all commas before splitting the string into substrings
    auto vector = elems.replace(",","").split();

    // writeln is shorter than fln by 1 char when filled in
    writeln(type, ' ', nameAndBracket, vector.length, "];");

    // print each element being assigned
    foreach(index, content; vector)
        writeln(nameAndBraket, index, "] = ", content, ";");
}

我不知道D,但是您能不能读一下方括号作为名字的一部分?这样可以节省您以后再单独写一个方括号的麻烦。
DLosc

2

利亚,154个 134 101字节

f(s,c=matchall(r"-?\w+",s),n=endof(c)-2)=c[]" "c[2]"[$n];
"join([c[2]"[$i] = "c[i+3]";
"for i=0:n-1])

这是一个接受字符串并返回带有单个尾随换行符的字符串的函数。

取消高尔夫:

function f(s, c = matchall(r"-?\w+", s), n = endof(c) - 2)
    c[] " " c[2] "[$n];\n" join([c[2] "[$i] = " x[i+3] ";\n" for i = 0:n-1])
end

我们定义c为正则表达式上的输入匹配项的数组-?\w+。它先键入类型,数组名称,然后是每个值。我们将n长度存储为c-2,即值的数量。输出被构造为内插的类型,名称和长度字符串,并与由换行符分隔的每个定义行组合。出于任何原因,c[]与相同c[1]

在Dennis的帮助下节省了32个字节!


1

Python 2,159字节

s=input().split()
t,n,v=s[0],s[1][:-2],''.join(s[3:])
a=v[1:-2].split(',')
print'%s %s[%d];'%(t,n,len(a))
for i in range(len(a)):print'%s[%d] = %s;'%(n,i,a[i])

在线尝试

感谢Kevin Lau的一些高尔夫建议


1

Python 3,116个字节

t,v,_,*l=input().split();v=v[:-1]+'%s]'
print(t,v%len(l)+';');i=0
for x in l:print(v%i,'= %s;'%x.strip('{,};'));i+=1

将输入分为类型,名称和数字列表。打印声明的数组后,通过手动枚举数字来打印元素,并删除附加在第一个和最后一个上的标点符号。

Python 2中的另一种方法达到了122个字节:

a,b=input()[:-2].split('] = {')
l=eval(b+',')
print a+`len(l)`+"];"
for y in enumerate(l):print a.split()[1]+'%s] = %s;'%y

这个想法是将eval数字列表作为一个元组,并以逗号结尾,以便将单个数字识别为一种类型。枚举的数字列表提供元组以字符串格式输入。


1

PHP,143字节

打高尔夫球

<?$t=count($n=explode(' ',preg_replace('/[^\s\w]/','',$argv[1])))-3;echo"$n[0] {$n[1]}[$t];";for($i=2;$t>$j=++$i-3;)echo$n[1]."[$j] = $n[$i];";

不打高尔夫球

<?  
$t = count(                                  // Get the number of elements for our array...
    $n = explode(' ',                            // After split the input on whitespace...
    preg_replace('/[^\s\w]/','',$argv[1])))-3;  // After removing all special characters.
echo "$n[0] {$n[1]}[$t];";                     // First line is type, name, and count.
for($i=2;                                        // Loop through array elements
    $t > $j = ++$i-3;)                         // Assign j to be the actual index for our new array
    echo $n[1]."[$j] = $n[$i];";                // Print each line

输入是通过命令行参数获取的。样品:

C:\(filepath)>php Expand.php "int foo[] = {4,8,15,16,23,42};"

输出:

int foo[6];foo[0] = 4;foo[1] = 8;foo[2] = 15;foo[3] = 16;foo[4] = 23;foo[5] = 42;

0

MATL68 64 58字节

'\w+'XX2:H#)XKxXIZc'['KnV'];'v!K"I2X)'['X@qV'] = '@g';'6$h

这不是C,但确实使用了类似C的sprintf函数 Nah,浪费了4个字节。

在线尝试!

          % Take input implicitly
'\w+'XX   % Find substrings that match regex '\w+'. Gives a cell array
2:H#)     % Split into a subarray with the first two substrings (type and name), and 
          % another with the rest (numbers that form the array)
XKx       % Copy the latter (numbers) into clipboard K. Delete it
XI        % Copy the former (type and name) into clipboard I
Zc        % Join the first two substrings with a space
'['       % Push this string
K         % Paste array of numbers
nV        % Get its length. Convert to string
'];'      % Push this string
v!        % Concatenate all strings up to now. Gives first line of the output
K"        % For each number in the array
  I2X)    %   Get name of array as a string
  '['     %   Push this string
  X@qV    %   Current iteration index, starting at 0, as a string
  '] = '  %   Push this string
  @g      %   Current number of the array, as a string
  ';'     %   Push this string
  5$h     %   Concatenate top 6 strings. This is a line of the output
          % Implicity end for each
          % Implicitly display

0

Clojure,115字节

#(let[[t n & v](re-seq #"-?\w+"%)](apply str t" "n\[(count v)"];\n"(map(fn[i v](str n"["i"] = "v";\n"))(range)v))))

我无法很好地合并awful_array_name[5];和分割,awful_array_name[0] = 7;以便它们重新使用代码:/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.