![Algorithmicx - 使用 \algstore 的缩进规则](https://linux22.com/image/349435/Algorithmicx%20-%20%E4%BD%BF%E7%94%A8%20%5Calgstore%20%E7%9A%84%E7%BC%A9%E8%BF%9B%E8%A7%84%E5%88%99.png)
我正在编写一个很长的算法,无法放在一页纸上,我必须使用包提供的命令\algstore
将其拆分。此外,我使用的代码来自\algrestore
algorithmicx
这个帖子获得垂直缩进规则。
如该屏幕截图所示,第二个算法中未恢复缩进和规则。我的编译器返回:
Argument of \@gobble has an extra }.
缩进规则代码和 之间可能存在兼容性问题\algstore
。有人知道如何修复它吗?我给你与屏幕截图相对应的 MWE。
\documentclass{article}
\usepackage{algorithm}% http://ctan.org/pkg/algorithm
\usepackage{algpseudocode}% http://ctan.org/pkg/algorithmicx
\makeatletter
% This is the vertical rule that is inserted
\def\therule{\makebox[\algorithmicindent][l]{\hspace*{.5em}\vrule height .75\baselineskip depth .25\baselineskip}}%
\newtoks\therules% Contains rules
\therules={}% Start with empty token list
\def\appendto#1#2{\expandafter#1\expandafter{\the#1#2}}% Append to token list
\def\gobblefirst#1{% Remove (first) from token list
#1\expandafter\expandafter\expandafter{\expandafter\@gobble\the#1}}%
\def\LState{\State\unskip\the\therules}% New line-state
\def\pushindent{\appendto\therules\therule}%
\def\popindent{\gobblefirst\therules}%
\def\printindent{\unskip\the\therules}%
\def\printandpush{\printindent\pushindent}%
\def\popandprint{\popindent\printindent}%
% *** DECLARED LOOPS ***
% (from algpseudocode.sty)
\algdef{SE}[WHILE]{While}{EndWhile}[1]
{\printandpush\algorithmicwhile\ #1\ \algorithmicdo}
{\popandprint\algorithmicend\ \algorithmicwhile}%
\algdef{SE}[FOR]{For}{EndFor}[1]
{\printandpush\algorithmicfor\ #1\ \algorithmicdo}
{\popandprint\algorithmicend\ \algorithmicfor}%
\algdef{S}[FOR]{ForAll}[1]
{\printindent\algorithmicforall\ #1\ \algorithmicdo}%
\algdef{SE}[LOOP]{Loop}{EndLoop}
{\printandpush\algorithmicloop}
{\popandprint\algorithmicend\ \algorithmicloop}%
\algdef{SE}[REPEAT]{Repeat}{Until}
{\printandpush\algorithmicrepeat}[1]
{\popandprint\algorithmicuntil\ #1}%
\algdef{SE}[IF]{If}{EndIf}[1]
{\printandpush\algorithmicif\ #1\ \algorithmicthen}
{\popandprint\algorithmicend\ \algorithmicif}%
\algdef{C}[IF]{IF}{ElsIf}[1]
{\popandprint\pushindent\algorithmicelse\ \algorithmicif\ #1\ \algorithmicthen}%
\algdef{Ce}[ELSE]{IF}{Else}{EndIf}
{\popandprint\pushindent\algorithmicelse}%
\algdef{SE}[PROCEDURE]{Procedure}{EndProcedure}[2]
{\printandpush\algorithmicprocedure\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
{\popandprint\algorithmicend\ \algorithmicprocedure}%
\algdef{SE}[FUNCTION]{Function}{EndFunction}[2]
{\printandpush\algorithmicfunction\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
{\popandprint\algorithmicend\ \algorithmicfunction}%
\makeatother
\begin{document}
\begin{algorithm}
\caption{Euclid’s algorithm - Part.1}\label{euclid}
\begin{algorithmic}[1]
\Procedure{Euclid}{$a,b$}\Comment{The g.c.d. of a and b}
\LState $r\gets a\bmod b$
\While{$r\not=0$}\Comment{We have the answer if r is 0}
\LState $a\gets b$
\algstore{test}
\end{algorithmic}
\end{algorithm}
\begin{algorithm}
\caption{Euclid’s algorithm - Part.2}\label{euclid2}
\begin{algorithmic}[1]
\algrestore{test}
\LState $b\gets r$
\LState $r\gets a\bmod b$
\EndWhile\label{euclidendwhile}
\LState \textbf{return} $b$\Comment{The gcd is b}
\EndProcedure
\end{algorithmic}
\end{algorithm}
\end{document}
答案1
我从algpseudocode
添加法语关键字(包选项french
和english
)以及vruled
允许缩进规则的包选项开始创建了自己的包,这些规则来自上面给出的代码。我\algrestore
通过在后面手动添加三个规则解决了我的问题:
\therules={\therule \therule \therule}
有新的.tex
:
\documentclass{article}
\usepackage{algorithm}% http://ctan.org/pkg/algorithm
\usepackage[french,vruled]{./style/algopc}
\usepackage{amsmath}
\begin{document}
\begin{algorithm}
\caption{Euclid’s algorithm - Part.1}\label{euclid1}
\begin{algorithmic}[0]
\Algo
\Procedure{Euclid}{$a,b$}\Comment{The g.c.d. of a and b}
\State $r\gets a\bmod b$
\While{$r\not=0$}\Comment{We have the answer if r is 0}
\State $a\gets b$
\State $b\gets r$
\algstore{savename}
\end{algorithmic}
\end{algorithm}
\begin{algorithm}
\begin{algorithmic}[0]
\algrestore{savename}
\therules={\therule \therule \therule}
\State $r\gets a\bmod b$
\EndWhile\label{euclidendwhile}
\Return $b$\Comment{The gcd is b}
\EndProcedure
\EndAlgo
\end{algorithmic}
\end{algorithm}
\end{document}
我给你我改进的版本的包algpseudocode
:
% PSEUDOCODE ALGORITHMIC STYLE -- Released 27 APR 2005
% for LaTeX version 2e
%
% Copyright Szasz Janos
% E-mail [email protected]
% Based on Szasz Janos's algpseudocode.sty
%
\NeedsTeXFormat{LaTeX2e}%
\ProvidesPackage{algopc}%
\RequirePackage{ifthen}%
\RequirePackage{algorithmicx}%
\typeout{Document Style - pseudocode environments for use with the `algorithmicx' style}%
%
\def\ALG@noend{f}%
\newboolean{ALG@compatible}%
\setboolean{ALG@compatible}{false}%
\newboolean{ALG@vruled}%
\setboolean{ALG@vruled}{false}%
%
\DeclareOption{noend}{\def\ALG@noend{t}}%
\DeclareOption{end}{\def\ALG@noend{f}}%
\DeclareOption{compatible}{%
\typeout{For compatibility mode use algcompatible.sty!!!}%
\setboolean{ALG@compatible}{true}%
}%
\DeclareOption{noncompatible}{\setboolean{ALG@noncompatible}{false}}%
\DeclareOption{vruled}{\setboolean{ALG@vruled}{true}}%
\DeclareOption{english}{%
\def\wordbegalgo{begin}%
\def\wordendalgo{end}%
\def\wordend{end}%
\def\worddo{do}%
\def\wordwhile{while}%
\def\wordfor{for}%
\def\wordforall{for all}%
\def\wordloop{loop}%
\def\wordrepeat{repeat}%
\def\worduntil{until}%
\def\wordprocedure{procedure}%
\def\wordfunction{function}%
\def\wordif{if}%
\def\wordthen{then}%
\def\wordelse{else}%
\def\wordrequire{Require:}%
\def\wordensure{Ensure:}%
\def\wordreturn{return}%
}%
\DeclareOption{french}{% FRENCH
\def\wordbegalgo{d\'ebut}%
\def\wordendalgo{fin}%
\def\wordend{fin}%
\def\worddo{faire}%
\def\wordwhile{tant que}%
\def\wordfor{pour}%
\def\wordforall{pour tout}%
\def\wordloop{boucle}%
\def\wordrepeat{r\'ep\'eter}%
\def\worduntil{jusqu'\`a}%
\def\wordprocedure{proc\'edure}%
\def\wordfunction{fonction}%
\def\wordif{si}%
\def\wordthen{alors}%
\def\wordelse{sinon}%
\def\wordrequire{demander :}%
\def\wordensure{assurer :}%
\def\wordreturn{retourner}%
}%
\ProcessOptions%
%
% *** DECLARATIONS ***
%
\algnewlanguage{pscde}%
\alglanguage{pscde}%
%
% *** KEYWORDS ***
%
\algnewcommand\textkw{\textbf}
\algnewcommand\algorithmicbegalgo{\textkw{\wordbegalgo}}
\algnewcommand\algorithmicendalgo{\textkw{\wordendalgo}}
\algnewcommand\algorithmicend{\textkw{\wordend}}
\algnewcommand\algorithmicdo{\textkw{\worddo}}
\algnewcommand\algorithmicwhile{\textkw{\wordwhile}}
\algnewcommand\algorithmicfor{\textkw{\wordfor}}
\algnewcommand\algorithmicforall{\textkw{\wordforall}}
\algnewcommand\algorithmicloop{\textkw{\wordloop}}
\algnewcommand\algorithmicrepeat{\textkw{\wordrepeat}}
\algnewcommand\algorithmicuntil{\textkw{\worduntil}}
\algnewcommand\algorithmicprocedure{\textkw{\wordprocedure}}
\algnewcommand\algorithmicfunction{\textkw{\wordfunction}}
\algnewcommand\algorithmicif{\textkw{\wordif}}
\algnewcommand\algorithmicthen{\textkw{\wordthen}}
\algnewcommand\algorithmicelse{\textkw{\wordelse}}
\algnewcommand\algorithmicrequire{\textkw{\wordRequire:}}
\algnewcommand\algorithmicensure{\textkw{\wordEnsure:}}
\algnewcommand\algorithmicreturn{\textkw{\wordreturn}}
\algnewcommand\textproc{\textsc}
%
% *** DEFINE VRULED COMMAND ***
%
\ifthenelse{\boolean{ALG@vruled}}{%
% This is the vertical rule that is inserted
\algnewcommand\therule{%
\makebox[\algorithmicindent][l]{%
\hspace*{.5em}\vrule height .75\baselineskip depth .25\baselineskip
}%
}%
\newtoks\therules% Contains rules
\therules={}% Start with empty token list
\def\appendto#1#2{% Append to token list
\expandafter#1\expandafter{\the#1#2}%
}%
\def\gobblefirst#1{% Remove (first) from token list
#1\expandafter\expandafter\expandafter{\expandafter\@gobble\the#1}%
}%
\algdef{SL}[STATE]{State}{0}{\unskip\the\therules}% New line-state
%
\def\pushindent{\appendto\therules\therule}%
\def\popindent{\gobblefirst\therules}%
\def\printindent{\unskip\the\therules}%
\def\printandpush{\printindent\pushindent}%
\def\popandprint{\popindent\printindent}%
}{}%
%
% *** DECLARED LOOPS ***
%
\ifthenelse{\boolean{ALG@vruled}}{%
\algdef{SE}[ALGO]{Algo}{EndAlgo}%
{\printandpush\algorithmicbegalgo}%
{\popandprint\algorithmicendalgo}%
\algdef{SE}[WHILE]{While}{EndWhile}%
[1]{\printandpush\algorithmicwhile\ #1\ \algorithmicdo}%
{\popandprint\algorithmicend\ \algorithmicwhile}%
\algdef{SE}[FOR]{For}{EndFor}%
[1]{\printandpush\algorithmicfor\ #1\ \algorithmicdo}%
{\popandprint\algorithmicend\ \algorithmicfor}%
\algdef{S}[FOR]{ForAll}%
[1]{\printandpush\algorithmicforall\ #1\ \algorithmicdo}%
\algdef{SE}[LOOP]{Loop}{EndLoop}%
{\printandpush\algorithmicloop}%
{\popandprint\algorithmicend\ \algorithmicloop}%
\algdef{SE}[REPEAT]{Repeat}{Until}%
{\printandpush\algorithmicrepeat}%
[1]{\popandprint\algorithmicuntil\ #1}%
\algdef{SE}[IF]{If}{EndIf}%
[1]{\printandpush\algorithmicif\ #1\ \algorithmicthen}%
{\popandprint\algorithmicend\ \algorithmicif}%
\algdef{C}[IF]{IF}{ElsIf}%
[1]{\popandprint\pushindent\algorithmicelse\ \algorithmicif\ #1\ \algorithmicthen}%
\algdef{Ce}[ELSE]{IF}{Else}{EndIf}%
{\popandprint\pushindent\algorithmicelse}%
\algdef{SE}[PROCEDURE]{Procedure}{EndProcedure}%
[2]{\printandpush\algorithmicprocedure\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
{\popandprint\algorithmicend\ \algorithmicprocedure}%
\algdef{SE}[FUNCTION]{Function}{EndFunction}%
[2]{\printandpush\algorithmicfunction\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
{\popandprint\algorithmicend\ \algorithmicfunction}%
}{%
\algdef{SE}[ALGO]{Algo}{EndAlgo}%
{\algorithmicbegalgo}%
{\algorithmicendalgo}%
\algdef{SE}[WHILE]{While}{EndWhile}%
[1]{\algorithmicwhile\ #1\ \algorithmicdo}%
{\algorithmicend\ \algorithmicwhile}%
\algdef{SE}[FOR]{For}{EndFor}%
[1]{\algorithmicfor\ #1\ \algorithmicdo}%
{\algorithmicend\ \algorithmicfor}%
\algdef{S}[FOR]{ForAll}%
[1]{\algorithmicforall\ #1\ \algorithmicdo}%
\algdef{SE}[LOOP]{Loop}{EndLoop}%
{\algorithmicloop}%
{\algorithmicend\ \algorithmicloop}%
\algdef{SE}[REPEAT]{Repeat}{Until}%
{\algorithmicrepeat}%
[1]{\algorithmicuntil\ #1}%
\algdef{SE}[IF]{If}{EndIf}%
[1]{\algorithmicif\ #1\ \algorithmicthen}
{\algorithmicend\ \algorithmicif}%
\algdef{C}[IF]{IF}{ElsIf}%
[1]{\algorithmicelse\ \algorithmicif\ #1\ \algorithmicthen}%
\algdef{Ce}[ELSE]{IF}{Else}{EndIf}%
{\algorithmicelse}%
\algdef{SE}[PROCEDURE]{Procedure}{EndProcedure}%
[2]{\algorithmicprocedure\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
{\algorithmicend\ \algorithmicprocedure}%
\algdef{SE}[FUNCTION]{Function}{EndFunction}%
[2]{\algorithmicfunction\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
{\algorithmicend\ \algorithmicfunction}%
}%
%
\ifthenelse{\equal{\ALG@noend}{t}}{%
\ifthenelse{\boolean{ALG@vruled}}{%
\algtext{EndWhile}{\popindent\vspace{-.99\baselineskip}}%
\algtext{EndFor}{\popindent\vspace{-.99\baselineskip}}%
\algtext{EndLoop}{\popindent\vspace{-.99\baselineskip}}%
\algtext{EndIf}{\popindent\vspace{-.99\baselineskip}}%
\algtext{EndProcedure}{\popindent\vspace{-.99\baselineskip}}%
\algtext{EndFunction}{\popindent\vspace{-.99\baselineskip}}%
\algtext{EndAlgo}{\popindent\vspace{-.99\baselineskip}}%
}{%
\algtext*{EndWhile}%
\algtext*{EndFor}%
\algtext*{EndLoop}%
\algtext*{EndIf}%
\algtext*{EndProcedure}%
\algtext*{EndFunction}%
\algtext*{EndAlgo}%
}%
}{}%
%
% *** OTHER DECLARATIONS ***
%
\algnewcommand\Require{\State\item[\algorithmicrequire]}%
\algnewcommand\Ensure{\State\item[\algorithmicensure]}%
\algnewcommand\Return{\State\algorithmicreturn{} }%
\algnewcommand\Call[2]{\textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
%
\ifthenelse{\boolean{ALG@compatible}}{%
\ifthenelse{\equal{\ALG@noend}{t}}{%
\RequirePackage[noend]{algcompatible}%
}{%
\RequirePackage{algcompatible}%
}%
}{}%
关键是要找到一种保存标记 \therules 的方法\algstore
。我尝试查看将保存过程放入algorithmicx
包中的过程,我甚至确定了一些相关的段落,但我并不真正理解它是如何工作的。如果了解 TeX 的人可以帮助我理解它的\algstore
工作原理,我会用优雅的方式完成包以拆分规则算法。