Problema de sangría del bucle doWhile

Problema de sangría del bucle doWhile

He estado intentando escribir múltiples declaraciones de bucle usando bucles do- while para el diagrama de flujo que se muestra en [1]. Sin embargo, gestionar la sangría resulta complicado. ¿Alguien puede ayudar con este tema?

\documentclass{article}
\usepackage{algorithmicx}
\usepackage{algpseudocode}

\algdef{SE}[DOWHILE]{Do}{doWhile}{\algorithmicdo}[1]{\algorithmicwhile\ #1}%

\begin{document}
\begin{algorithmic}
  \Do
    \State a,b,c,d,e,m,n
  \doWhile{$!f$} % <--- use \doWhile for the "while" at the end
  
  $g$
  
    \Do
    \State abc
    \doWhile{$!h$}
    
    $i$
    \Do
    \State Pv
    \doWhile{$!j$}
    
    $r s t $
  %  \doWhile{$!$}
  %   \State l
\end{algorithmic}
\end{document}

El problema es la sangría.

Respuesta1

Aunque los lenguajes de programación suelen ignorar los espacios en blanco en el texto del programa, según la práctica común, la sangría se utiliza en los programas para hacerlos más legibles. Para lograr este propósito, la sangría generalmente debe seguir algún estilo de manera consistente que refleje la estructura del programa.

En el código que tienes no puedo seguir la estructura de tu programa. Desafortunadamente, el algorithmicxpaquete (versu documentacion) tampoco sigue su estructura y sangra su código de una manera que no es la esperada.

En particular, yo (y algorithmicxtampoco) no puedo ver:

  1. Qué $g$es. Si se trata de una declaración abstracta, debe escribirse con la \State $g$sangría adecuada. Lo mismo se aplica a $i$y $r s t$.

  2. ¿Por qué espera que las líneas siguientes $g$tengan sangría no directamente debajo $g$sino más a la derecha? Esto sólo podría explicarse si $g$denota alguna forma de declaración de bloque (por ejemplo, a while) cuyo cuerpo se extiende hasta las líneas debajo de ella.

El resultado obtenido (luego de agregar las \Statemacros que faltan y algunas \medskippara agregar espacio vertical) refleja la estructura del programa tal como algorithmicxlo percibe:

resultado 1

Por otro lado, si realmente desea introducir una sangría arbitraria después del encabezado de un bloque, puede definir un nuevo tipo de bloque para este propósito (lo llamé \Arbitrary{header} ... \endArbitrary):

\documentclass{article}
\usepackage{algorithmicx}
\usepackage{algpseudocode}

\algdef{SE}[DOWHILE]{Do}{doWhile}{\algorithmicdo}[1]{\algorithmicwhile\ #1}%
\algblockdefx[ARBITRARY]{Arbitrary}{endArbitrary}[1]{#1}

\begin{document}
\begin{algorithmic}
  \Do
    \State a,b,c,d,e,m,n
  \doWhile{$!f$} % <--- use \doWhile for the "while" at the end
  \medskip
  \Arbitrary{$g$}
    \medskip
    \Do
    \State abc
    \doWhile{$!h$}
    \medskip
    \State $i$
    \Do
    \State Pv
    \doWhile{$!j$}
    \medskip
    \State $r s t $
  \endArbitrary
\end{algorithmic}
\end{document}

Esto resulta en:

resultado 2

Respuesta2

A continuación se muestra el pseudocódigo anidado basado en Do-While que escribí en LaTex. Alguien puede comprobarlo y usarlo para otras personas que puedan tener el mismo problema en el futuro.

\documentclass[11pt]{article}
\usepackage[fleqn]{amsmath}
\usepackage[ruled,vlined]{algorithm2e}
\PassOptionsToPackage{noend}{algpseudocode}
\usepackage{algpseudocode}

    %%%%%%%%%%%%%%%%%%
    %% DoWhile algorithm macro definition 
    \makeatletter
    \newcommand*{\algrule}[1][\algorithmicindent]{\makebox[#1][l]{\hspace*{.5em}\vrule height .75\baselineskip depth .25\baselineskip}}
    
    \newcount\ALG@printindent@tempcnta
    \def\ALG@printindent{%
        \ifnum \theALG@nested>0% is there anything to print
        \ifx\ALG@text\ALG@x@notext% is this an end group without any text?
        % do nothing
        \addvspace{-3pt}% FUDGE for cases where no text is shown, to make the rules line up
        \else
        \unskip
        % draw a rule for each indent level
        \ALG@printindent@tempcnta=1
        \loop
        \algrule[\csname ALG@ind@\the\ALG@printindent@tempcnta\endcsname]%
        \advance \ALG@printindent@tempcnta 1
        \ifnum \ALG@printindent@tempcnta<\numexpr\theALG@nested+1\relax% can't do <=, so add one to RHS and use < instead
        \repeat
        \fi
        \fi
    }
\usepackage{etoolbox}
% the following line injects our new indent handling code in place of the default spacing
\patchcmd{\ALG@doentity}{\noindent\hskip\ALG@tlm}{\ALG@printindent}{}{\errmessage{failed to patch}}
\makeatother
% end vertical rule patch for algorithmicx
\algdef{SE}[DOWHILE]{Do}{doWhile}{\algorithmicdo}[1]{\algorithmicwhile\ #1}%

\begin{algorithm}%\captionsetup{labelfont={sc,bf}, labelsep=newline}
    \caption{Workspace boundary determination}
    \label{alg:PoEG}    
    \begin{algorithmic}
        \State Input $z_0,~z_f,~n,~m$
        \State \quad \quad ~ $\Delta_z = \dfrac{z_0-z_f}{n}, \textit{tol}$
        \State \quad \quad ~ $\varepsilon_f= 2\pi~, \Delta\varepsilon = \dfrac{\varepsilon_f}{m}$
        \State \quad \quad ~ $k_{\textup{max}}, \Delta\alpha_0, i = j=1$
        \medskip
        \State Output $\boldsymbol{\theta}, \boldsymbol{\psi}, \boldsymbol{z} $
        \medskip
        \State initialize ~$z \gets z_0,~ \psi=\theta =\gets \emptyset$
        \Do
            \Do 
                \Do
                    \Do 
                        \State $\Delta\psi = \psi + \Delta\alpha c\varepsilon$
                        \State $\Delta\theta = \theta + \Delta\alpha s\varepsilon $ 
                        \State $\psi = \psi +\Delta\varepsilon$
                        \State $\theta = \psi + \Delta\varepsilon$ 
                        \State Compute $\boldsymbol{J}_{dh}$ 
                        \State $k = cond(\boldsymbol{J}_{dh})$
        
                    \doWhile{$k<k_{max}$}
        
                    \State $\psi = \psi -\Delta\varepsilon$
                    \State $\theta = \psi - \Delta\varepsilon$ 
        
                    \State $\Delta\alpha = \Delta\alpha/2$
        
                \doWhile{$\Delta\alpha > tol $}
                \State $\psi(i,j) = \psi $
                \State $\theta(i,j) = \theta $
        
                \State $ j =j+1$
                \State $\Delta\alpha = \Delta\alpha_0$
                \State $\varepsilon = \varepsilon + \Delta\varepsilon$
            \doWhile{$\varepsilon < 2\pi$}
        
            \State $ \theta =0$
            \State $\psi =0$
            \State $\varepsilon =0$
            \State $\Delta\alpha=\Delta\alpha_0$
            \State $i=i+1$
            \State $z_i=z+\Delta_z$

        \doWhile{$z<z_f$} \\ % <--- use \doWhile for the "while" at the end
        plot$(\boldsymbol{\psi},\boldsymbol{\theta},\boldsymbol{z})$\\ \medskip Note: $s$ and $c$ stands for sine and cosine, respectively.
        %\endArbitrary
    \end{algorithmic}
\end{algorithm}

\end{document} 

información relacionada