Como posso desenhar diagramas de strings CS?

Como posso desenhar diagramas de strings CS?

Existe um pacote específico para renderizar diagramas de strings (strings de CS, não strings de física) como na figura abaixo?

diagrama de cordas

Alternativamente, como você criaria tal figura? Você pode fornecer um exemplo (muito) mínimo?

Responder1

Aqui está uma maneira de fazer isso com Tikz.

Ideias básicas:

  • desenhe algumas linhas
  • coloque alguns \nodes para os rótulos abaixo
  • \drawalguns caminhos decorados acima
  • lembre-se de itens relevantes coordinatepara apoiar essas ações
  • defina /.styles conforme você simplifica o código e faz alterações de parâmetros em um único lugar
  • tentando uma abordagem equilibrada, que não seja muito difícil de seguir como um novato E usando alguns recursos de caminho para um código melhor

resultado

Linhas:

Vamos digerir o primeiro.

    \draw[bar] (0,0) coordinate (A) -- (1.5,0)  coordinate (B) node[a]{$a$};

Pense em desenhar uma linha simples, primeiro em coordenadas absolutas:

    \draw (0,0) -- (1.5,0);

Como Tikzse trata de caminhos, que terminam com ponto e vírgula ;, poderíamos adicionar um nó, eliminando o \antes do caminho terminar. Então este coloca um nó com texto (rótulo) após ter chegado em (1.5,0); aceita texto com algum estilo a, ou seja, em modo matemático $a$:

    \draw (0,0) -- (1.5,0) node[a]{$a$};

Coloque informações de estilo para a linha na frente e deixe na seção de estilo no início para especificar em detalhes o que desenhar aqui:

    \draw[bar] (0,0) -- (1.5,0) node[a]{$a$};

Por fim, adicione a \coordinateinstrução ao caminho, para lembrar determinados locais, E elimine \porque ainda está no mesmo caminho a ser desenhado. Aí está você:

    \draw[bar] (0,0) coordinate (A) -- (1.5,0)  coordinate (B) node[a]{$a$};

Os outros caminhos são semelhantes, usando uma mistura de movimentos relativos --++(1.5,0), coordenadas absolutas e usando o conhecimento sobre a largura mínima desses nós, definida aqui como 5mm. Isso pode ser feito de forma mais sistemática, com certeza.

Etiquetas abaixo:

    % ~~~ labels below ~~~~~~~~~~
    \node[mth] at                (A) {$1$};
    \node[mth] at ([xshift=-2.5mm]C) {$f(i) + 1$};

Isso é bastante simples. A primeira linha coloca o texto $1$na posição lembrada (A), usando style mth, o que desloca o texto um pouco para baixo na direção y.

O segundo é bem parecido, exceto alguma complicação introduzida ao colocar o nó do $a$jeito que eu fiz. Portanto, uma maneira de corrigir a posição é usar (C)e deslocá-la um pouco para trás (metade da largura mínima):

([xshift=-2.5mm]C).

Sobreposição:

    % ~~~ labels above ~~~~
    \draw[decorate,blue] ([ys]A) -- ([ys]B) node[alf]{$\alpha$};
    \draw[decorate,blue] ([ys]D) -- ([ys]E) node[alf]{$\alpha$};

Ele combina conceitos acima, enquanto usa decorate, que é fornecido pela tikz-library decorations.pathreplacing:

  • ele desenha um caminho acima (A) para cima (B)
  • substitui-o por uma cinta
  • Em azul
  • colocando um nó no meio e um pouco acima para $\alpha$.

Bloco de estilo:

 \begin{tikzpicture}[
    a/.style={anchor=west,minimum width=5mm},   % for the node containing "a"
    bar/.style={{Bar[]}-{Bar[]}},               % start- and end-tipps as Bars
    bar2/.style={-{Bar[]}},                     % only end-tipp as bar
    mth/.style={yshift=-5mm},                   % for placing the math-labels
    decoration=brace,                           % the overbrace
    alf/.style={midway,yshift=3mm},             % placing \alpha there
    ys/.style={yshift=5mm},                     % shortcut for these yshifts
 ]

Pelo menos para mim esta parte se desenvolve à medida que avanço, por exemplo, assim:

  • lembre-se da parte da linha descrita acima
  • coloque opções de estilo úteis diretamente para drawenode
  • eles são muito longos? OU precisarei deles pelo menos duas vezes?
  • então mova-os aqui, com alguns nomes úteis
  • então, mais tarde, eu poderia facilmente ajustar todas essas mudanças de rótulo, etc., aqui mesmo

Código:

\documentclass[10pt,border=3mm,tikz]{standalone}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{decorations.pathreplacing}

\begin{document}
 \begin{tikzpicture}[
    a/.style={anchor=west,minimum width=5mm},   % for the node containing "a"
    bar/.style={{Bar[]}-{Bar[]}},               % start- and end-tipps as Bars
    bar2/.style={-{Bar[]}},                     % only end-tipp as bar
    mth/.style={yshift=-5mm},                   % for placing the math-labels
    decoration=brace,                           % the overbrace
    alf/.style={midway,yshift=3mm},             % placing \alpha there
    ys/.style={yshift=5mm},                     % shortcut for these yshifts
 ]
    % ~~~ lines ~~~~~~~~~~~~
    \draw[bar] (0,0) coordinate (A) -- (1.5,0)  coordinate (B) node[a]{$a$};
    \draw[bar] (2,0) coordinate (C) -- (3.5,0)  coordinate (D);
    \draw[bar2](3.5,0)              --++(1.5,0) coordinate (E) node[a]{$a$};
    \draw[bar] (5.5,0)              --++(1.5,0)                node[a]{$P$};
    
    % ~~~ labels below ~~~~~~~~~~
    \node[mth] at                (A) {$1$};
    \node[mth] at ([xshift=-2.5mm]C) {$f(i) + 1$};
    \node[mth] at                (D) {$i - f(i) + 1$};
    \node[mth] at ([xshift=+2.5mm]E) {$i + 1$};
    
    % ~~~ labels above ~~~~
    \draw[decorate,blue] ([ys]A) -- ([ys]B) node[alf]{$\alpha$};
    \draw[decorate,blue] ([ys]D) -- ([ys]E) node[alf]{$\alpha$};
    
 \end{tikzpicture}
\end{document}

informação relacionada