使用 \iftoggle 实现 TeX 嵌套循环

使用 \iftoggle 实现 TeX 嵌套循环

这个论坛帮助我理解了如何在 TeX 中使用嵌套循环,但现在我在使用\iftoggle(来自etoolbox包的)循环时遇到了麻烦。我的目标是有一个切换开关,它可以在循环进行时跟踪“偶数”或“奇数”状态,其中状态由循环内的代码更新。但是,下面显示的示例没有按我预期的方式工作,因为每次回到外循环时,切换开关似乎都会设置为“偶数”。为什么会发生这种情况,我该如何防止它/有什么更好的方法来实现此功能?

\documentclass{book}
\usepackage{etoolbox}
\begin{document}
\newcount\X
\newcount\Y

\newtoggle{even}
\toggletrue{even}

\loop
\Y = 0
\advance \X by 1
{%
  \loop
  \advance \Y by 1
  \message{\the\X,\the\Y}
  \iftoggle{even}{%
    \message{EVEN}%
    \togglefalse{even}%
  }{%
    \message{ODD}%
    \toggletrue{even}%
  }%
  \ifnum \Y < 3
  \repeat
}%
\ifnum \X < 6
\repeat
\end{document}

输出(注意重复的EVENs):

1,1 偶数 1,2 奇数 1,3 偶数 2,1 偶数 2,2 奇数 2,3 偶数 3,1 偶数 3,2 奇数 3,3 偶数 4,1 偶数 4,2 奇数 4,3 偶数 5,1 偶数 5,2 奇数 5,3 偶数 6,1 偶数 6,2 奇数 6,3 偶数

答案1

这与切换开关的作用域有关。也就是说,在内循环中,对\toggletrue和 的调用\togglefalse是有效的,但一旦完成就会被忽略,恢复为原始定义\toggletrue{even}。这就是为什么 then 输出是EVEN用于每个内循环的开始。为了让这些重新定义在整个范围内保持不变,请在切换开关前面加上\global

...
\global\togglefalse{even}%
...
\global\toggletrue{even}%
...

这是我进行上述更改后得到的输出:

1,1 EVEN 1,2 ODD 1,3 EVEN 2,1 ODD 2,2 EVEN 2,3 ODD 3,1 EVEN 3,2 ODD 3,3 EVEN 4, 1 ODD 4,2 EVEN 4,3 ODD 5,1 EVEN 5,2 ODD 5,3 EVEN 6,1 ODD 6,2 EVEN 6,3 ODD

答案2

你必须在和\global前面写。\togglefalse{even}\toggletrue{even}

答案3

如果你使用etoolbox,那么你应该使用\whileboolexpr。也许可以使用\newcounter{X}\value{X}而不是\newcount\X\X因此:

\documentclass{minimal}
\usepackage{etoolbox}
\begin{document}
\newcounter{X}
\newcounter{Y}

\newtoggle{even}
\toggletrue{even}

\setcounter{X}{0}
\whileboolexpr{test {\ifnumcomp{\value{X}}<6} }{%
  \stepcounter{X}
  \setcounter{Y}{0}
  \whileboolexpr{test {\ifnumcomp{\value{Y}}<3} }{%
    \stepcounter{Y}
    \arabic{X}, \arabic{Y}:
    \iftoggle{even}%
      {EVEN\togglefalse{even}}%
      {ODD\toggletrue{even}}\par
  }%
}

\end{document}

我删除了多余的内循环组,只需重置\Y=0它就可以工作。你会发现它看起来像其他编程语言中常见的 for 循环。

相关内容