\pgfmatharray{\a}{0}、\pgfmathparse{\a[0]} 和 \pgfmathparse{array(\a, 0)} 之间的区别

\pgfmatharray{\a}{0}、\pgfmathparse{\a[0]} 和 \pgfmathparse{array(\a, 0)} 之间的区别

至少有 4 种不同的方法(在代码中)可以访问列表/数组中的项。出于好奇,我想看看不同的组合会发生什么。我选择了 6 种不同的输入场景(在代码中)并对其进行了 2 级深度测试。这意味着可能进行 4*4*6=96 次测试。

\documentclass{standalone}
\usepackage{tikz}
\usepackage{ifthen}
\begin{document}

\message{^^J}

\begin{tikzpicture}
  \def \A {{{{9, 8, 7}}, {{6, 5}}}}
  \def \B {{{9, 8, 7}, {6, 5}}}
  \def \C {{9, 8, 7}}
  \def \D {{{9, 8, 7}}, {{6, 5}}}
  \def \E {{9, 8, 7}, {6, 5}}
  \def \F {9, 8, 7}

  \def \tests#1#2#3
  {
    \begingroup
    \edef \depth {3.0}
    \edef \olddepth {#3}
    \def \arecurse {0}
    \def \brecurse {0}
    \def \crecurse {0}
    \def \drecurse {0}

    \pgfmathparse{\olddepth + 1}
    \edef\newdepth{\pgfmathresult}

    \ifthenelse{\equal{\newdepth}{\depth}}{}
    {
      \message{input (#1):}
      \message{#2 ^^J}

      %% a
      \message{ foreach (#1+a):}
      \foreach \x in #2
      {
        \xdef \aa {\x}
        \message{\aa ^^J}
        \breakforeach
      }

      %% b
      \message{ pgfmatharray (#1+b):}
      \pgfmatharray{#2}{0}
      \edef \bb {\pgfmathresult}
      \message{\bb ^^J}

      %% c
      \message{ pgfmathparse + index (#1+c):}
      \ifthenelse{\equal{#1}{Ba} \or
                  \equal{#1}{Da} \or
                  \equal{#1}{F}}
      {
        \def \crecurse {1}
        \message{Error ^^J}
      }{
        \pgfmathparse{#2[0]}
        \edef \cc {\pgfmathresult}
        \message{\cc ^^J}
      }

      %% d
      \message{ pgfmathparse + array (#1+d):}
      \ifthenelse{\equal{#1}{Ad} \or
                  \equal{#1}{Ba} \or
                  \equal{#1}{Bd} \or
                  \equal{#1}{D} \or
                  \equal{#1}{Da} \or
                  \equal{#1}{E} \or
                  \equal{#1}{F}}
      {
        \def \drecurse {1}
        \message{Error ^^J}
      }{
        \pgfmathparse{array(#2, 0)}
        \edef \dd {\pgfmathresult}
        \message{\dd ^^J}
      }

      \ifthenelse{\arecurse = 0}{\tests{#1a}{\aa}{\newdepth}}{}
      \ifthenelse{\brecurse = 0}{\tests{#1b}{\bb}{\newdepth}}{}
      \ifthenelse{\crecurse = 0}{\tests{#1c}{\cc}{\newdepth}}{}
      \ifthenelse{\drecurse = 0}{\tests{#1d}{\dd}{\newdepth}}{}
    }
    \endgroup
  }

  \tests{A}{\A}{0.0}
  \tests{B}{\B}{0.0}
  \tests{C}{\C}{0.0}
  \tests{D}{\D}{0.0}
  \tests{E}{\E}{0.0}
  \tests{F}{\F}{0.0}
\end{tikzpicture}
\end{document}

在输出中,可以从括号内的字符串推断出执行的操作。例如,(Aa+b)(Aab)表示使用输入A:{{{{9, 8, 7}}, {{6, 5}}}}/foreach选择第一项,然后选择选择第一项。某些组合会产生错误,因此代码\pgfmatharray会跳过这些组合以完成。\ifthenelse

有一些有趣的结果。我知道有些输入是令人讨厌的,但好奇心让我问为什么这些特定的东西会产生输出?

foreach工作相当稳定

input:                        foreach:
(A): {{{9, 8, 7}}, {{6, 5}}}  (A+a): {{9, 8, 7}}, {{6, 5}}
(Aa): {{9, 8, 7}}, {{6, 5}}   (Aa+a): {9, 8, 7}
(Ab): {9}{8}{7}               (Ab+a): {9}{8}{7}
(Ac): {{9}{8}{7}}             (Ac+a): {9}{8}{7}
(Ad): {9}{8}{7}               (Ad+a): {9}{8}{7}
(B): {{9, 8, 7}, {6, 5}}      (B+a): {9, 8, 7}, {6, 5}
(Ba): {9, 8, 7}, {6, 5}       (Ba+a): 9, 8, 7
(Bb): {9}{8}{7}               (Bb+a): {9}{8}{7}
(Bc): {{9}{8}{7}}             (Bc+a): {9}{8}{7}
(Bd): {9}{8}{7}               (Bd+a): {9}{8}{7}
(C): {9, 8, 7}                (C+a): 9, 8, 7
(Ca): 9, 8, 7                 (Ca+a): 9
(Cb): 9                       (Cb+a): 9
(Cc): 9                       (Cc+a): 9
(Cd): 9                       (Cd+a): 9                   
(D): {{9, 8, 7}}, {{6, 5}}    (D+a): {9, 8, 7}
(Da): {9, 8, 7}               (Da+a): 9, 8, 7
(Db): {9}{8}{7}               (Db+a): {9}{8}{7}
(Dc): {{9}{8}{7}}{{6}{5}}     (Dc+a): {{9}{8}{7}}{{6}{5}}
(E): {9, 8, 7}, {6, 5}        (E+a): 9, 8, 7
(Ea): 9, 8, 7                 (Ea+a): 9
(Eb): {9}{8}{7}               (Eb+a): {9}{8}{7}
(Ec): {{9}{8}{7}}{6}          (Ec+a): {{9}{8}{7}}{6}
(F): 9, 8, 7                  (F+a): 9
(Fa): 9                       (Fa+a): 9
(Fb): 9                       (Fb+a): 9

工作方式之间存在明显差异pgfmath*pgfmatharraypgfmathparse + array显然彼此接近。后者似乎偶尔会堵塞,因此前者更受欢迎。

pgfmathparse + index显然是例外。它看起来有些不一致,例如 (E+c) 的情况。

结果为 5、6 或 7 的情况很有趣。如果在尝试访问第一个元素时返回任何内容,为什么要返回最后一个元素?看起来宏解析了输入并仅返回剩下的最后一个项。

各个版本之间为什么会有这么大的差异呢pgfmath*

有趣的问题是使用哪一个?即使输入合理,它们显然也会返回不同的东西。

input:                        pgfmatharray:     pgfmathparse + array:   pgfmathparse + index:
(A): {{{9, 8, 7}}, {{6, 5}}}  (A+b): {9}{8}{7}  (A+d): {9}{8}{7}        (A+c): {{9}{8}{7}}
(Aa): {{9, 8, 7}}, {{6, 5}}   (Aa+b): 9         (Aa+d): 9               (Aa+c): 9
(Ab): {9}{8}{7}               (Ab+b): 7         (Ab+d): 7               (Ab+c): 7
(Ac): {{9}{8}{7}}             (Ac+b): 7         (Ac+d): 7               (Ac+c): 7
(Ad): {9}{8}{7}               (Ad+b): 7         (Ad+d): Error           (Ad+c): 7
(B): {{9, 8, 7}, {6, 5}}      (B+b): {9}{8}{7}  (B+d): {9}{8}{7}        (B+c): {{9}{8}{7}}
(Ba): {9, 8, 7}, {6, 5}       (Ba+b): 9         (Ba+d): Error           (Ba+c): Error
(Bb): {9}{8}{7}               (Bb+b): 7         (Bb+d): 7               (Bb+c): 7
(Bc): {{9}{8}{7}}             (Bc+b): 7         (Bc+d): 7               (Bc+c): 7
(Bd): {9}{8}{7}               (Bd+b): 7         (Bd+d): Error           (Bd+c): 7
(C): {9, 8, 7}                (C+b): 9          (C+d): 9                (C+c): 9
(Ca): 9, 8, 7                 (Ca+b): 9         (Ca+d): 9               (Ca+c): 9
(Cb): 9                       (Cb+b): 9         (Cb+d): 9               (Cb+c): 9
(Cc): 9                       (Cc+b): 9         (Cc+d): 9               (Cc+c): 9
(Cd): 9                       (Cd+b): 9         (Cd+d): 9               (Cd+c): 9
(D): {{9, 8, 7}}, {{6, 5}}    (D+b): {9}{8}{7}  (D+d): Error            (D+c): {{9}{8}{7}}{{6}{5}}
(Da): {9, 8, 7}               (Da+b): 9         (Da+d): Error           (Da+c): Error
(Db): {9}{8}{7}               (Db+b): 7         (Db+d): 7               (Db+c): 7
(Dc): {{9}{8}{7}}{{6}{5}}     (Dc+b): 5         (Dc+d): 5               (Dc+c): 5
(E): {9, 8, 7}, {6, 5}        (E+b): {9}{8}{7}  (E+d): Error            (E+c): {{9}{8}{7}}{6}
(Ea): 9, 8, 7                 (Ea+b): 9         (Ea+d): 9               (Ea+c): 9
(Eb): {9}{8}{7}               (Eb+b): 7         (Eb+d): 7               (Eb+c): 7
(Ec): {{9}{8}{7}}{6}          (Ec+b): 6         (Ec+d): 6               (Ec+c): 6
(F): 9, 8, 7                  (F+b): 9          (F+d): Error            (F+c): Error
(Fa): 9                       (Fa+b): 9         (Fa+d): 9               (Fa+c): 9
(Fb): 9                       (Fb+b): 9         (Fb+d): 9               (Fb+c): 9

相同的输入应该得到相同的结果。当输入排序时,这些结果会脱颖而出。那里一定有事情发生。

input:                        pgfmatharray:     pgfmathparse + array:   pgfmathparse + index:
(Ca): 9, 8, 7                 (Ca+b): 9         (Ca+d): 9               (Ca+c): 9
(Ea): 9, 8, 7                 (Ea+b): 9         (Ea+d): 9               (Ea+c): 9
(F): 9, 8, 7                  (F+b): 9          (F+d): Error            (F+c): Error

(C): {9, 8, 7}                (C+b): 9          (C+d): 9                (C+c): 9
(Da): {9, 8, 7}               (Da+b): 9         (Da+d): Error           (Da+c): Error

(Ba): {9, 8, 7}, {6, 5}       (Ba+b): 9         (Ba+d): Error           (Ba+c): Error
(E): {9, 8, 7}, {6, 5}        (E+b): {9}{8}{7}  (E+d): Error            (E+c): {{9}{8}{7}}{6}

(Ab): {9}{8}{7}               (Ab+b): 7         (Ab+d): 7               (Ab+c): 7
(Bb): {9}{8}{7}               (Bb+b): 7         (Bb+d): 7               (Bb+c): 7
(Db): {9}{8}{7}               (Db+b): 7         (Db+d): 7               (Db+c): 7
(Eb): {9}{8}{7}               (Eb+b): 7         (Eb+d): 7               (Eb+c): 7
(Ad): {9}{8}{7}               (Ad+b): 7         (Ad+d): Error           (Ad+c): 7
(Bd): {9}{8}{7}               (Bd+b): 7         (Bd+d): Error           (Bd+c): 7

(Aa): {{9, 8, 7}}, {{6, 5}}   (Aa+b): 9         (Aa+d): 9               (Aa+c): 9
(D): {{9, 8, 7}}, {{6, 5}}    (D+b): {9}{8}{7}  (D+d): Error            (D+c): {{9}{8}{7}}{{6}{5}}

(Ec): {{9}{8}{7}}{6}          (Ec+b): 6         (Ec+d): 6               (Ec+c): 6
(Eca): {{9}{8}{7}}{6}         (Eca+b): 6        (Eca+d): Error          (Eca+c): 6

原始输出

input (A): {{{9, 8, 7}}, {{6, 5}}}
 foreach (A+a): {{9, 8, 7}}, {{6, 5}}
 pgfmatharray (A+b): {9}{8}{7}
 pgfmathparse + index (A+c): {{9}{8}{7}}
 pgfmathparse + array (A+d): {9}{8}{7}
input (Aa): {{9, 8, 7}}, {{6, 5}}
 foreach (Aa+a): {9, 8, 7}
 pgfmatharray (Aa+b): 9
 pgfmathparse + index (Aa+c): 9
 pgfmathparse + array (Aa+d): 9
input (Ab): {9}{8}{7}
 foreach (Ab+a): {9}{8}{7}
 pgfmatharray (Ab+b): 7                           % 1. Why last?
 pgfmathparse + index (Ab+c): 7                   % 1. Why last?
 pgfmathparse + array (Ab+d): 7                   % 1. Why last?
input (Ac): {{9}{8}{7}}
 foreach (Ac+a): {9}{8}{7}
 pgfmatharray (Ac+b): 7                           % 1. Why last?
 pgfmathparse + index (Ac+c): 7                   % 1. Why last?
 pgfmathparse + array (Ac+d): 7                   % 1. Why last?
input (Ad): {9}{8}{7}
 foreach (Ad+a): {9}{8}{7}
 pgfmatharray (Ad+b): 7                           % 1. Why last?
 pgfmathparse + index (Ad+c): 7                   % 1. Why last?
 pgfmathparse + array (Ad+d): Error               % 2. Why differ from (Ab+d)?
input (B): {{9, 8, 7}, {6, 5}}
 foreach (B+a): {9, 8, 7}, {6, 5}
 pgfmatharray (B+b): {9}{8}{7}
 pgfmathparse + index (B+c): {{9}{8}{7}}
 pgfmathparse + array (B+d): {9}{8}{7}
input (Ba): {9, 8, 7}, {6, 5}
 foreach (Ba+a): 9, 8, 7
 pgfmatharray (Ba+b): 9
 pgfmathparse + index (Ba+c): Error
 pgfmathparse + array (Ba+d): Error
input (Bb): {9}{8}{7}
 foreach (Bb+a): {9}{8}{7}
 pgfmatharray (Bb+b): 7                           % 1. Why last?
 pgfmathparse + index (Bb+c): 7                   % 1. Why last?
 pgfmathparse + array (Bb+d): 7                   % 1. Why last?
input (Bc): {{9}{8}{7}}
 foreach (Bc+a): {9}{8}{7}
 pgfmatharray (Bc+b): 7                           % 1. Why last?
 pgfmathparse + index (Bc+c): 7                   % 1. Why last?
 pgfmathparse + array (Bc+d): 7                   % 1. Why last?
input (Bd): {9}{8}{7}
 foreach (Bd+a): {9}{8}{7}
 pgfmatharray (Bd+b): 7                           % 1. Why last?
 pgfmathparse + index (Bd+c): 7                   % 1. Why last?
 pgfmathparse + array (Bd+d): Error               % 2. Why differ from (Bb+d)?
input (C): {9, 8, 7}
 foreach (C+a): 9, 8, 7
 pgfmatharray (C+b): 9
 pgfmathparse + index (C+c): 9
 pgfmathparse + array (C+d): 9
input (Ca): 9, 8, 7
 foreach (Ca+a): 9
 pgfmatharray (Ca+b): 9
 pgfmathparse + index (Ca+c): 9
 pgfmathparse + array (Ca+d): 9
input (Cb): 9
 foreach (Cb+a): 9
 pgfmatharray (Cb+b): 9
 pgfmathparse + index (Cb+c): 9
 pgfmathparse + array (Cb+d): 9
input (Cc): 9
 foreach (Cc+a): 9
 pgfmatharray (Cc+b): 9
 pgfmathparse + index (Cc+c): 9
 pgfmathparse + array (Cc+d): 9
input (Cd): 9
 foreach (Cd+a): 9
 pgfmatharray (Cd+b): 9
 pgfmathparse + index (Cd+c): 9
 pgfmathparse + array (Cd+d): 9
input (D): {{9, 8, 7}}, {{6, 5}}
 foreach (D+a): {9, 8, 7}
 pgfmatharray (D+b): {9}{8}{7}
 pgfmathparse + index (D+c): {{9}{8}{7}}{{6}{5}}
 pgfmathparse + array (D+d): Error                % 3. Why differ from (D+c)?
input (Da): {9, 8, 7}
 foreach (Da+a): 9, 8, 7
 pgfmatharray (Da+b): 9
 pgfmathparse + index (Da+c): Error
 pgfmathparse + array (Da+d): Error
input (Db): {9}{8}{7}
 foreach (Db+a): {9}{8}{7}
 pgfmatharray (Db+b): 7                           % 1. Why last?
 pgfmathparse + index (Db+c): 7                   % 1. Why last?
 pgfmathparse + array (Db+d): 7                   % 1. Why last?
input (Dc): {{9}{8}{7}}{{6}{5}}
 foreach (Dc+a): {{9}{8}{7}}{{6}{5}}
 pgfmatharray (Dc+b): 5                           % 1. Why last?
 pgfmathparse + index (Dc+c): 5                   % 1. Why last?
 pgfmathparse + array (Dc+d): 5                   % 1. Why last?
input (E): {9, 8, 7}, {6, 5}
 foreach (E+a): 9, 8, 7
 pgfmatharray (E+b): {9}{8}{7}
 pgfmathparse + index (E+c): {{9}{8}{7}}{6}       % 4. Strange. Why?
 pgfmathparse + array (E+d): Error                % 3. Why differ from (E+c)?
input (Ea): 9, 8, 7
 foreach (Ea+a): 9
 pgfmatharray (Ea+b): 9
 pgfmathparse + index (Ea+c): 9
 pgfmathparse + array (Ea+d): 9
input (Eb): {9}{8}{7}
 foreach (Eb+a): {9}{8}{7}
 pgfmatharray (Eb+b): 7                           % 1. Why last?
 pgfmathparse + index (Eb+c): 7                   % 1. Why last?
 pgfmathparse + array (Eb+d): 7                   % 1. Why last?
input (Ec): {{9}{8}{7}}{6}
 foreach (Ec+a): {{9}{8}{7}}{6}
 pgfmatharray (Ec+b): 6                           % 1. Why last?
 pgfmathparse + index (Ec+c): 6                   % 1. Why last?
 pgfmathparse + array (Ec+d): 6                   % 1. Why last?
input (F): 9, 8, 7
 foreach (F+a): 9
 pgfmatharray (F+b): 9
 pgfmathparse + index (F+c): Error
 pgfmathparse + array (F+d): Error
input (Fa): 9
 foreach (Fa+a): 9
 pgfmatharray (Fa+b): 9
 pgfmathparse + index (Fa+c): 9
 pgfmathparse + array (Fa+d): 9
input (Fb): 9
 foreach (Fb+a): 9
 pgfmatharray (Fb+b): 9
 pgfmathparse + index (Fb+c): 9
 pgfmathparse + array (Fb+d): 9

最长的无评论帖子是否有徽章?

答案1

不,但是最复杂的问题必须有一个徽章。我不知道为什么你需要递归来解决这个问题 :)


如果我没记错的话,无论有意还是无意,你都在侵入多维数组语法的中间步骤,例如,

\pgfmathparse{\A[0][0]}

在移动到下一个括号之前,先\A[0]渲染。但请注意,第二个括号应该是紧邻的。{9}{8}{7}

如果数组定义为具有多个维度,则可以立即重复数组访问运算符。

现在您可以说这并不好或有缺陷,我同意,但这是一个选择。因此,如果您不遵守它,结果显然会不一致。这排除了除索引符号之外的两者的嵌套使用。

还涉及一些堆栈操作。这是我没有准确检查的部分,但 pgfmath 的解析器有一些堆栈模拟。如果您推送结果标记并弹出顶部标记,它将是 7,尽管理论上 8 和 9 仍会存在。我没有时间对其进行解码,但您可以在 pgfmathparser.code.tex 的第 750 行左右进行检查。

我认为我们可以将您的案例归类为

“为什么最后”

这很可能是无效语法的推入弹出堆栈操作。

“为何不同于”

其实,这么长的文字,可以总结为为什么下面两行不同

\pgfmatharray{{9}{8}{7}}{0}\pgfmathresult\\           % Ad + b
\pgfmathparse{array({9}{8}{7},0)}\pgfmathresult\\     % Ad + d

这是第一个应该抛出错误但却没有抛出的错误。原因是内联解析有一个额外的操作数解析(也会去掉括号),并且它正确地看到那里没有逗号分隔的数组。另一个被欺骗了,因为解析被绕过了。另一个证据是

\pgfmathdim{{9}{8}{7}}

给出 1。所以它不是三元组。


稍后更多...

相关内容