我需要简洁地可视化给定字符串的多个可能相交的字符串段。例如,以下是二进制字符串中所有回文出现的伪代码:
S = 1 0 1 0 0 1 0 0
----- ---------
- ----------- -
----- -----
- ------- ---
- --- - -
- -
我想以紧凑的方式在 LaTeX 中呈现它,最好使用可读的 LaTeX 代码。
我最好的尝试是使用下划线,但它只能覆盖不相交的线段,强加一定的垂直顺序,并且在代码中不是特别易读:
\begin{align*}
\let\u\underline
S = \u{\u{1}\,\u{0}\,\u{1}}\,\u{\u{\u{0}\,\u{0}}\,\u{1}\,\u{\u{0}\,\u{0}}}
\end{align*}
有没有办法使用下划线或其他技术来可视化相交的线段?如果是这样,我可以使用漂亮的代码布局(如上所示或类似)吗?
编辑:另一个挑战是还要能够可视化两个连续符号之间的空子字符串。例如,以下是以索引 4 结尾/开始的回文S
,包括一个空字符串(退化回文):
S = 1 0 1 0 0 1 0 0
-
- -
----- -----
请注意,这也可以通过断开字符串来实现,但这通常是不可取的:
S = 1 0 1 0 _ 0 1 0 0
- -
----- -----
答案1
建议命令的语法是
\segments[<width>]{<string>}{<segments>;<segments>;...}
其中<width>
是单元格的宽度(默认为 1em),<string>
是要排版的字符串,<segments>
是要加下划线的单元格列表。此类列表由单个数字组成, 或<number>-<number>
表示要跨越的单元格。
请注意,这将忽略两个参数中的空格(但输入范围时不应有空格),因此也可以像这样输入示例
\segments{1 0 1 0 0 1 0 0}{
1, 2, 3, 4, 5, 6, 7, 8 ;
1-3, 4-5, 7-8 ;
4-8
}
如果愿意的话。
\documentclass{article}
\usepackage{xparse,array,booktabs}
\ExplSyntaxOn
\NewDocumentCommand{\segments}{O{1em}mm}
{% #1 = width of cells, #2 = string, #3 = list of underlines
\group_begin:
\renewcommand{\arraystretch}{0}
\fizruk_segments:n { #3 }
\begin{tabular}[t]{ @{} *{ \tl_count:n { #2 } }{ w{c}{#1} @{} } }
\seq_set_split:Nnn \l__fizruk_string_seq { } { #2 }
\seq_use:Nn \l__fizruk_string_seq { & } \\
\tl_use:N \l__fizruk_segments_tl
\end{tabular}
\group_end:
}
\seq_new:N \l__fizruk_string_seq
\seq_new:N \l__fizruk_stages_seq
\tl_new:N \l__fizruk_segments_tl
\cs_new_protected:Nn \fizruk_segments:n
{
\tl_clear:N \l__fizruk_segments_tl
\seq_set_split:Nnn \l__fizruk_stages_seq { ; } { #1 }
\seq_map_function:NN \l__fizruk_stages_seq \__fizruk_segment_row:n
}
\cs_new_protected:Nn \__fizruk_segment_row:n
{
\clist_map_function:nN { #1 } \__fizruk_add_segment:n
\tl_put_right:Nn \l__fizruk_segments_tl { \morecmidrules }
}
\cs_new_protected:Nn \__fizruk_add_segment:n
{
\str_if_in:nnTF { #1 } { - }
{
\tl_put_right:Nn \l__fizruk_segments_tl { \cmidrule(l{2pt}r{2pt}){#1} }
}
{
\tl_put_right:Nn \l__fizruk_segments_tl { \cmidrule(l{2pt}r{2pt}){#1-#1} }
}
}
\ExplSyntaxOff
\begin{document}
\[
S=\segments{10100100}{1,2,3,4,5,6,7,8;1-3,4-5,7-8; 4-8}
\]
\end{document}
以下是输出
\[
S=\segments{10100100}{
1-3,4-8;
1,2-7,8;
2-4,5-7;
2,3-6,7-8;
3,4-5,6,7;
4,5
}
\]
通过以下修改,您可以在两个符号之间插入一条线,.3
如果您希望它跟在第三个符号后面,则用 表示。
\documentclass{article}
\usepackage{xparse,array,booktabs}
\ExplSyntaxOn
\NewDocumentCommand{\segments}{O{1em}mm}
{% #1 = width of cells, #2 = string, #3 = list of underlines
\group_begin:
\renewcommand{\arraystretch}{0}
\dim_set:Nn \l__fizruk_cell_dim { #1 }
\fizruk_segments:n { #3 }
\tl_show:N \l__fizruk_segments_tl
\begin{tabular}[t]{ @{} *{ \tl_count:n { #2 } }{ w{c}{#1} @{} } }
\seq_set_split:Nnn \l__fizruk_string_seq { } { #2 }
\seq_use:Nn \l__fizruk_string_seq { & } \\
\tl_use:N \l__fizruk_segments_tl
\end{tabular}
\group_end:
}
\dim_new:N \l__fizruk_cell_dim
\seq_new:N \l__fizruk_string_seq
\seq_new:N \l__fizruk_stages_seq
\tl_new:N \l__fizruk_segments_tl
\cs_new_protected:Nn \fizruk_segments:n
{
\tl_set:Nn \l__fizruk_segments_tl { \addlinespace[3pt] }
\seq_set_split:Nnn \l__fizruk_stages_seq { ; } { #1 }
\seq_map_function:NN \l__fizruk_stages_seq \__fizruk_segment_row:n
}
\cs_new_protected:Nn \__fizruk_segment_row:n
{
\clist_map_function:nN { #1 } \__fizruk_add_segment:n
\tl_put_right:Nn \l__fizruk_segments_tl { \morecmidrules }
}
\cs_new_protected:Nn \__fizruk_add_segment:n
{
\str_if_in:nnTF { #1 } { - }
{
\tl_put_right:Nx \l__fizruk_segments_tl { \__fizruk_cmidrule:nn { /5 } { #1 } }
}
{
\str_if_in:nnTF { #1 } { . }
{
\tl_put_right:Nx \l__fizruk_segments_tl
{
\__fizruk_cmidrule:ne { *4/5 } { \tl_tail:n { #1 }-\int_eval:n { \tl_tail:n { #1 }+1 } }
}
}
{
\tl_put_right:Nx \l__fizruk_segments_tl { \__fizruk_cmidrule:nn { /5 } { #1-#1 } }
}
}
}
\cs_new:Nn \__fizruk_cmidrule:nn
{
\exp_not:N\cmidrule(l{\dim_eval:n{\l__fizruk_cell_dim #1}}r{\dim_eval:n{\l__fizruk_cell_dim #1}}){#2}
}
\cs_generate_variant:Nn \__fizruk_cmidrule:nn { ne }
\ExplSyntaxOff
\begin{document}
\[
S=\segments{10100100}{1,2,3,4,5,6,7,8;1-3,4-5,7-8; 4-8}
\]
\[
S=\segments{10100100}{
1-3,4-8;
1,2-7,8;
2-4,5-7;
2,3-6,7-8;
3,4-5,6,7;
4,5
}
\]
\[
S = \segments{1 0 1 0 0 1 0 0}{
.3;
3,4;
2-4,5-7
}
\]
\end{document}
答案2
我这里只做了三行,但是
\documentclass{article}
\usepackage{booktabs}
\begin{document}
\[
\begin{array}{r@{}*{10}{c}}
S={}&1&0&1&0&0&1&0&0 \\
\cmidrule(r){2-4}\cmidrule(l){5-9}
\morecmidrules
\cmidrule(r){2-2}\cmidrule(lr){3-8}\cmidrule(l){9-9}
\morecmidrules
\cmidrule(r){3-5}\cmidrule(l){6-7}
\end{array}
\]
\end{document}
答案3
使用 ti 的解决方案钾Z.符号如下:在\ourInfo
数组中,每个单元格对应:{等级, 起始角色索引(含), 结束角色索引(含)}
\documentclass[margin=1cm, tikz]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=0.5]
\def\binaryString{{1, 0, 1, 0, 0, 1, 0, 0}}
%Notation: {level, starting character index (including), finish character index(including)}
%NOTE! Everyting is zero-based
\def\ourInfo{{
% Level 0
{0,0,2},{0,3,7},
% Level 1
{1,0,0},{1,1,6},{1,7,7},
% Level 2
{2,1,3},{2,4,7},
% Level 3
{3,1,1},{3,2,5},{3,6,7},
% Level 4
{4,2,2},{4,3,4},{4,5,5},{4,6,6},
% Level 5
{5,3,3},{5,4,4}
}}
\pgfmathsetmacro{\length}{15}% Zero based.
\foreach \i in {0, ..., 7}{
\draw[] (\i,0) node{\pgfmathparse{\binaryString[\i]}\pgfmathresult};
}
\foreach \i in {0, ..., \length}{
\pgfmathsetmacro{\level}{\ourInfo[\i][0]}
\pgfmathsetmacro{\start}{\ourInfo[\i][1]}
\pgfmathsetmacro{\finish}{\ourInfo[\i][2]}
\draw[thick] (\start-0.3,-0.5-\level/2)--(\finish+0.3,-0.5-\level/2){};
}
\end{tikzpicture}
\end{document}