算法中是否可以有连接环路(如算法2e)?

算法中是否可以有连接环路(如算法2e)?

我正在使用该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 移除讨论于如何从代币列表中删除材料?

相关内容