如何放置大量括号

如何放置大量括号

我想显示由 {} [] () 组成的所有有效括号字符串。这是预期的输出:

{[()]}
{[]()}
{[]}()
{([])}
{()[]}
{()}[]
{}[()]
{}[]()
{}([])
{}()[]
[{()}]
[{}()]
[{}]()
[({})]
[(){}]
[()]{}
[]{()}
[]{}()
[]({})
[](){}
({[]})
({}[])
({})[]
([{}])
([]{})
([]){}
(){[]}
(){}[]
()[{}]
()[]{}

这是我做的:

\{[()]\}\\
\{[]()\}\\
\{[]\}()\\
\{([])\}\\
\{()[]\}\\
\{()\}[]\\
\{\}[()]\\
\{\}[]()\\
\{\}([])\\
\{\}()[]\\
[\{()\}]\\
[\{\}()]\\
[\{\}]()\\
[(\{\})]\\
[()\{\}]\\
[()]\{\}\\
[]\{()\}\\
[]\{\}()\\
[](\{\})\\
[]()\{\}\\
(\{[]\})\\
(\{\}[])\\
(\{\})[]\\
([\{\}])\\
([]\{\})\\
([])\{\}\\
()\{[]\}\\
()\{\}[]\\
()[\{\}]\\
()[]\{\}\

但是,其中一些会导致错误。知道为什么会发生这种情况吗?最好的解决方法是什么?

编辑:抱歉,没有贴出 MWE 和完整示例。这是我的旧.tex文件。注释掉的是导致错误的文件(!缺少数字,视为零。\protect):

\documentclass{article}
\begin{document}
   Lots of Brackets:\\
   \texttt{
      \{[()]\}\\
      \{[]()\}\\
      \{[]\}()\\
      \{([])\}\\
      \{()[]\}\\
      \{()\}[]\\
      \{\}[()]\\
      \{\}[]()\\
      \{\}([])\\
      \{\}()[]\\
      %[\{()\}]\\
      %[\{\}()]\\
      %[\{\}]()\\
      %[(\{\})]\\
      %[()\{\}]\\
      %[()]\{\}\\
      %[]\{()\}\\
      %[]\{\}()\\
      %[](\{\})\\
      %[]()\{\}\\
      (\{[]\})\\
      (\{\}[])\\
      (\{\})[]\\
      ([\{\}])\\
      ([]\{\})\\
      ([])\{\}\\
      ()\{[]\}\\
      ()\{\}[]\\
      ()[\{\}]\\
      ()[]\{\}\\
   }
\end{document}

感谢 David Carlisle 的回答,我现在知道了确切的问题。此.tex文件运行正常:

\documentclass{article}
\begin{document}
   Lots of Brackets:\\
   \texttt{
      \{[()]\}\\\relax
      \{[]()\}\\\relax
      \{[]\}()\\\relax
      \{([])\}\\\relax
      \{()[]\}\\\relax
      \{()\}[]\\\relax
      \{\}[()]\\\relax
      \{\}[]()\\\relax
      \{\}([])\\\relax
      \{\}()[]\\\relax
      [\{()\}]\\\relax
      [\{\}()]\\\relax
      [\{\}]()\\\relax
      [(\{\})]\\\relax
      [()\{\}]\\\relax
      [()]\{\}\\\relax
      []\{()\}\\\relax
      []\{\}()\\\relax
      [](\{\})\\\relax
      []()\{\}\\\relax
      (\{[]\})\\\relax
      (\{\}[])\\\relax
      (\{\})[]\\\relax
      ([\{\}])\\\relax
      ([]\{\})\\\relax
      ([])\{\}\\\relax
      ()\{[]\}\\\relax
      ()\{\}[]\\\relax
      ()[\{\}]\\\relax
      ()[]\{\}\\\relax
   }
\end{document}

但是,我最终将所有这些都放在了另一个文件中,并使用该listings包和\lstinputlisting命令直接从文件中插入文本。

答案1

如果您只想展示它们,我会使用以下verbatim环境:

\documentclass[10pt]{article}
\usepackage{verbatim}

\begin{document}
\begin{verbatim}
{[()]}
{[]()}
{[]}()
{([])}
{()[]}
{()}[]
{}[()]
{}[]()
{}([])
{}()[]
[{()}]
[{}()]
[{}]()
[({})]
[(){}]
[()]{}
[]{()}
[]{}()
[]({})
[](){}
({[]})
({}[])
({})[]
([{}])
([]{})
([]){}
(){[]}
(){}[]   
()[{}]
()[]{}
\end{verbatim}

\end{document}

答案2

总是发布完整的文档而不仅仅是片段,并完整说明错误信息。

添加

\documentclass{article}

\begin{document}

你得到

! Missing number, treated as zero.
<to be read again> 
                   \protect 
l.14 [\{()\}]
             \

这是由于建筑

\\
[\{...]

这与带有可选参数\\[\{...] 的命令相同,的可选参数是\\\{...\\长度类似于\\[10pt]因此\{会产生错误,即它不是一个数字。

使用

\\\relax

将停止 LaTeX 寻找可选参数。

答案3

编辑(2017)

  • xint 1.09c (2013/10/09)自 以来,即在最初发布几天后,答案就被破坏了,原因是 中的内部更改尝试使用抽象\xintApplyInline\macro{items}扩展,原因我已忘记。的版本没有。在此处的代码中,宏无法以这种方式扩展。因此,我添加了一个以获取扩展并挽救代码。\macro##11.09b\xintApplyInline\DefineAVANTAPRES\empty

  • 答案也因此被打破xint 1.1 (2014/10/28),因为从那时起既没有xint也没有xintfrac加载xinttools。因此需要答案\usepackage{xinttools}


也许你还想产生图案?

可以使用TeX宏来实现这一点。由于技术原因(可以通过一些额外的工作来解决),下面的代码无法处理 \{\},而只能处理纯字符。

对于N开闭对,允许模式的数量除以 ,分别N!12514, ,42132429, ,14304862, ,16796, ,对于 ,N=12, ... , 。这是通过运行下面的代码(第二种算法,可能更快)获得的(或者说,证实了……)。这些数字是许多组合问题中出现的 10加泰罗尼亚数 。参见(2N)!/(N!(N+1)!)http://oeis.org/A000108

首先用 声明(每个任意一个字符)的开闭对\DeclareStuff

然后命令\PrintStuff作为参数给出一个列表开幕字符,它将显示完整的可能性列表保留开头字符的顺序。如果N是此类字符的数量,则模式的真实总数必须乘以 以N!考虑排列。例如,对于六对开头-结尾,可以找到132模式,因此可能性的真实数量是132x720

\Stuff模式的实际生成由具有完全可扩展递归结构的命令处理......

这是输出。您的案例对应于第二行,该行具有成对5的模式3,因此确实存在5x3! = 30解决方案。成对的4模式存在14x4!=336解决方案;仅打印排列似乎是一个合理的选择(只是懒惰的人对自己的算法很满意,不想再增加一层来排列所有内容……)

更新:我在下面插入了另一种算法的输出和代码,该算法当然具有更有效的递归,并且也更容易解释。

括号

以下是代码。它使用了包中的一些宏编程实用程序新工具

\documentclass{article}

\usepackage{xinttools}% for some of its expandable and non expandable utilities to
                 % deal with lists.

\begin{document}

\makeatletter

% This is NON expandable

% can not be used with \{, \}. Only standard characters

\def\DeclareStuff #1%
{%
    \toks@{}%
    \xintAssignArray #1\to\DATA % attention fait un \edef
    \count@ \@ne
    \loop
      \edef\tmp{\DATA{\count@+1}}%
      \expandafter\let\csname FERMEUR\DATA\count@\endcsname\tmp
      \toks@\expandafter\expandafter\expandafter
           {\expandafter\the\expandafter\toks@
                         \romannumeral-`0\DATA{\count@}}%
      \advance\count@\tw@
    \ifnum\count@<\DATA{0} % \DATA{0} is twice the number of pairs
    \repeat
    \edef\LESOUVREURS {\the\toks@}%           (The list of only the openers)
    \xintApplyInline{\empty\DefineAVANTAPRES}{\LESOUVREURS}%
}%

\def\DefineAVANTAPRES #1%
{%
    \expandafter\def\csname AVANT#1\endcsname ##1#1##2\relax {##1}%
    \expandafter\def\csname APRES#1\endcsname ##1#1##2\relax {##2}%
}%   

\def\AVANT #1#2{\csname AVANT#1\endcsname #2\relax }%
\def\APRES #1#2{\csname APRES#1\endcsname #2\relax }%


% THE WHOLE STUFF NEXT IS COMPLETELY EXPANDABLE

\def\Stuff #1{\expandafter\Stuffa\expandafter{\romannumeral-`0#1}}%

\def\Stuffa #1{\ifnum \xintNthElt{0}{#1}>1
                  \expandafter\@firstoftwo
               \else
                  \expandafter\@secondoftwo
               \fi
               {\xintApplyUnbraced {\Stuffb {#1}}{#1}}
               {\expandafter{\expandafter#1\csname FERMEUR#1\endcsname}}% 
               }%

\def\Stuffb #1#2%
{%
    \expandafter\Stuffc\expandafter
    {\romannumeral-`0\AVANT #2{#1}}%
    {\romannumeral-`0\APRES #2{#1}}#2%
}%

\def\Stuffc #1#2%
{%
   \expandafter\Stuffd\expandafter{#2}{#1}%
}%

\def\Stuffd #1#2#3%
{%
    \ifnum\xintLength {#1}>0      % APRES
       \expandafter\@firstoftwo
    \else
       \expandafter\@secondoftwo
    \fi
    {\ifnum\xintLength {#2}>0     % AVANT
        \expandafter\@firstoftwo
     \else
        \expandafter\@secondoftwo
     \fi
     {\expandafter\xintApplyUnbraced\expandafter
        {\expandafter\Join\expandafter
        {\romannumeral-`0\xintApply {\Autour #3}{\Stuff {#1}}}}{\Stuff {#2}}}%
     {\xintApply {\Autour #3}{\Stuff {#1}}}}%
    {\xintApply {\Apres #3}{\Stuff {#2}}}%
}%

\def\Apres #1{\expandafter\Apresa\csname FERMEUR#1\endcsname #1}%
\def\Apresa #1#2#3{ #3#2#1}% the space to stop the romannumeral, but here
                           % nothing is 

\def\Autour #1{\expandafter\Autoura\csname FERMEUR#1\endcsname #1}%
\def\Autoura #1#2#3{ #2#3#1}%

\def\Join #1#2{\xintApply {\Joinb {#2}}{#1}}
\def\Joinb #1#2{ #1#2}% re-reverses order in joining.


% The list is printed in reverse order of its creation, perhaps
% then the pattern is easier to understand by a human


\def\PrintStuff #1{\noindent
                   \xintListWithSep{\hskip1ex plus 1ex minus.5ex }
                   {\xintRevWithBraces{\Stuff {#1}}}%
                   \begingroup\parfillskip\z@\par\endgroup\medskip}

\DeclareStuff {()[]<>-+?!aAbBcCdDeEfF} 

\ttfamily

\PrintStuff {([} 

\PrintStuff {([<}

\PrintStuff {([<-}

\PrintStuff {([<-?}

\PrintStuff {abcdef}

\thispagestyle{empty}

\end{document}

现在,以下是使用以下算法的输出:如果要遵守开启符的顺序,最后一对中不能包含任何内容。因此,只需少生成一对模式,然后将最后一对插入到任何合法位置,即倒数第二个开启符左侧的任何位置。

关于代码,我不会尝试解释;在某些时候,我需要从列表中生成abcd某些类型的东西{-abcd}{a-bcd}{ab-cd}{abc-d}{abcd-};而不是为此编写一个宏(必须是可扩展的),而是以某种方式使用可用的工具xint,这是一个技巧,最好编写正确的工具(因为这里的方法首先需要一些不可扩展的定义,这是可以避免的)。

与上一个代码相反,宏输出的模式列表\Stuff具有精确的给定字符,而在上一个代码中,结束字符在打印时仍由宏表示(例如 \FERMEUR[ 是伪装的 ])。但是保留宏可能会有一些用处,因为它们的定义可以修改。要修改此处的代码,只需保留或删除几个\expandafter' 即可。

但首先输出的顺序与以前的算法不同,但可能更容易让人理解当添加一对新的分隔符时会发生什么。

括号

\documentclass{article}

\usepackage{xinttools}% for some of its expandable and non expandable utilities to
                 % deal with lists.

\begin{document}

\makeatletter

% This is NON expandable

% can not be used with \{, \}. Only standard characters

\def\DeclareStuff #1%
{%
    \toks@{}%
    \xintAssignArray #1\to\DATA % attention fait un \edef
    \count@ \@ne
    \loop
      \edef\tmp{\DATA{\count@+1}}%
      \expandafter\let\csname FERMEUR\DATA\count@\endcsname\tmp
      \toks@\expandafter\expandafter\expandafter
           {\expandafter\the\expandafter\toks@
                         \romannumeral-`0\DATA{\count@}}%
      \advance\count@\tw@
    \ifnum\count@<\DATA{0}
    \repeat
    \edef\LESOUVREURS {\the\toks@}%
    %\xintApplyInline{\empty\DefineAVANTAPRES}{\LESOUVREURS}%
    \xintApplyInline{\empty\DefineAVANTAPRES}{#1}% more AVANT-APRES
    % \Stuff variant needs it also for closing characters
}%

\def\DefineAVANTAPRES #1%
{%
    \expandafter\def\csname AVANT#1\endcsname ##1#1##2\relax {##1}%
    \expandafter\def\csname APRES#1\endcsname ##1#1##2\relax {##2}%
% rajouté pour variante:
    \expandafter\def\csname SPLITL#1\endcsname ##1#1##2\relax {{##1#1}{##2}}%
    \expandafter\def\csname SPLITR#1\endcsname ##1#1##2\relax {{##1}{#1##2}}%
}%   

\def\AVANT   #1#2{\csname AVANT#1\endcsname #2\relax }%
\def\APRES   #1#2{\csname APRES#1\endcsname #2\relax }%
\def\SPLITL #1#2{\csname SPLITL#1\endcsname #2\relax }%
\def\SPLITR #1#2{\csname SPLITR#1\endcsname #2\relax }%


% Completely Expandable macros:

\def\Stuff #1{\expandafter\Stuffa\expandafter{\romannumeral-`0#1}}%

\def\Stuffa #1{\expandafter\Stuffb\expandafter 
               {\romannumeral-`0\xintLength{#1}}{#1}}%

\def\Stuffb #1#2{\ifnum #1>1
                  \expandafter\@firstoftwo
               \else
                  \expandafter\@secondoftwo
               \fi
               {\expandafter\Stuffc\expandafter 
                  {\romannumeral-`0\xintNthElt {1}{\xintReverseOrder {#2}}}%
                  {#2}}%
               {\expandafter\expandafter\expandafter
                  {\expandafter\expandafter\expandafter
                   #2\csname FERMEUR#2\endcsname}}% 
               }%

\def\Stuffc #1#2% #1 = last character of #2
{%
    \expandafter\Stuffd\expandafter #1\expandafter
    {\romannumeral-`0\AVANT #1{#2}}%
}%

\def\Stuffd #1#2%
{%
    \expandafter\Stuffe
    \romannumeral-`0\xintNthElt {1}{\xintReverseOrder{#2}}%
    {#2}#1%
}%

% ouh c'est compliqué
% SPLITL x transforme aabaubxahaoi en {aabaubx}{ahaoi} mais un seul x
% SPLITR x transforme aabaubxahaoi en {aabaub}{xahaoi} mais un seul x

\def\Stuffe #1#2% en #1, le marqueur ouvrant précédent, en #3 le dernier marqueur
{%
    \expandafter\Stufff\expandafter
    {\romannumeral-`0\xintApply {\SPLITL #1}{\Stuff {#2}}}%
}%

\def\Stufff #1#2%
{%
   \xintApplyUnbraced {\Stuffg #2}{#1}%
}%

% compliqué 

\def\Stuffg #1#2{\expandafter\expandafter\expandafter
                 \Stuffk 
                 \expandafter\expandafter\expandafter
                 #1\csname FERMEUR#1\endcsname #2}%

\def\Stuffk #1#2#3#4%
{%
    \xintApply {\Joinb {#3}}{\xintApply {\Insert #1#2}%
                 {\xintApply {\SPLITRrev {#4}}{#4}}{#4#1#2}}%
}%

\def\SPLITRrev #1#2{\SPLITR #2{#1}}% #1 is a "string", #2 a character

\def\Insert  #1#2#3{\Inserta #1#2#3}%
\def\Inserta #1#2#3#4{ #3#1#2#4}%

\def\Joinb #1#2{ #1#2}%

%-------------------------------------------------------------------------------

% The list is printed in reverse order of its creation, perhaps
% then the pattern is easier to understand by a human


\def\PrintStuff #1{\noindent
                   \xintListWithSep{\hskip1ex plus 1ex minus.5ex }
                   {\xintRevWithBraces{\Stuff {#1}}}%
                   \begingroup\parfillskip\z@\par\endgroup\medskip}

\DeclareStuff {()[]<>-+?!aAbBcCdDeEfF} 

\ttfamily

\PrintStuff {([}


\PrintStuff {([<}


\PrintStuff {([<-}

\PrintStuff {([<-?}

\PrintStuff {abcdef}

\thispagestyle{empty}

\end{document}

相关内容