我正在使用这些包
\usepackage{algpseudocode}
\usepackage{algorithm}
生成以下算法的伪代码:
\begin{algorithm}
\centering
\caption{Octree based search algorithm}
\label{alg:octree-search}
{\small
\begin{algorithmic}
\Function{octree-search}{node=root, point, squaredDistance, nearestPoint=distant point}
\For{octants of node}
\State get subNode
\State pointSphere = sphere around point using squaredDistance
\If{subNode has child nodes}
\State subNodeBox = Axis Aligned Bound Box (subNode)
\If{subNodeBox overlaps with pointSphere}
\State \Call{octree-search}{subNode, point, squaredDistance, nearestPoint}
\EndIf
\ElsIf{subNode is a leaf node}
\State leafNodeBox = Axis Aligned Bounding Box (node)
\If{leafNodeBox overlaps with pointSphere}
\State minimalPoint = distant point
\For{shape in node shapes}
\State distanceToShape, shapePoint = \Call{signed distance}{shape, point}
\If{$\|\text{distanceToShape}\| < \|\text{minimalDistance}\|$}
\State minimalPoint = shapePoint
\EndIf
\EndFor
\State nearestPoint = minimalPoint \Comment return point of the recursive search
\EndIf
\EndIf
\EndFor
\EndFunction
\end{algorithmic}
}
\end{algorithm}
我使用\small
算法字体大小。不幸的是,页面宽度会导致问题并引入换行符,如下所示:
由于伪代码(以及一般干净的代码)的全部要点是使用合理的名称(例如用 squaredDistance 代替 sqD),我想重新格式化 algpseudocode 生成的输出,以便函数声明使其看起来像这样:
function OCTREE-SEARCH(
node = root,
point,
squaredDistance,
nearestPoint = distant point
)
没有难看的换行符。
编程旁注
我知道函数最好是单子/二元函数,但此时我正在将我的代码与遗留代码进行交互,无法更改函数签名。因此,减少参数数量不是一个选择。
编辑
另外,之前的大片水平空间能Comment
以某种方式缩短吗?
答案1
以下示例显示如何在函数定义中添加换行符。这可以通过一对新命令\FunctionTwo
和来完成\EndFunctionTwo
,分别类似于\Function
和\EndFunction
。在此解决方案中,每个参数前面都必须有一个\State
充当手动换行符的命令。
\documentclass{article}
\usepackage{algpseudocode}
\usepackage{algorithm}
\usepackage{amsmath}
\usepackage{calc}
\usepackage{suffix}
\algblockdefx[funcDef]{funcStart}{funcEnd}[1]{\algorithmicfunction\ \textproc{#1}(}{)}
\algblockdefx[funcStarDef]{funcStarStart}{funcStarEnd}[1]{\textproc{#1}(}{)}
\algblockdefx[funcTwo]{funcTwoStart}{EndFunctionTwo}{\vspace{-\baselineskip}}{\algorithmicend\ \algorithmicfunction}
\newcommand{\FunctionTwo}[2]{\funcStart{#1} #2 \funcEnd \funcTwoStart }
\newlength{\skipamount}
\newcommand{\CallTwo}[3][]{%
\setlength{\skipamount}{\widthof{#1\textproc{#2}(}}%
#1\textproc{#2}(#3)}
\newcommand{\StateTwo}{\State \hspace{\skipamount}}
\WithSuffix\newcommand\CallTwo*[2]{\funcStarStart{#1} #2 \funcStarEnd }
\WithSuffix\newcommand\FunctionTwo*[2]{\State \CallTwo[\algorithmicfunction\ ]{#1}{#2} \funcTwoStart }
\WithSuffix\newcommand\EndFunctionTwo*{\EndFunctionTwo}
\begin{document}
\begin{algorithm}
\centering
\caption{Octree based search algorithm}
\label{alg:octree-search}
{\small
\begin{algorithmic}
\FunctionTwo{octree-search}{\State node=root, \State point, \State squaredDistance, \State nearestPoint=distant point}
\For{octants of node}
\State get subNode
\State pointSphere = sphere around point using squaredDistance
\If{subNode has child nodes}
\State subNodeBox = Axis Aligned Bound Box (subNode)
\If{subNodeBox overlaps with pointSphere}
\State \Call{octree-search}{subNode, point, squaredDistance, nearestPoint}
\EndIf
\ElsIf{subNode is a leaf node}
\State leafNodeBox = Axis Aligned Bounding Box (node)
\If{leafNodeBox overlaps with pointSphere}
\State minimalPoint = distant point
\For{shape in node shapes}
\State distanceToShape, shapePoint = \Call{signed distance}{shape, point}
\If{$\|\text{distanceToShape}\| < \|\text{minimalDistance}\|$}
\State minimalPoint = shapePoint
\EndIf
\EndFor
\State nearestPoint = minimalPoint \Comment return point of the recursive search
\EndIf
\EndIf
\EndFor
\EndFunctionTwo
\end{algorithmic}
}
\end{algorithm}
\begin{algorithm}
\centering
\caption{Alternative formatting}
\label{alg:octree-search2}
{\small
\begin{algorithmic}
\FunctionTwo*{octree-search}{node=root, \StateTwo point, \StateTwo squaredDistance, \StateTwo nearestPoint=distant point}
\State \CallTwo{octree-search}{subNode, point, \StateTwo squaredDistance, nearestPoint}
\State \CallTwo{octree-search}{subNode, \StateTwo point, \StateTwo squaredDistance, \StateTwo nearestPoint}
\CallTwo*{octree-search}{\State subNode, \State point, \State squaredDistance, \State nearestPoint}
\EndFunctionTwo*
\end{algorithmic}
}
\end{algorithm}
\end{document}
在函数定义中添加换行符后,整个算法如下所示:
第二张图片显示了调用和函数定义的替代格式选择。请参阅示例代码。请注意,\CallTwo
with\StateTwo
通常不能嵌套。这是因为只有一个变量\skipamount
用于缩进级别。这个答案对我来说是一个有用的资源。
注释前有空格
该\Comment
命令似乎将注释文本向右对齐。如果可用空间很大而注释文本很短,这将在代码行和注释之间留下很大的间隙。减少间隙的一个解决方案是假装注释文本需要的空间比实际需要的更多:
\State nearestPoint = minimalPoint \Comment \makebox[\width + 1cm][l]{return point of the recursive search}
这条线会将间隙缩小一厘米。这里必须通过实验找到合适的填充长度。这个答案由 Werner 编写的关于使用calc
包进行长度运算的程序,正如我的示例所用到的。