如何获取环境中的总行数

如何获取环境中的总行数

在试图找到一个完整的答案时这个帖子,我想知道如何才能获得环境中的总行数algorithmic

当然,这个问题也与其他环境相关。

我已经尝试使用该包,但是当尝试使用其中 totcount计数器的最终值时,它失败了。\totalvalue{<counter>}\makeatketter ... \makeatother

我很确定我遗漏了一些基本的东西,所以想更好地理解这个问题。

其他先前的答案例如这个例如,针对其他环境解决此问题,但我不知道如何使它们适应这种情况。

以下是改编自邮报我正在尽力回答。

\documentclass[a4paper,10pt]{IEEEtran}
\usepackage{totcount}
\usepackage{algpseudocode}

\regtotcounter{ALG@line}

% Patch the line numbering to display the first and last line numbers
\makeatletter
\def\ALG@step%
   {%
   \addtocounter{ALG@line}{1}%
   \addtocounter{ALG@rem}{1}%
   % Beginning of patch
   % First line
   \ifthenelse{\equal{\arabic{ALG@line}}{1}}%
      {\alglinenumber{\arabic{ALG@line}}}%
      {}%
   % Last line  --> DOES NOT WORK
%   \ifthenelse{\equal{\arabic{ALG@line}}{\arabic{\total{ALG@line}}}}%
%      {\alglinenumber{\arabic{ALG@line}}}%
%      {}%
   % End of patch
   \ifthenelse{\equal{\arabic{ALG@rem}}{\ALG@numberfreq}}%
      {\setcounter{ALG@rem}{0}\alglinenumber{\arabic{ALG@line}}}%
      {}%
   }%
\makeatother


\begin{document}
See \figurename{~\ref{fig:myalgorithm}} below.

\begin{figure}[!ht]
 \noindent\rule{\linewidth}{0.8pt}
 \noindent \textbf{Algorithm} itsname
 \noindent\hrule
 \begin{algorithmic}[3]
  \Procedure {BellmanKalaba}{$G$, $u$, $l$, $p$}
  \ForAll {$v \in V(G)$}
  \State $l(v) \leftarrow \infty$
  \EndFor
  \State $l(u) \leftarrow 0$
  \Repeat
  \For {$i \leftarrow 1, n$}
  \State $min \leftarrow l(v_i)$
  \For {$j \leftarrow 1, n$}
  \If {$min > e(v_i, v_j) + l(v_j)$}
  \State $min \leftarrow e(v_i, v_j) + l(v_j)$
  \State $p(i) \leftarrow v_j$
  \EndIf
  \EndFor
  \State $l'(i) \leftarrow min$
  \EndFor
  \State $changed \leftarrow l \not= l'$
  \State $l \leftarrow l'$
  \Until{$\neg changed$}
  \EndProcedure
 \end{algorithmic}
 \noindent\rule{\linewidth}{0.8pt}
 \caption{This algorithm was copied from the algorithmicx's package documentation.}\label{fig:myalgorithm}
\end{figure}

Total amount of lines in the algorithm: \total{ALG@line}


\end{document}

enter image description here

答案1

以下是解决您问题的两步方法。我允许您使用它来回答另一个问题,但请给我信用 :)

\documentclass[a4paper,10pt]{IEEEtran}
\usepackage{totcount}
\usepackage{algpseudocode}

\usepackage{etoolbox}

\regtotcounter{ALG@line}

% Patch the line numbering to display the first and last line numbers
\makeatletter
% execute this code at \end{algorithmic} but before the group is closed
\AtEndEnvironment{algorithmic}{\@WriteAlgorithmicLastLine}
% execute this code at \begin{algorithmic} just after the group is opened
\AtBeginEnvironment{algorithmic}{\stepcounter{AlgorithmicEnvironmentCounter}}
\newcounter{AlgorithmicEnvironmentCounter}
\newcommand*\@WriteAlgorithmicLastLine
  {% this macro writes the definition to the aux file, you have to make sure
   % that only the right stuff is expanded (\write expands its argument as
   % much as it is able to)
    \immediate\write\@auxout
      {%
        % we don't want \expandafter to disappear
        \unexpanded{\expandafter\gdef}%
        % we don't want \csname to do its work just here
        \unexpanded{\csname @AlgorithmicLastLine@}%
        % the counter should be expanded
        \the\c@AlgorithmicEnvironmentCounter%
        % \endcsname isn't expandable (if you're unsure whether something is
        % expandable enclose it by \unexpanded or precede it with \noexpand)
        \endcsname%
        % this counter should as well be expanded
        {\arabic{ALG@line}}%
      }%
  }
\def\ALG@step%
  {%
    \addtocounter{ALG@line}{1}%
    \addtocounter{ALG@rem}{1}%
    % Beginning of patch
   \ifthenelse{\equal{\arabic{ALG@rem}}{\ALG@numberfreq}}%
      {\setcounter{ALG@rem}{0}\alglinenumber{\arabic{ALG@line}}}%
      {% if it is no line that already gets a number one of the other rules
       % might apply
        \ifthenelse{\equal{\arabic{ALG@line}}{1}}%
          {\alglinenumber{\arabic{ALG@line}}}%
          {% if not the first line, it may be the last
            % \ifcsdef is a wrapper around \ifcsname to check whether something
            % is defined or not
            \ifcsdef
              {@AlgorithmicLastLine@\arabic{AlgorithmicEnvironmentCounter}}%
              {% if it is defined execute this code
                % \ifnum is a TeX primitive comparing the following two numbers
                % and executing the true branch if the comparison is true,
                % possible comparisons are '=', '>' and '<'.
                \ifnum
                  % csuse is a wrapper around \csname building the
                  % control-sequence which's name is the argument of \csuse
                  % (argument is fully expanded)
                  \csuse
                    {%
                      @AlgorithmicLastLine@%
                      \arabic{AlgorithmicEnvironmentCounter}%
                    }%
                  =\c@ALG@line
                  \alglinenumber{\arabic{ALG@line}}%
                \fi
              }%
              {}% not defined
          }%
      }%
   }%
\makeatother


\begin{document}
See \figurename{~\ref{fig:myalgorithm}} below.

\begin{figure}[!ht]
 \noindent\rule{\linewidth}{0.8pt}
 \noindent \textbf{Algorithm} itsname
 \noindent\hrule
 \begin{algorithmic}[3]
  \Procedure {BellmanKalaba}{$G$, $u$, $l$, $p$}
  \ForAll {$v \in V(G)$}
  \State $l(v) \leftarrow \infty$
  \EndFor
  \State $l(u) \leftarrow 0$
  \Repeat
  \For {$i \leftarrow 1, n$}
  \State $min \leftarrow l(v_i)$
  \For {$j \leftarrow 1, n$}
  \If {$min > e(v_i, v_j) + l(v_j)$}
  \State $min \leftarrow e(v_i, v_j) + l(v_j)$
  \State $p(i) \leftarrow v_j$
  \EndIf
  \EndFor
  \State $l'(i) \leftarrow min$
  \EndFor
  \State $changed \leftarrow l \not= l'$
  \State $l \leftarrow l'$
  \Until{$\neg changed$}
  \EndProcedure
 \end{algorithmic}
 \noindent\rule{\linewidth}{0.8pt}
 \caption
  {%
    This algorithm was copied from the algorithmicx's package documentation.%
    \label{fig:myalgorithm}%
  }
\end{figure}

Total amount of lines in the algorithm: \total{ALG@line}

\begin{figure}[!ht]
 \noindent\rule{\linewidth}{0.8pt}
 \noindent \textbf{Algorithm} itsname
 \noindent\hrule
 \begin{algorithmic}[3]
  \Procedure {BellmanKalaba}{$G$, $u$, $l$, $p$}
  \ForAll {$v \in V(G)$}
  \State $l(v) \leftarrow \infty$
  \EndFor
  \State $l(u) \leftarrow 0$
  \Repeat
  \For {$i \leftarrow 1, n$}
  \State $min \leftarrow l(v_i)$
  \For {$j \leftarrow 1, n$}
  \If {$min > e(v_i, v_j) + l(v_j)$}
  \State $min \leftarrow e(v_i, v_j) + l(v_j)$
  \State $p(i) \leftarrow v_j$
  \EndIf
  \EndFor
  \State $l'(i) \leftarrow min$
  \EndFor
  \Until{$\neg changed$}
  \EndProcedure
 \end{algorithmic}
 \noindent\rule{\linewidth}{0.8pt}
 \caption
  {%
    This algorithm was copied from the algorithmicx's package documentation.%
    \label{fig:myalgorithm2}%
  }
\end{figure}

\end{document}

编辑:我在上面的代码中添加了一些注释,希望能描述所有内容。

编辑2:解决多行编号的错误。

答案2

由于计数器是全局保存的,因此您所需要的只是\arabic{ALG@line}。如果您想在计算之前访问它,您可以伪造一个\label

\documentclass[a4paper,10pt]{IEEEtran}
\usepackage{totcount}
\usepackage{algpseudocode}

\begin{document}
See \figurename{~\ref{fig:myalgorithm}} below (\ref{ALGlines} lines).

\begin{figure}[!ht]
 \noindent\rule{\linewidth}{0.8pt}
 \noindent \textbf{Algorithm} itsname
 \noindent\hrule
 \begin{algorithmic}[3]
  \Procedure {BellmanKalaba}{$G$, $u$, $l$, $p$}
  \ForAll {$v \in V(G)$}
  \State $l(v) \leftarrow \infty$
  \EndFor
  \State $l(u) \leftarrow 0$
  \Repeat
  \For {$i \leftarrow 1, n$}
  \State $min \leftarrow l(v_i)$
  \For {$j \leftarrow 1, n$}
  \If {$min > e(v_i, v_j) + l(v_j)$}
  \State $min \leftarrow e(v_i, v_j) + l(v_j)$
  \State $p(i) \leftarrow v_j$
  \EndIf
  \EndFor
  \State $l'(i) \leftarrow min$
  \EndFor
  \State $changed \leftarrow l \not= l'$
  \State $l \leftarrow l'$
  \Until{$\neg changed$}
  \EndProcedure
 \end{algorithmic}
 \noindent\rule{\linewidth}{0.8pt}
 \caption{This algorithm was copied from the algorithmicx's package documentation.}\label{fig:myalgorithm}
 \addtocounter{ALG@line}{-1}\refstepcounter{ALG@line}\label{ALGlines}%
\end{figure}

Total amount of lines in the algorithm: \arabic{ALG@line}

\end{document}

相关内容