我需要两种客户端与服务器交互的算法。我写了一个图表,其中包含两个小页面,每个小页面包含一个算法。
\begin{figure}[!htb]
\begin{minipage}[t]{.48\linewidth}
\algrenewcommand\alglinenumber[1]{\AlgLyn{s}{algo:FigName}}
\begin{algorithm}[H]
\end{algorithm}
\end{minipage}
\begin{minipage}[t]{.48\linewidth}
\algrenewcommand\alglinenumber[1]{\AlgLyn{c}{algo:FigName}}
\begin{algorithm}[H]
\end{algorithm}
\end{minipage}
\label{algo:FigName}
\end{figure}
我需要对两种算法的行进行编号。确切地说,客户端算法编号为 (c101,c102,..., c110,c111),服务器算法编号为 (s101,s102,..., s120,s121),其中 c-1-01 代表客户端,这是第 1 个数字,第 1 行,等等。为了以这种方式识别每行,我使用了计数允许用零填充字符串的包。我定义了两个宏:
\newcommand{\AlgLyn}[2]{#1\ref{#2}\padzeroes[\zfill]{\decimal{ALG@line}}:}
\newcommand{\AlgLyne}[3]{#1\ref{#2}\padzeroes[\zfill]{\decimalnum{\ref{#3}}}}
第一个根据需要打印算法描述中的行号。第二个用于引用算法的特定行。例如,如果已经用 \label{line:5} 标记了第 5 行,则可以通过调用 \AlgLyne{s}{algo:FigName}{line:5} 引用服务器代码的第 5 行。即使使用聪明人包括。
现在,当我尝试包含该包时,我遇到了一个问题超链接。我面临的问题有两个方面:
- 注意 s-1-05(\AlgLyn{s}{algo:FigName} 的输出),1 是由于 \AlgLyn 中的 \ref{#2} 而来的。现在,正在尝试向所有 1 添加超链接,即算法描述中打印的所有 (s101、s102、s103、...) 都已取消引用,并且向 algo:FigName 添加超链接。我不想要那样。我想要它以前的行为方式。例如,在算法描述中,将打印行号(s101、s102、s103、...),但没有任何指向 algo:FigName 的超链接。
- \AlgLyne{s}{algo:FigName}{line:5} 失败,并显示消息“缺少数字,视为零”。我不知道它失败的具体原因是什么?
如果这是我定义上述两个宏的方式的内在限制,请建议其他方法,以便我能够得到以下内容:
- 服务器-客户端交互算法,行号为(c101,…,c111),(s101,…,s121)的算法描述。
- 无兼容性问题聪明人。
- 无兼容性问题超文件。只有当我定义标签时,\AlgLyne 才会显示行号和超文件将会把超链接放置到该特定行。
我附上了两张当前情况的照片。
- 这是因为 \AlgLyn{c}{algo:FigName-3} 和 \AlgLyn{s}{algo:FigName-3} 将行号打印到算法的每一行。
- 这是因为 \AlgLyne{s}{algo:FigName-3}{line:3} 引用了算法的某一行。
注意:根据 egreg 的要求,我发布了一个示例代码。
\documentclass[12pt]{article}
\usepackage{mathtools}
\usepackage{fmtcount}
\usepackage{algpseudocode
\usepackage[lined,linesnumbered,commentsnumbered]{algorithm}
%\usepackage[hypertexnames=false]{hyperref}
\usepackage{cleveref}
\floatname{algorithm}{Algorithm}
\def\zfill{2}
\newcommand{\AlgLyn}[2]{#1\ref{#2}\padzeroes[\zfill]{\decimal{ALG@line}}:}
\newcommand{\AlgLyne}[3]{#1\ref{#2}\padzeroes[\zfill]{\decimalnum{\ref{#3}}}}
\newcommand{\rarrow}[2]{\xrightarrow{\makebox[#1]{$#2$}}}
\begin{document}
\begin{figure}[!htb]
\begin{minipage}[t]{.5\linewidth}
\algrenewcommand\alglinenumber[1]{\AlgLyn{c}{algo:FigName}}
\begin{algorithm}[H]
\caption*{Client}
\begin{scriptsize}
\begin{algorithmic}[1]
\State{$K_i\leftarrow F(K, z_1||i)$ for $i\in[0,2]$; ${\sf Msg}\leftarrow \bot$}
\Statex{\hspace*{0.64\linewidth}$\rarrow{0.5\textwidth}{\Phi}$}%
\For{$c=1,2,\ldots$} \label{cli-cstart}
\For{$\alpha\in[2,n]$}
\State{$X[c,\alpha]\leftarrow g^{F_p(K_Z,z_1||c)F_p(K_X,z_\alpha)}$}
\EndFor
\EndFor \label{cli-cend}
\end{algorithmic}
\end{scriptsize}
\end{algorithm}
\end{minipage}
\begin{minipage}[t]{.5\linewidth}
\algrenewcommand\alglinenumber[1]{\AlgLyn{s}{algo:FigName}}
\begin{algorithm}[H]
\caption*{Server}
\begin{scriptsize}
\begin{algorithmic}[1]
\State{$Answer\_Set\leftarrow \phi$}
\Statex\Statex
\For{$c=1,2,\ldots$} \label{srv-cstart}
\State{$List[c]\leftarrow c$}
\EndFor \label{srv-cend}
\end{algorithmic}
\end{scriptsize}
\end{algorithm}
\end{minipage}
\caption{Client Server Conversion}
\label{algo:FigName}
\end{figure}
\AlgLyne{c}{algo:FigName}{cli-cstart}
\AlgLyne{s}{algo:FigName}{srv-cend}
\end{document}
`
\AlgLyne{c}{algo:FigName}{cli-cstart} 生成 c102,而 \AlgLyne{s}{algo:FigName}{srv-cend} 生成 s104。我需要 [c102] 或 [s304] 超链接。如果我们取消注释 hyperref,
- 收到错误“缺失数字,视为零”
- 除了指向 c102 或 s304 行的超链接外,我们有时会在 c[1]0[2] 和 s[1]0[4] 处获得超链接。
- 上述算法的所有行有时会获得超链接,行号看起来像 c[1]01,c[1]02,c[1]03 等等。
答案1
你可以利用refcount
TeX 的算术能力\numexpr
。为了得到唯一的标识符,还\theHALG@line
应该定义。
\documentclass[12pt]{article}
\usepackage{mathtools}
\usepackage{refcount}
\usepackage{algpseudocode}
\usepackage[lined,linesnumbered,commentsnumbered]{algorithm}
\usepackage{hyperref}
\usepackage{cleveref}
\floatname{algorithm}{Algorithm}
\newcommand{\AlgLyn}[2]{%
#1\the\numexpr\getrefnumber{#2}*100+\arabic{ALG@line}\relax
}
\newcommand{\AlgLyne}[3]{%
#1\the\numexpr\getrefnumber{#2}*100+\getrefnumber{#3}\relax
}
\newcommand{\AlgoRef}[3]{%
\hyperref[#3]{#1\the\numexpr\getrefnumber{#2}*100+\getrefnumber{#3}\relax}%
}
\newcommand{\rarrow}[2]{\xrightarrow{\makebox[#1]{$#2$}}}
\begin{document}
\begin{figure}[!htb]
\begin{minipage}[t]{.5\linewidth}
\algrenewcommand\alglinenumber[1]{\AlgLyn{c}{algo:FigName}}
\makeatletter\newcommand\theHALG@line{c\arabic{ALG@line}}\makeatother
\begin{algorithm}[H]
\caption*{Client}
\scriptsize
\begin{algorithmic}[1]
\State{$K_i\leftarrow F(K, z_1||i)$ for $i\in[0,2]$; $\textsf{Msg}\leftarrow \bot$}
\Statex{\hspace*{0.64\linewidth}$\rarrow{0.5\textwidth}{\Phi}$}%
\For{$c=1,2,\ldots$} \label{cli-cstart}
\For{$\alpha\in[2,n]$}
\State{$X[c,\alpha]\leftarrow g^{F_p(K_Z,z_1||c)F_p(K_X,z_\alpha)}$}
\EndFor
\EndFor \label{cli-cend}
\end{algorithmic}
\end{algorithm}
\end{minipage}
\begin{minipage}[t]{.5\linewidth}
\algrenewcommand\alglinenumber[1]{\AlgLyn{s}{algo:FigName}}
\makeatletter\newcommand\theHALG@line{s\arabic{ALG@line}}\makeatother
\begin{algorithm}[H]
\caption*{Server}
\scriptsize
\begin{algorithmic}[1]
\State{$\mathit{Answer\_Set}\leftarrow \phi$}
\Statex\Statex
\For{$c=1,2,\ldots$} \label{srv-cstart}
\State{$\mathit{List}[c]\leftarrow c$}
\EndFor \label{srv-cend}
\end{algorithmic}
\end{algorithm}
\end{minipage}
\caption{Client Server Conversion}
\label{algo:FigName}
\end{figure}
\AlgoRef{c}{algo:FigName}{cli-cstart}
\AlgoRef{s}{algo:FigName}{srv-cend}
\end{document}