解决方案 A

解决方案 A

我发现自己写了$\{0,1\}^x$很多东西,所以我想定义一个简写宏:

\def\zo#1{\{0,1\}^{#1}}

但是,有时我需要$\{0,1\}$没有上标。如果我写的话,\zo{}在右括号后会得到一点点额外的空间(因为那里有一个空的上标)。我发现摆脱它的唯一方法是

\def\zo#1{\{0,1\}\if\relax\detokenize{#1}\relax\else^{#1}\fi}

这听起来有点拗口。有没有更优雅的方法来实现这一点?请注意,我正在编写的实际文档是 LaTeX 格式的,因此如果 amsmath(例如)能达到目的,那将是一个很好的答案。我用纯 TeX 表达了这个问题,因为它从根本上来说是一个关于核心数学引擎的问题。

如果你看不到那一点点额外的空间,这个 MWE(需要(pdf)etex)会让它变得明显:

\def\a#1{\{0,1\}^{#1}}
\def\b#1{\{0,1\}\if\relax\detokenize{#1}\relax\else^{#1}\fi}
\leavevmode\rlap{$\a{}\a{}\a{}\a{}$}$\b{}\b{}\b{}\b{}$
\bye

→ (400% 缩放)

在此处输入图片描述

答案1

解决方案 A

使用

\def\a{\{0,1\}}

^{<stuff>}如果需要的话,可以添加。

解决方案 B

笔记

  • \csname <something else>\endcsname\relax如果\<something else>未定义,则扩展为。
  • \qrrgobbletwo<something><something>可以作为 参数的地方,不得命名任何其他宏\a
  • 其他答案中使用的所有其他“技巧”和帮助程序(\newcommand带有可选参数/ \@ifnextchar)仍然可以应用。 (但无论如何我都会使用条件!)

参考

代码

\def\qrrgobbletwo#1#2{}
\def\a#1{%
    \{0,1\}\csname qrrgobbletwo\detokenize{#1}\endcsname^{#1}%
}
\def\b#1{\{0,1\}\if\relax\detokenize{#1}\relax\else^{#1}\fi}
\leavevmode\rlap{$\a{}\a{}\a{}\a{}$}$\b{}\b{}\b{}\b{}$

\leavevmode\rlap{$\a{a}\a{a}\a{a}\a{a}$}$\b{a}\b{a}\b{a}\b{a}$
\bye

输出

在此处输入图片描述

答案2

这似乎是一个可选功能,因此应该是一个可选参数:

 \newcommand\zo[1][]{\{0,1\}\ifx\relax#1\relax\else^{#1}\fi}

    \zo   \zo[x]

答案3

使用例如xparse你会得到更易读的代码:

\usepackage{xparse}
\DeclareDocumentCommand\zo{g}{%
  \ensuremath{%
    \{0,1\}%
    \IfNoValueTF{#1}{}{^{#1}}%
  }%
}

使用{o}作为参数说明符而不是{g}将使命令使用可选的([]-delimited)参数,这可能更合适。

答案4

\makeatletter
\newcommand\zo[1]{\begingroup\def\x{#1}\ifx\x\@empty\{0,1\}\else\{0,1\}^{\x}\fi\endgroup}
\makeatother

我们通过 收集参数\def\x{#1},然后通过 测试它是否为空\ifx\x\@empty。其余的应该很清楚。这个解决方案比你的好一点,因为我们只读了一次 #1。如果用 替换 来使其更强大\newcommand,可能是一个好主意\DeclareRobustCommand,这样你也可以在奇怪的上下文中将它用作章节标题。


为了实现它纯粹的 TeX,您可以执行以下操作:

\def\zo#1{\begingroup\def\x{#1}\def\y{}\ifx\x\y\{0,1\}\else\{0,1\}^{\x}\fi\endgroup}

例子:

在此处输入图片描述

\makeatletter
\newcommand\zo[1]{\begingroup\def\x{#1}\ifx\x\@empty\{0,1\}\else\{0,1\}^{\x}\fi\endgroup}
\newcommand\oldzo[1]{\{0,1\}^{#1}}
\makeatother

\noindent
$\zo{}\zo{}\zo{}\zo{}$\\
$\oldzo{}\oldzo{}\oldzo{}\oldzo{}$\\
$\{0,1\}\{0,1\}\{0,1\}\{0,1\}$

具有可选参数的变体:

\makeatletter
\def\zo@opt[#1]{\{0,1\}^{#1}}
\newcommand\zo{\@ifnextchar[\zo@opt{\{0,1\}}}
\makeatother

$\zo[2] \neq \zo \zo$

相关内容