可视化嵌套数组


15

您将获得一个嵌套数组。您的程序必须可视化数组。


但是..如何?

例如,假设我们有一个嵌套数组,例如 [["1","2"],[["1","2"],"3"],"4",[[[["5"]]]],"6"]

此嵌套数组可以显示为:

->1
->2
-->1
-->2
->3
>4
---->5
>6

例子

Input 1:
["Atom",["Proton",["Up Quark", "Up Quark", "Down Quark"], "Neutron", ["Up Quark", "Down Quark", "Down Quark"], "Electron"]]
Output 1:
>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Down Quark
-->Down Quark
->Electron

Input 2:
[["1","2"],["3","4"]]
Output 2:
->1
->2
->3
->4

规则

  • 您可以使用字符串(或其他类似嵌套数组的类型)作为输入。
  • “层”的最大级别为2 ^ 32-1。

是否必须具有这种精确的可视化效果?
penalosa

@mnbvc是的,除非我强迫这样做,否则人们会开始大量扭曲I / O。相信我,我尝试了。
马修·鲁

我觉得视网膜会赢得这场胜利。
魔术八达通Ur

1
字符串中可以出现哪些字符有任何限制?
Martin Ender

其他相关问题1、2
AdmBorkBork

Answers:


12

APL,32字节

{1=≡⍺:⎕←⍺,⍨⍵↑1↓⍵/'->'⋄⍺∇¨⍵+1}∘0

测试:

      r
┌────┬─────────────────────────────────────────────────────────────────────────────────────────┐
│Atom│┌──────┬──────────────────────────────┬───────┬────────────────────────────────┬────────┐│
│    ││Proton│┌────────┬────────┬──────────┐│Neutron│┌────────┬──────────┬──────────┐│Electron││
│    ││      ││Up Quark│Up Quark│Down Quark││       ││Up Quark│Down Quark│Down Quark││        ││
│    ││      │└────────┴────────┴──────────┘│       │└────────┴──────────┴──────────┘│        ││
│    │└──────┴──────────────────────────────┴───────┴────────────────────────────────┴────────┘│
└────┴─────────────────────────────────────────────────────────────────────────────────────────┘
      {1=≡⍺:⎕←⍺,⍨⍵↑1↓⍵/'->'⋄⍺∇¨⍵+1}∘0 ⊢ r 
>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Down Quark
-->Down Quark
->Electron

说明:

  • {... }∘0:运行以下功能并0绑定到
    • 1=≡⍺::如果输入的深度为1(即不包含其他数组的数组):
      • ⍵/'->':创建一个包含 -s和 >s 的字符串,
      • 1↓:删除第一个元素,
      • ⍵↑:并采用第一个元素。这将导致包含⍵-1破折号和一个的字符串>
      • ⍺,⍨:将输入追加到它,
      • ⎕←:并将其输出到屏幕
    • : 除此以外,
      • ⍺∇¨⍵+1:将1加到并将此函数应用于每个嵌套数组

5
等等,它以这种艺术形式接受输入吗?
Rɪᴋᴇʀ

4
@Riker:不,它需要一个普通的嵌套数组,但是这就是Dyalog APL显示嵌套数组的方式,并且(我认为)这使正在发生的事情显而易见。您可以通过编写eg构造它('Atom' ('Proton' ('Up Quark' 'Up Quark' 'Down Quark') 'Neutron' ('Up Quark' 'Down Quark' 'Down Quark') 'Electron'))
马里纳斯(Marus)

9
啊好吧。这样就清除了。现在有点失望的,虽然....
Rɪᴋᴇʀ


7

Mathematica,58 57 56字节

感谢Greg Martin节省了1个字节。

感谢ngenisis节省了1个字节。

MapIndexed[Print[Table["-",Tr[1^#2]-1]<>">",#]&,#,{-1}]&

47
欢迎来到PPCG!您应该知道,很少或没有解释的答案会被系统自动标记,并最终进入“低质量审核队列”。那可能会删除您的答案。请注意,如果您有几个已删除的答案,则可能会被暂时停职。只是一点头!
Stewie Griffin

20
@StewieGriffin感谢您的热情欢迎,我会记住这一点!
Martin Ender

6
@StewieGriffin您欢迎sitemod吗?这里发生了什么?这是内心的笑话吗?#confused如果你们在北方,那对你们来说是美好的春天。
Mindwin

4
@Mindwin:Stack Exchange的过滤器旨在捕获不太有用的答案。这种帖子(标题+简短代码示例,无评论)极有可能导致误报,因为它看起来很像是费力的发布到计算机上的帖子(而Stewie Griffin的评论包含指向屏幕截图的链接,该链接指示实际上确实发生了误报;这是在嘲笑这种情况)。是另一个帖子被过滤器捕获的示例。

8
@Titus我想添加一个,但我不想使Stewie的评论无效。:(
马丁·恩德

6

Java 7中,153个 141 114字节

String r="";<T,S>S c(S s,T o){for(T x:(T[])o)if(x instanceof Object[])c("-"+s,x);else r+=s+">"+x+"\n";return(S)r;}

-39字节感谢@ Barteks2x

说明:

String r="";                         // Result String outside the method / on class-level
<T,S> S c(S s, T o){                 // Recursive Method with generic String and Object parameters and String return-type
  for(T x : (T[])o)                  //  Loop over the input-array
    if(x instanceof Object[])        //   If the current item is an array itself:
      c("-"+s, x);                   //    Recursive method-call with this array
    else                             //   Else:
      r += s+">"+x+"\n";             //    Append return-String with stripes String-input, ">", current item, and a new-line
                                     //  End of loop (implicit / single-line body)
  return (S)r;                       //  Return the result-String
}                                    // End of method

测试代码:

在这里尝试。

class M{
  String r="";<T,S>S c(S s,T o){for(T x:(T[])o)if(x instanceof Object[])c("-"+s,x);else r+=s+">"+x+"\n";return(S)r;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c("", new Object[]{new Object[]{1,2},new Object[]{new Object[]{1,2},3},4,new Object[]{new Object[]{new Object[]{new Object[]{5}}}},6}));
    m.r = "";
    System.out.println(m.c("", new Object[]{"Atom",new Object[]{"Proton",new Object[]{"Up Quark","Up Quark","Down Quark"}},new Object[]{"Neutron",new Object[]{"Up Quark","Up Quark","Down Quark"}},"Electron"}));
  }
}

输出:

->1
->2
-->1
-->2
->3
>4
---->5
>6

>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Up Quark
-->Down Quark
>Electron

1
通过使用三元运算符for(int j=i;j-->0;r+="-");也可以执行下一行的操作,并使用通用参数代替Object [],可以使它略短一些(143甚至142): String r="";<T>String c(int i,T[] o){for(T x:o)if(x instanceof Object[])c(i+1,(T[])x);else for(int j=i;j-->=0;r+=j<0?">"+x+"\n":"-");return r;} 如果将1而不是0传递给第一个,则甚至少了1个字符争论还可以。
barteks2x

我找到了一种方法,可以通过从通用参数中删除[]来使其更短,它可以节省额外的2个字符(但在超过5分钟后无法编辑注释)
barteks2x

@ Barteks2x谢谢!-12个字节感谢您。:)顺便说一句,[]从参数中删除以保存1个额外的字节会产生错误。运行后,请在>调试中查看此处的错误。
Kevin Cruijssen

String r="";<T>String c(int i,T a){for(T x:(T[])a)if(x instanceof Object[])c(i+1,x);else for(int j=i;j-->0;r+=j<1?">"+x+"\n":"-");return r;}这可行。您也可以使用字符串执行类似的通用技巧,以节省一个字节,但需要在打印之前将结果存储在变量中,或进行显式转换(模糊方法调用):String r="";<T,S>S c(int i,T a){for(T x:(T[])a)if(x instanceof Object[])c(i+1,x);else for(int j=i;j-->0;r+=j<1?">"+x+"\n":"-");return(S)r;}
barteks2x

1
我不确定是否允许这样做,但是这里有114个字节,空字符串作为参数而不是零(如果允许“>”作为参数,则可以少1个字符),String r="";<T,S>S c(S p,T a){for(T x:(T[])a)if(x instanceof Object[])c("-"+p,x);else r+=p+">"+x+"\n";return(S)r;}并且在调用时对返回类型强制转换为字符串它不见了。
barteks2x

6

PHP,77 74 73字节

感谢@manatwork,节省了4个字节。

function f($a,$p=">"){foreach($a as$e)"$e"!=$e?f($e,"-$p"):print"$p$e
";}

递归函数,需要PHP 7.1或更高版本作为负字符串索引。
"$e"Array用于阵列; 所以"$e"!=$e和一样is_array($e)

  • 以前缀开头 >
  • -在每个级别的前缀前面加上a
  • 打印原子的前缀+元素+换行符

1
75个字节:function f($a,$p=""){foreach($a as$e)echo$p,is_array($e)?f($e,"-"):">$e\n";}
Ismael Miguel

1
如果不是必需的格式,print_r($ array)会更小:)
ivanivan

1
只是做了一个快速测试,但似乎is_array($e)可以用代替$e[-1]!==""
manatwork'Mar

1
@manatwork这是PHP 7.1中的PHP <7.1 ...,可以通过$e[-]==""...并以相反的条件完成$e[-1]>""。好发现!
泰特斯(Titus),

1
也许我想念一些特殊情况,但目前看来$e[-1]>""可以替换为"$e"==$e。至少在我使用的古老PHP 5.6中。
manatwork

5

C99(GCC),201 187 140 112 109

f(char*a){for(long d=1,j;j=d+=*++a>90?92-*a:0;)if(*a<35){for(;j||*++a^34;)putchar(j?"->"[!--j]:*a);puts("");}}

展开形式:

f(char*a){
    for(long d=1,j;j=d+=*++a>90?92-*a:0;)
        if(*a<35){
            for(;j||*++a^34;)putchar(j?--j?45:62:*a);
            puts("");
        }
}

这将采用正确格式的字符串,并在找到最后一个匹配项时终止 ]

它不使用递归,而是使用长类型来实际实现第二条规则:2 ^ 32-1级别。大多数脚本语言的递归深度有限,或者仅在堆栈溢出时崩溃。

我不习惯在C中打高尔夫球,不胜感激:)

感谢bolov的提示!特别要感谢提多(Titus),他一直努力打好高尔夫(即使在C中)!

我们可以在匹配最后一个]并且不需要匹配null字符的情况下完成操作,从而节省了另外两个字节。

可以在Wandbox上进行测试。



您可以将第二行缩短到for(int d=1 ...吗?long包含4个字符,而int只有3 个字符,并且没有理由需要使它超过才可以使2^32 - 1提交有效,从而节省了一个字节。
Restioson

@Restioson int是带符号的,因此仅适用于2^31-1
克里斯多夫(Christoph)

@Christoph说,你没有挑战去任何进一步不止于此。
Restioson

@Restioson挑战状态为规则The maximum level of "layers" is 2^32-1.2^31-1比少了很多2^32-12^32-1int适合使用unsignedor或long(适合大多数系统/编译器)的时间。因此int不会做出正确的答案(就像这里的大多数答案都无法做到)。
克里斯多夫(Christoph)

4

JavaScript(ES6),58 51字节

f=(a,s='>')=>a.map(e=>e.map?f(e,'-'+s):s+e).join`
`

编辑:@Arnauld指出我可以结合两种方法时,节省了7个字节。


4

PHP,129123112109 109 95 93 91字节

for(;a&$c=$argn[++$i];)$c<A?$c<"-"?a&$s?$s=!print"$p>$s
":0:$s.=$c:$p=substr("---$p",$c^i);

迭代解决方案取自STDIN的字符串:
使用echo '<input>' | php -nR '<code>'在线对其进行测试

分解

for(;a&$c=$argn[++$i];)     // loop $c through input characters
    $c<A                        // not brackets?
        ?$c<"-"                     // comma or quote?
            ?a&$s?$s=!print"$p>$s\n":0  // if $s not empty, print and clear $s
            :$s.=$c                     // digit: append to $s
        :$p=substr("---$p",$c^i)    // prefix plus or minus one "-"
;

很高兴这些数字都用引号引起来;所以我一次只需要做一个动作。

ASCII摆弄

char    ascii   binary/comment
 "       34
 ,       44
 [       91     0101 1011
 ]       93     0101 1101

 A       65     $c<A    true for comma, quote and digits
 -       45     $c<"-"  true for comma and quote

                =0011 1010 -> 50 -> "2"
i^"["   105^91  ^0101 1011
 i      105      0110 1001
i^"]"   105^93  ^0101 1101
                =0011 0100 -> 52 -> "4"

加入3个破折号$p和用于去除2 [为,4 ]增加了一个用于[并删除一个用于]



4

Python 2,65 64字节

f=lambda o,d=0:o<''and'\n'.join(f(e,d+1)for e in o)or'-'*d+'>'+o

现在,我的答案始终以破折号开头,因此["foo", "bar"]

>foo
>bar

import sys, pprint; pprint.pprint(sys.argv)是43个字节,但我不知道它是否违反了高尔夫规则。
卡雷尔

这样可以节省一个字节:f=lambda o,d=0:o<''and'\n'.join(f(e,d+1)for e in o)or'-'*d+'>'+o
Ben Frankel

@Carel你不能做“进口pprint为p”也许(不知道这作品)(似乎上帝,我无法找到我的手机键盘上的反勾)“进口pprint.pprint为p”
科尔

@Cole Hmm .. import sys, pprint.pprint as p; p(sys.argv)仍然是43,但仍然是一个很好的建议; D尝试import sys.argv as v实际上将其延长了约48个字节。如果可以消除sys.argv,他们可以节省很多,但是该程序将变得毫无用处。递归方法相当长,def p(L,d=0): [p(i,d+1) if isinstance(i,list) else print(">"*d + i) for i in L]〜80个字节。
卡雷尔

3

Perl 5、55个字节

53个字节的代码+ -nl标志。

/"/?print"-"x~-$v.">$_":/]/?$v--:$v++for/]|\[|".*?"/g

在线尝试!

对于正则表达式不是最佳选择,因为可能会发生某些前卫情况(特别是如果数组的元素内部包含方括号)。
但是,递归匿名函数几乎不会更长(61个字节):

sub f{my$v=pop;map{ref?f(@$_,$v+1):"-"x$v.">$_"}@_}sub{f@_,0}

在线尝试!

但是Perl处理参数的方式对于高尔夫功能并不是最佳的:没有可选参数意味着我必须做第二个函数(匿名)来调用第一个函数,并且我必须显式地获取具有那么长的最后一个参数my$v=pop


3

Ruby,49 45 46字节

f=->c,p=?>{c.map{|x|x==[*x]?f[x,?-+p]:p+x}*$/}

例:

puts f[["Atom",["Proton",["Up Quark", "Up Quark", "Down Quark"], "Neutron", ["Up Quark", "Down Quark", "Down Quark"], "Electron"]]]

>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Down Quark
-->Down Quark
->Electron

说明:

递归函数:如果x==[*x]x是一个数组,我们对其进行迭代。如果不是,则缩进。


3

Haskell,104个字节

l@(x:y)#(a:m)|[(h,t)]<-reads$a:m=y++h++l#t|a<'#'=l#m|a<'-'='\n':l#m|a>'['=y#m|q<-'-':l=q#m
l#_=""
(">"#)

Haskell没有具有不同深度的嵌套列表,因此我必须自己解析输入字符串。幸运的是,库函数reads可以解析字符串(即- "封闭的char序列),因此在这里我有一点帮助。

用法示例:

*Main> putStrLn $ (">"#) "[[\"1\",\"2\"],[\"3\",\"4\"]]" 
->1
->2
->3
->4

在线尝试!

怎么运行的:

该函数#逐个字符地遍历字符串char,并将嵌套级别(第一个参数l)保持为-带final 的字符串>。如果可以将列表的开头解析为字符串,请先获取l和,然后进行递归调用,并删除该字符串。如果第一个字符是一个空格,请跳过它。如果是,,请换行并继续,如果是],则降低嵌套级别并继续,否则(仅[左)提高嵌套级别并继续。递归以空的输入字符串结束。main函数(">"#)将嵌套级别设置为">"#


2

SWI-Prolog,115字节

p(L):-p(L,[>]).
p([],_):-!.
p([H|T],F):-p(H,[-|F]),p(T,F),!.
p(E,[_|F]):-w(F),w([E]),nl.
w([]).
w([H|T]):-write(H),w(T).

添加换行符只是为了提高可读性,不包括在字节数中。

p谓词递归遍历数组,F在将级别更深时将前缀添加“-” 。w用于将前缀数组以及实际元素写入输出。

例:

?- p(["Atom",["Proton",["Up Quark", "Up Quark", "Down Quark"], "Neutron", ["Up Quark", "Down Quark", "Down Quark"], "Electron"]]).
>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Down Quark
-->Down Quark
->Electron

2

批次,249个字节

@echo off
set/ps=
set i=
:t
set t=
:l
set c=%s:~,1%
set s=%s:~1%
if "%c%"=="[" set i=-%i%&goto l
if not "%c%"=="]" if not "%c%"=="," set t=%t%%c%&goto l
if not "%t%"=="" echo %i:~1%^>%t%
if "%c%"=="]" set i=%i:~1%
if not "%s%"=="" goto t

令人讨厌的是,批处理在比较逗号时遇到麻烦。样品运行:

[Atom,[Proton,[Up Quark,Up Quark,Down Quark],Neutron,[Up Quark,Down Quark,Down Quark],Electron]]
>Atom
->Proton
-->Up Quark
-->Up Quark
-->Down Quark
->Neutron
-->Up Quark
-->Down Quark
-->Down Quark
->Electron

2

视网膜63 54 52字节

感谢Martin Ender,节省了2个字节

.*?".*?"
$`$&¶
T`[] -~`-]_`.(?=.*".*")
-]

-"
>
T`]"

在线尝试!

说明

.*?".*?"
$`$&¶

首先,通过将每个用引号引起来的字符串替换为其之前的所有内容,自身和换行符来分解数组。通过这样分解,可以在每根弦之前找到不匹配的开括号。

T`[] -~`-]_`.(?=.*".*")

此音译将替换[-]保持不变,并删除其他 -~所有字符(均为可打印的ASCII)。但是,它仅替换每行最后一个字符串之前出现的字符。

-]

接下来,-]将删除的所有实例。这些对应于匹配的括号对,我们只需要不匹配的括号。删除这些行之后,每行的-s 数等于之前有多少个不匹配的左括号。

-"
>

-a之前的最后一个"替换为>,以形成箭头。

T`]"

最后,删除所有剩余]的和"


看起来它假设字符串中不会包含(转义)引号。我不确定这是否合法,但已要求澄清。
Martin Ender

@MartinEnder好收获,我会密切关注
商务猫

1

罗达(Röda),54个字节

f d=""{{|n|{n|f d=`$d-`}if[n is list]else[`$d>$n
`]}_}

在线尝试!

这个函数从流中读取输入数组。对于每个项目,它要么递归调用自身,要么打印该项目。


1

Python 3,80字节

似乎Python的lambda支持递归,谁知道呢?

p=lambda l,d=1:[p(i,d+1)if isinstance(i,list)else print("-"*d+">"+i)for i in l]

这是对orlp答案回应/补充。


欢迎来到PPCG!看来您已经计入了尾随换行符或其他内容(因为我只计了80个字节),并且不需要在空格=。我还怀疑您可以在这三个位置之后放掉所有空格),但是我对Python打高尔夫球不是很熟悉。
Martin Ender

0

Groovy,92个字节

x={a,b->if(a instanceof List){a.each{x(it,b+1)}}else{y(a,b)}};y={a,b->println("-"*b+">$a")};


0

Gema,63个字符

\A=@set{i;-1}
[=@incr{i}
]=@decr{i}
"*"=@repeat{$i;-}>*\n
,<s>=

像其他解析解决方案一样,假定字符串中不会有转义的双引号。

样品运行:

bash-4.3$ gema '\A=@set{i;-1};[=@incr{i};]=@decr{i};"*"=@repeat{$i;-}>*\n;,<s>=' <<< '[["1","2"],[["1","2"],"3"],"4",[[[["5"]]]],"6"]'
->1
->2
-->1
-->2
->3
>4
---->5
>6

0

智商70 67个字符

67 64个字符的代码+ 3个字符的命令行选项)

def f(i):if type=="array"then.[]|f("-"+i)else i+. end;.[]|f(">")

样品运行:

bash-4.3$ jq -r 'def f(i):if type=="array"then.[]|f("-"+i)else i+. end;.[]|f(">")' <<< '[["1","2"],[["1","2"],"3"],"4",[[[["5"]]]],"6"]'
->1
->2
-->1
-->2
->3
>4
---->5
>6

在线测试

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.