Problem mit der Einrückung der doWhile-Schleife

Problem mit der Einrückung der doWhile-Schleife

Ich habe versucht, mehrere Schleifenanweisungen mit do-while-Schleifen für das in [1] gezeigte Flussdiagramm zu schreiben. Die Verwaltung der Einrückungen ist jedoch schwierig. Kann mir jemand bei diesem Problem helfen?

\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}

Das Problem ist die Einrückung.

Antwort1

Obwohl Leerzeichen in Programmtexten von Programmiersprachen normalerweise ignoriert werden, werden Einrückungen in Programmen üblicherweise verwendet, um sie lesbarer zu machen. Um dieses Ziel zu erreichen, sollten Einrückungen im Allgemeinen einem einheitlichen Stil folgen, der die Struktur des Programms widerspiegelt.

In dem Code, den Sie haben, kann ich die Struktur Ihres Programms nicht nachvollziehen. Leider ist das algorithmicxPaket (sieheseine Dokumentation) folgt ebenfalls nicht Ihrer Struktur und rückt Ihren Code auf eine Weise ein, die nicht Ihren Erwartungen entspricht.

Insbesondere kann ich (und algorithmicxkann auch) nicht sehen:

  1. Was $g$ist. Wenn es sich um eine abstrakte Aussage handelt, sollte sie so geschrieben werden, dass \State $g$sie richtig eingerückt ist. Dasselbe gilt für $i$und $r s t$.

  2. Warum Sie erwarten, dass die Zeilen darunter nicht direkt darunter , sondern weiter rechts $g$eingerückt werden ? Dies könnte nur erklärt werden, wenn es sich um eine Art Blockanweisung (z. B. a ) handelt, deren Hauptteil sich bis zu den Zeilen darunter erstreckt.$g$$g$while

Das erhaltene Ergebnis (nach dem Hinzufügen der fehlenden \StateMakros und einiger \medskipzum Hinzufügen von vertikalem Abstand) spiegelt die Struktur des Programms wider, wie algorithmicxes wahrgenommen wird:

Ergebnis 1

Wenn Sie andererseits tatsächlich beliebige Einrückungen nach einer Blocküberschrift einfügen möchten, können Sie zu diesem Zweck einen neuen Blocktyp definieren (ich habe ihn genannt \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}

Das führt zu:

Ergebnis 2

Antwort2

Unten ist der verschachtelte Do-While-basierte Pseudocode, den ich in LaTex geschrieben habe. Jemand kann ihn überprüfen und er kann von anderen verwendet werden, die in Zukunft möglicherweise dasselbe Problem haben.

\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} 

verwandte Informationen