算法包中的新子句

算法包中的新子句

我想在算法包中定义一个新子句(sync在我的情况下),以便该子句内的代码可以像在while子句内部一样缩进。

到目前为止,我通过在不同的地方添加这些行来使事情正常进行algorithmic.sty

\newcommand{\algorithmicsync}{\textbf{sync}}
\newcommand{\algorithmicendsync}{\algorithmicend\ \algorithmicsync}
\newenvironment{ALC@syn}{\begin{ALC@g}}{\end{ALC@g}}
\newcommand{\SYNC}[2][default]{\ALC@it\algorithmicsync\ ##2\ %
    \ALC@com{##1}\begin{ALC@syn}}
\ifthenelse{\boolean{ALC@noend}}{
    \newcommand{\ENDSYNC}{\end{ALC@syn}}
}{
    \newcommand{\ENDSYNC}{\end{ALC@syn}\ALC@it\algorithmicendsync}
}

有没有更简单的方法来完成这项工作而无需编辑algorithmic.sty文件?

答案1

正如 Werner 在他的评论中所说,不建议.sty直接修改文件。您可以在文档序言中包含您的定义(在加载所需的包之后);由于您的命令使用了字符@,因此您需要\makeatletter在定义之前和\makeatother之后使用。

不过,我建议你使用算法包;这个包为您提供了许多自定义算法布局的可能性,并为您提供了一种简单的方法来根据您的特定需求定义一个全新的布局。例如(algpseudocode内部加载algorithmicx):

\documentclass{article}
\usepackage{algpseudocode}

\algblockdefx{Sync}{EndSync}[1]{\textbf{sync} #1}{\textbf{end sync}}

\begin{document}

\begin{algorithmic}
\Require$n \geq 0$
\Ensure $y = x^n$
\State $y \leftarrow 1$
\While{$N \neq 0$}
\State $X \leftarrow X$
\EndWhile
\Sync{$N$ id odd}
\State $N \leftarrow n$
\EndSync
\end{algorithmic}

\end{document}

在此处输入图片描述

编辑:如果algorithmicx目前无法更改为,您仍然可以在文档的序言中进行定义,而不是.sty直接修改文件;只需使用\renewenvironment重新定义algorithmic环境并包含新定义:

\documentclass{article}
\usepackage{algorithmic}

\makeatletter
\newcommand{\algorithmicsync}{\textbf{sync}}
\newcommand{\algorithmicendsync}{\algorithmicend\ \algorithmicsync}
\renewenvironment{algorithmic}[1][0]{
\let\@item\ALC@item
  \newcommand{\ALC@lno}{%
\ifthenelse{\equal{\arabic{ALC@rem}}{0}}
{{\footnotesize \arabic{ALC@line}:}}{}%
}
\let\@listii\@listi
\let\@listiii\@listi
\let\@listiv\@listi
\let\@listv\@listi
\let\@listvi\@listi
\let\@listvii\@listi
  \newenvironment{ALC@g}{
    \begin{list}{\ALC@lno}{ \itemsep\z@ \itemindent\z@
    \listparindent\z@ \rightmargin\z@ 
    \topsep\z@ \partopsep\z@ \parskip\z@\parsep\z@
    \leftmargin 1em
    \addtolength{\ALC@tlm}{\leftmargin}
    }
  }
  {\end{list}}
  \newcommand{\ALC@it}{\addtocounter{ALC@line}{1}\addtocounter{ALC@rem}{1}\ifthenelse{\equal{\arabic{ALC@rem}}{#1}}{\setcounter{ALC@rem}{0}}{}\item}
  \newcommand{\ALC@com}[1]{\ifthenelse{\equal{##1}{default}}%
{}{\ \algorithmiccomment{##1}}}
  \newcommand{\REQUIRE}{\item[\algorithmicrequire]}
  \newcommand{\ENSURE}{\item[\algorithmicensure]}
  \newcommand{\STATE}{\ALC@it}
  \newcommand{\COMMENT}[1]{\algorithmiccomment{##1}}
  \newenvironment{ALC@if}{\begin{ALC@g}}{\end{ALC@g}}
  \newenvironment{ALC@for}{\begin{ALC@g}}{\end{ALC@g}}
  \newenvironment{ALC@whl}{\begin{ALC@g}}{\end{ALC@g}}
  \newenvironment{ALC@loop}{\begin{ALC@g}}{\end{ALC@g}}
  \newenvironment{ALC@rpt}{\begin{ALC@g}}{\end{ALC@g}}
  \newenvironment{ALC@syn}{\begin{ALC@g}}{\end{ALC@g}}% new
  \renewcommand{\\}{\@centercr}

  \newcommand{\IF}[2][default]{\ALC@it\algorithmicif\ ##2\ \algorithmicthen%
\ALC@com{##1}\begin{ALC@if}}
  \newcommand{\ELSE}[1][default]{\end{ALC@if}\ALC@it\algorithmicelse%
\ALC@com{##1}\begin{ALC@if}}
  \newcommand{\ELSIF}[2][default]%
{\end{ALC@if}\ALC@it\algorithmicelsif\ ##2\ \algorithmicthen%
\ALC@com{##1}\begin{ALC@if}}
  \newcommand{\FOR}[2][default]{\ALC@it\algorithmicfor\ ##2\ \algorithmicdo%
\ALC@com{##1}\begin{ALC@for}}
  \newcommand{\FORALL}[2][default]{\ALC@it\algorithmicforall\ ##2\ %
\algorithmicdo%
\ALC@com{##1}\begin{ALC@for}}
  \newcommand{\WHILE}[2][default]{\ALC@it\algorithmicwhile\ ##2\ %
\algorithmicdo%
\ALC@com{##1}\begin{ALC@whl}}
  \newcommand{\LOOP}[1][default]{\ALC@it\algorithmicloop%
\ALC@com{##1}\begin{ALC@loop}}
  \newcommand{\REPEAT}[1][default]{\ALC@it\algorithmicrepeat%
\ALC@com{##1}\begin{ALC@rpt}}
  \newcommand{\UNTIL}[1]{\end{ALC@rpt}\ALC@it\algorithmicuntil\ ##1}
\newcommand{\SYNC}[2][default]{\ALC@it\algorithmicsync\ ##2\ % new
    \ALC@com{##1}\begin{ALC@syn}} %new
  \ifthenelse{\boolean{ALC@noend}}{
    \newcommand{\ENDIF}{\end{ALC@if}}
    \newcommand{\ENDFOR}{\end{ALC@for}}
    \newcommand{\ENDWHILE}{\end{ALC@whl}}
    \newcommand{\ENDLOOP}{\end{ALC@loop}}
    \newcommand{\ENDSYNC}{\end{ALC@syn}} % new
  }{
    \newcommand{\ENDIF}{\end{ALC@if}\ALC@it\algorithmicendif}
    \newcommand{\ENDFOR}{\end{ALC@for}\ALC@it\algorithmicendfor}
    \newcommand{\ENDWHILE}{\end{ALC@whl}\ALC@it\algorithmicendwhile}
    \newcommand{\ENDLOOP}{\end{ALC@loop}\ALC@it\algorithmicendloop}
    \newcommand{\ENDSYNC}{\end{ALC@syn}\ALC@it\algorithmicendsync}% new
  } 
  \renewcommand{\@toodeep}{}
  \begin{list}{\ALC@lno}{\setcounter{ALC@line}{0}\setcounter{ALC@rem}{0}%
    \itemsep\z@ \itemindent\z@ \listparindent\z@%
    \partopsep\z@ \parskip\z@ \parsep\z@%
    \labelsep 0.5em \topsep 0.2em%
\ifthenelse{\equal{#1}{0}}
  {\labelwidth 0.5em }
  {\labelwidth  1.2em }
\leftmargin\labelwidth \addtolength{\leftmargin}{\labelsep}
    \ALC@tlm\labelsep
  }
}
{\end{list}}
\makeatother

\begin{document}

\begin{algorithmic}
\REQUIRE $n \geq 0$
\ENSURE $y = x^n$
\STATE $y \leftarrow 1$
\WHILE{$N \neq 0$}
\STATE $X \leftarrow X$
\ENDWHILE
\SYNC{$N$ id odd}
\STATE $N \leftarrow n$
\ENDSYNC
\end{algorithmic}

\end{document}

如果您不想让序言看起来太拥挤,您可以将\makeatletter和之间的代码放在\makeatother一个新文档中,并将此新文档保存为,例如,保存algorithmic-modified.sty在当前工作目录中(或保存在本地 TDS 树中)。现在,可以在加载后以标准方式将此文件加载到文档的序言中algorithmic(您必须小心,因为使用该文档的其他用户也必须有权访问此新文件):

\documentclass{article}
\usepackage{algorithmic}
\usepackage{algorithmic-modified}

\begin{document}

\begin{algorithmic}
\REQUIRE $n \geq 0$
\ENSURE $y = x^n$
\STATE $y \leftarrow 1$
\WHILE{$N \neq 0$}
\STATE $X \leftarrow X$
\ENDWHILE
\SYNC{$N$ id odd}
\STATE $N \leftarrow n$
\ENDSYNC
\end{algorithmic}

\end{document}

以下是的内容algorithmic-modified.sty

% redefinition of the algorithmic environment
\newcommand{\algorithmicsync}{\textbf{sync}}
\newcommand{\algorithmicendsync}{\textbf{end sync}}
\renewenvironment{algorithmic}[1][0]{
\let\@item\ALC@item
  \newcommand{\ALC@lno}{%
\ifthenelse{\equal{\arabic{ALC@rem}}{0}}
{{\footnotesize \arabic{ALC@line}:}}{}%
}
\let\@listii\@listi
\let\@listiii\@listi
\let\@listiv\@listi
\let\@listv\@listi
\let\@listvi\@listi
\let\@listvii\@listi
  \newenvironment{ALC@g}{
    \begin{list}{\ALC@lno}{ \itemsep\z@ \itemindent\z@
    \listparindent\z@ \rightmargin\z@ 
    \topsep\z@ \partopsep\z@ \parskip\z@\parsep\z@
    \leftmargin 1em
    \addtolength{\ALC@tlm}{\leftmargin}
    }
  }
  {\end{list}}
  \newcommand{\ALC@it}{\addtocounter{ALC@line}{1}\addtocounter{ALC@rem}{1}\ifthenelse{\equal{\arabic{ALC@rem}}{#1}}{\setcounter{ALC@rem}{0}}{}\item}
  \newcommand{\ALC@com}[1]{\ifthenelse{\equal{##1}{default}}%
{}{\ \algorithmiccomment{##1}}}
  \newcommand{\REQUIRE}{\item[\algorithmicrequire]}
  \newcommand{\ENSURE}{\item[\algorithmicensure]}
  \newcommand{\STATE}{\ALC@it}
  \newcommand{\COMMENT}[1]{\algorithmiccomment{##1}}
  \newenvironment{ALC@if}{\begin{ALC@g}}{\end{ALC@g}}
  \newenvironment{ALC@for}{\begin{ALC@g}}{\end{ALC@g}}
  \newenvironment{ALC@whl}{\begin{ALC@g}}{\end{ALC@g}}
  \newenvironment{ALC@loop}{\begin{ALC@g}}{\end{ALC@g}}
  \newenvironment{ALC@rpt}{\begin{ALC@g}}{\end{ALC@g}}
  \newenvironment{ALC@syn}{\begin{ALC@g}}{\end{ALC@g}}% new
  \renewcommand{\\}{\@centercr}

  \newcommand{\IF}[2][default]{\ALC@it\algorithmicif\ ##2\ \algorithmicthen%
\ALC@com{##1}\begin{ALC@if}}
  \newcommand{\ELSE}[1][default]{\end{ALC@if}\ALC@it\algorithmicelse%
\ALC@com{##1}\begin{ALC@if}}
  \newcommand{\ELSIF}[2][default]%
{\end{ALC@if}\ALC@it\algorithmicelsif\ ##2\ \algorithmicthen%
\ALC@com{##1}\begin{ALC@if}}
  \newcommand{\FOR}[2][default]{\ALC@it\algorithmicfor\ ##2\ \algorithmicdo%
\ALC@com{##1}\begin{ALC@for}}
  \newcommand{\FORALL}[2][default]{\ALC@it\algorithmicforall\ ##2\ %
\algorithmicdo%
\ALC@com{##1}\begin{ALC@for}}
  \newcommand{\WHILE}[2][default]{\ALC@it\algorithmicwhile\ ##2\ %
\algorithmicdo%
\ALC@com{##1}\begin{ALC@whl}}
  \newcommand{\LOOP}[1][default]{\ALC@it\algorithmicloop%
\ALC@com{##1}\begin{ALC@loop}}
  \newcommand{\REPEAT}[1][default]{\ALC@it\algorithmicrepeat%
\ALC@com{##1}\begin{ALC@rpt}}
  \newcommand{\UNTIL}[1]{\end{ALC@rpt}\ALC@it\algorithmicuntil\ ##1}
\newcommand{\SYNC}[2][default]{\ALC@it\algorithmicsync\ ##2\ % new
    \ALC@com{##1}\begin{ALC@syn}} %new
  \ifthenelse{\boolean{ALC@noend}}{
    \newcommand{\ENDIF}{\end{ALC@if}}
    \newcommand{\ENDFOR}{\end{ALC@for}}
    \newcommand{\ENDWHILE}{\end{ALC@whl}}
    \newcommand{\ENDLOOP}{\end{ALC@loop}}
    \newcommand{\ENDSYNC}{\end{ALC@syn}} % new
  }{
    \newcommand{\ENDIF}{\end{ALC@if}\ALC@it\algorithmicendif}
    \newcommand{\ENDFOR}{\end{ALC@for}\ALC@it\algorithmicendfor}
    \newcommand{\ENDWHILE}{\end{ALC@whl}\ALC@it\algorithmicendwhile}
    \newcommand{\ENDLOOP}{\end{ALC@loop}\ALC@it\algorithmicendloop}
    \newcommand{\ENDSYNC}{\end{ALC@syn}\ALC@it\algorithmicendsync}% new
  } 
  \renewcommand{\@toodeep}{}
  \begin{list}{\ALC@lno}{\setcounter{ALC@line}{0}\setcounter{ALC@rem}{0}%
    \itemsep\z@ \itemindent\z@ \listparindent\z@%
    \partopsep\z@ \parskip\z@ \parsep\z@%
    \labelsep 0.5em \topsep 0.2em%
\ifthenelse{\equal{#1}{0}}
  {\labelwidth 0.5em }
  {\labelwidth  1.2em }
\leftmargin\labelwidth \addtolength{\leftmargin}{\labelsep}
    \ALC@tlm\labelsep
  }
}
{\end{list}}

相关内容