在下面的代码中,我想将两个列表显示在同一个环境中,并以一个垂直指定的间距显示。
我怎样才能做到这一点 ?
代码
\documentclass{article}
\usepackage{tikz}
\usepackage{xstring}
\tikzset{
raw sort entry/.style={rectangle, thick, draw, node distance=1.5em},
sort entry black/.style={raw sort entry, black, fill=white},
sort entry blackgray/.style={raw sort entry, black, fill=gray!25},
s1/.style={raw sort entry, red, fill=yellow!30},
s2/.style={raw sort entry, blue, fill=green!20},
s3/.style={raw sort entry, violet, fill=orange!25}
}
\newcommand*{\List}[2][sort entry black]{%
\par\noindent%
\edef\listtoprocess{#2}%
\def\ListToProcess{}%
\begin{tikzpicture}[inner sep=2pt, outer sep=0]
\foreach \content in \listtoprocess{
\IfSubStr{\content}{/}{% true
\xdef\ListToProcess{\ListToProcess,\content}
}{% false
\xdef\ListToProcess{\ListToProcess,#1/\content}
}
}
\StrGobbleLeft{\ListToProcess}{1}[\ListToProcess]% removes the first comma (\listToProcess is empty at the start)
\foreach [count=\i] \Style/\Value in \ListToProcess {
\ifnum\i=1\relax
\node [raw sort entry, \Style] (sortnode\i) {\Value};
\else
\node [raw sort entry, right of=sortnode\number\numexpr\i-1\relax, \Style] (sortnode\i) {\Value};
\fi
}
\end{tikzpicture}%
}
\begin{document}
\List[sort entry blackgray]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}
\bigskip
\List[sort entry blackgray]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}
\end{document}
答案1
我只是重复使用代码TikZ 箭头用于显示排序算法并添加了键
previous row
和previous col
我用库提供的right of=…
语法替换了旧语法。(→right=… of …
positioning
PGF/TikZ 中“right of=”和“right=of”之间的区别)
值.5em
(水平) 和1em
(垂直) 在宏中是硬编码的\List
。
previous row
在处理一行中的所有节点结束时,键会自动设置为当前行名,以便在下面的\List
调用中previous row
已经设置为前一行名(参见第一个示例)。
使用上述按键可以进行手动放置。参见第二个示例(previous row=a
实际上并不需要,但为了完整性还是添加了)。
代码
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usepackage{xstring}
\usetikzlibrary{calc,positioning}
\tikzset{
raw sort entry/.style={rectangle, thick, draw, node distance=1.5em},
sort entry black/.style={raw sort entry, black, fill=white},
sort entry blackgray/.style={raw sort entry, black, fill=gray!25},
s1/.style={raw sort entry, red, fill=yellow!30},
s2/.style={raw sort entry, blue, fill=green!20},
s3/.style={raw sort entry, violet, fill=orange!25},
/qrr/default/.style=sort entry black,
name row/.initial={},
previous row/.initial={},
previous col/.initial={1},
default/.style={/qrr/default/.style={#1}},
|-|/.style={
to path={
let \p1=(\tikztostart),
\p2=(\tikztotarget) in
-- (\x1,.5*\y1+.5*\y2) -- (\x2,.5*\y1+.5*\y2) \tikztonodes
-- (\tikztotarget)
}
}
}
\newcommand*{\List}[2][default=sort entry black]{%
\tikzset{#1}%
\edef\listtoprocess{#2}%
\pgfkeysgetvalue{/tikz/name row}{\rowname}%
\pgfkeysgetvalue{/tikz/previous row}{\previousRow}%
\pgfkeysgetvalue{/tikz/previous col}{\previousCol}%
\def\ListToProcess{}%
\foreach \content in \listtoprocess{
\IfSubStr{\content}{/}{% true
\xdef\ListToProcess{\ListToProcess,\content}
}{% false
\xdef\ListToProcess{\ListToProcess,{/qrr/default}/\content}
}
}
\StrGobbleLeft{\ListToProcess}{1}[\ListToProcess]% removes the first comma (\listToProcess is empty at the start)
\foreach [count=\i] \Style/\Value in \ListToProcess {
\ifnum\i=1\relax
\expandafter\ifx\expandafter\relax\previousRow\relax
\node [raw sort entry, \Style] (\rowname-\i) {\Value};
\else
\node [raw sort entry, \Style, below=1em of \previousRow-\previousCol] (\rowname-\i) {\Value};
\fi
\else
\node [raw sort entry, right=.5em of \rowname-\number\numexpr\i-1\relax, \Style] (\rowname-\i) {\Value};
\fi
}
\tikzset{previous row/.expand once=\rowname}
}
\begin{document}
\begin{tikzpicture}
\List[default=sort entry blackgray, name row=a]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}
\List[default=sort entry blackgray, name row=b]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}
\draw[thick, shorten >=\pgflinewidth,->] (a-7) to[|-|] (b-9);
\end{tikzpicture}
\begin{tikzpicture}
\List[default=sort entry blackgray, name row=a]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}
\List[default=sort entry blackgray, name row=b, previous row=a, previous col=3]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}
\draw[thick, shorten >=\pgflinewidth,->] (a-7) to[|-|] (b-9);
\end{tikzpicture}
\end{document}