我正在使用该algorithmic
包排版算法。我希望在循环或条件的开始和结束之间有连接线,就像在algorithm2e
包中一样。有没有简单的方法可以实现这一点,或者我最好切换到algorithm2e
?
答案1
这是使用的方法之一algorithmicx
- 更先进但相似且兼容algorithmic
\thelines
。它涉及扩展和收缩跟踪嵌套级别的标记列表。在每个新级别,\theline
都会向 中添加一个附加项\thelines
。
\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}\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$
\LState $b\gets r$
\LState $r\gets a\bmod b$
\EndWhile\label{euclidendwhile}
\LState \Return $b$\Comment{The gcd is b}
\EndProcedure
\end{algorithmic}
\end{algorithm}
\end{document}
每一个定义都被重新定义来管理缩进:
- 在每个块的开头,插入
\printindent
并附加\pushindent
。这将删除常规算法缩进\algorithmicindent
并打印垂直规则。最后它会添加另一个缩进,以便后续语句正确缩进;并且 - 在每个块的末尾插入
\popindent\printindent
。这将删除常规算法缩进\algorithmicindent
,然后吞掉一个缩进,并打印剩余的缩进。
我添加了一些额外的宏,如和\printandpush
,\popandprint
以结合上述内容\printindent
和修改。\pushindent
\popindent
\State
不要使用传统的程序语句,而是使用\LState
。它执行与上面提到的类似的任务。
此解决方案应该适用于定义的标准环境。但是,使用定义的其他更复杂的环境\algdef
可能需要更多调整才能获得正确的缩进。
.5em
关于垂直规则。它从块的最左边距开始设置,.4pt
宽度为\therule
:
\def\therule{%
\makebox[\algorithmicindent][l]{%
\hspace*{.5em}\vrule height .75\baselineskip depth .25\baselineskip}}%
标记列表附加描述于如何将材料附加到令牌列表?,而 token 移除讨论于如何从代币列表中删除材料?