森林节点中没有保存箱的 Tikzpictures

森林节点中没有保存箱的 Tikzpictures

我能够使用下面的 MWE 生成以下树。它使用命令创建 tikzpictures\drawtape并将它们放入保存框中,而保存框又可以直接用作环境中节点的内容forest

一个简单的计算树

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{positioning}

\newcommand{\drawtape}[3]{
\begin{tikzpicture}[cell/.style={minimum size=0.5cm,outer sep=0pt,draw,rectangle,node distance=0pt,text height=1.5ex}]
\foreach \x [count=\xi] in {#1} {
    \ifnum \xi=1
        \node[cell] (\xi) {$\x$};
    \else
        \pgfmathtruncatemacro{\xil}{\xi - 1}
        \node[cell] (\xi) [right=of \xil] {$\x$};
    \fi
}
\node[font=\footnotesize] [below=0cm of #2, xshift=0.03em] {$#3$};
\end{tikzpicture}
}

\newsavebox{\treeroot}
\newsavebox{\treeone}
\newsavebox{\treetwo}

\usepackage{forest}

\begin{document}

\savebox{\treeroot}{\drawtape{1, 1, 1}{1}{1}}
\savebox{\treeone}{\drawtape{0, 1, 1, 1}{1}{2}}
\savebox{\treetwo}{\drawtape{1, 1, 1}{2}{1}}

\begin{forest}
    [\usebox{\treeroot}
        [\usebox{\treeone}]
        [\usebox{\treetwo}]
    ]
\end{forest}

\end{document}

对于像图中这样的小树来说,这没问题,但如果我想创建更大的树,那么我必须手动创建的保存箱数量很快就会变得非常繁琐。理想情况下,我希望能够编写一个forest像下面这样的环境。有什么办法可以实现这一点吗?

\begin{forest}
    [\drawtape{1, 1, 1}{1}{1}
        [\drawtape{0, 1, 1, 1}{1}{2}]
        [\drawtape{1, 1, 1}{2}{1}]
    ]
\end{forest}

答案1

如果您愿意考虑使用稍微不同的语法,您可以使用简单的表格以及append after command

\documentclass{article}
\usepackage{array}
\newcolumntype{C}[1]{>{\centering\arraybackslash}p{#1}}
\usepackage{forest}
\tikzset{drawtape/.style n args={3}{node contents={
\begin{tabular}{|*{10}{@{}C{5mm}@{}|}}
\hline
#1
\hline
\end{tabular}},append after command={
([xshift=#2*5mm-1mm]\tikzlastnode.south west) 
node[anchor=north,inner sep=0pt,font=\footnotesize]{#3}}}}

\begin{document}

\begin{forest}
for tree={l sep+=2ex,edge={shorten <=2.5ex}}
    [,drawtape={1& 1& 1\\}{1}{1}
        [,drawtape={0 & 1 & 1& 1\\}{1}{2}]
        [,drawtape={1& 1& 1\\}{3}{1}]
    ]
\end{forest}
\end{document}

在此处输入图片描述

答案2

感谢 Zarko 向我指出使用多部分节点,我得出了以下解决方案:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{shapes.multipart, positioning}

\usepackage{xinttools}

\usepackage{forest}

\def\numname#1{%
    \ifcase#1 \or one\or two\or three\or four\or five\or six\or seven\or eight\or nine\or ten\or eleven \or twelve\or thirteen\or fourteen\or fifteen\or sixteen\or seventeen\or eighteen\or nineteen\or twenty\fi%
}

\newcounter{cellnum}
\newcommand{\tape}[1]{%
    \setcounter{cellnum}{1}
    \xintFor* ##1 in {#1} \do {%
        \nodepart[text width=1.5ex, align=center]{\numname{\value{cellnum}}} $##1$%
        \stepcounter{cellnum}%
    }
    \addtocounter{cellnum}{-1}%
}

\begin{document}

\begin{forest}
    for tree={
        delay={
            content={\tape{#1}}
        },
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=\value{cellnum},
        rectangle split part align=base,
        draw,
        l sep=6ex,
        s sep=2em,
        anchor=parent,
        edge path={
            \noexpand\path[draw] 
            ([yshift=-2.5ex]!u.children) -- ([yshift=1ex].parent);
        },
        head/.style n args=2{
            tikz={\node[below=0cm of .\numname{#1} south, font=\scriptsize]{$#2$};}
        }
    }
    [111, head={1}{1}
        [0111, head={1}{2}]
        [111, head={2}{1}]
    ]
\end{forest}

\end{document}

不幸的是,边缘路径长度不等存在问题。我会寻求解决方案,并在找到解决方案后更新此答案。编辑:使用anchor=parentinfor tree解决了这个问题。

一个简单的计算树

相关内容