制作一个宏,使输入字符串成为行数组的内容

制作一个宏,使输入字符串成为行数组的内容

我正在尝试创建一个宏,在输入string(其中的n长度为string)时,它将创建一个数组,该数组将手动由

\begin{array}{ccc... % n c's here}
    string[0] & string[1] & string[2] & ... & string[n-1]
\end{array}

例如,输入12345应该给出

\begin{array}{ccccc}
    1 & 2 & 3 & 4 & 5
\end{array}

我尽了最大努力,做出了以下尝试

\documentclass{article}
\usepackage{xstring, etoolbox, pgffor}

\newcommand{\cycle}[1]{%
    \def\mystring{{#1}}
    \StrLen{\mystring}[\mystringlen]
    \def\columns{c}
    \def\content{\empty}
    \foreach \x in {0,...,\mystringlen - 1} {%
        \appto\columns{c}
        \appto\content{\StrMid{\mystring}{\x}{\x + 1} \& }
    }
    \appto\content{\StrMid{\mystring}{\mystringlen - 1}{\mystringlen}}

    \begin{array}{\columns} \content \end{array}
}

\begin{document}
$\cycle{12345}$
\end{document}

以及大量错误。我对这种深度的 LaTeX 还不熟悉,所以如果有人能告诉我这个特定示例有什么问题、更好的方法和/或我应该查看的相关资料,我将不胜感激。提前致谢。

答案1

\documentclass{article}

\makeatletter
\def\cycle#1{\xcycle{}{\@gobble}#1\relax}
\def\xcycle#1#2#3{%
\ifx\relax#3%
\begin{array}{#1}#2\end{array}%
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
{\xcycle{#1c}{#2&#3}}}
\makeatother

\begin{document}
$\cycle{12345}$
\end{document}

在此处输入图片描述

或者使用egreg的扩展要求:

在此处输入图片描述

\documentclass{article}

\makeatletter
\def\cycle#1{\xcycle{}{\@gobble}#1\relax}
\def\xcycle#1#2#3{%
\ifx\relax#3%
\begin{array}{@(#1@)}#2\end{array}%
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
{\xcycle{#1c}{#2&#3}}}

\def\permutation#1{\xpermutation{}{\@gobble}#1\relax}
\def\xpermutation#1#2#3{%
\ifx\relax#3%
\begin{array}{@(#1@)}#2\end{array}%
\expandafter\@gobbletwo
\else
\ifx;#3%
\expandafter\expandafter\expandafter\@secondoftwo
\else
\expandafter\expandafter\expandafter\@firstoftwo
\fi\fi
{\xpermutation{#1c}{#2&#3}}{\xpermutation{#1@{}c@{}}{#2&)(}}%
}


\makeatother

\begin{document}
$\cycle{12345}$

$\permutation{12;34;567}$

\end{document}

答案2

我建议采用基于expl3和的方法xparse

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\cycle}{m}
 {
  % split at "nothing"
  \seq_set_split:Nnn \l_egreg_cycle_seq { } { #1 }
  % the sequence length can be used to set the number of columns
  \begin{array}{* { \seq_count:N \l_egreg_cycle_seq } { c } }
  % use the sequence
  \seq_use:Nn \l_egreg_cycle_seq { & }
  \end{array}
}
\seq_new:N \l_egreg_cycle_seq
\ExplSyntaxOff

\begin{document}

X$\cycle{12345}$X

\end{document}

在此处输入图片描述

您可以轻松地改进这一点,使用舒适的语法将排列打印为不相交的循环:

\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath}

\ExplSyntaxOn
\NewDocumentCommand{\cycle}{m}
 {
  \egreg_cycle:n { #1 }
 }
\NewDocumentCommand{\permutation}{m}
 {
  \egreg_permutation:n { #1 }
 }

\seq_new:N \l_egreg_permutation_seq
\seq_new:N \l_egreg_cycle_seq

\cs_new_protected:Nn \egreg_permutation:n
 {
  % split the input at semicolons
  \seq_set_split:Nnn \l_egreg_permutation_seq { ; } { #1 }
  % map the obtained sequence passing each item to \egreg_cycle:n
  \seq_map_inline:Nn \l_egreg_permutation_seq
   {
    \egreg_cycle:n { ##1 }
   }
 }
\cs_new_protected:Nn \egreg_cycle:n 
 {
  % split at "nothing"
  \seq_set_split:Nnn \l_egreg_cycle_seq { } { #1 }
  % use the sequence; no array needed, just spacing in the middle
  (\seq_use:Nn \l_egreg_cycle_seq { \mspace{6mu} })
 }

\ExplSyntaxOff

\begin{document}

$\cycle{12345}$

$\permutation{12;34;567}$

\end{document}

在此处输入图片描述

相关内容