【问题标题】:Do strings contain empty substrings everywhere?字符串是否到处都包含空子字符串?
【发布时间】:2014-05-04 02:05:06
【问题描述】:

这个问题来自this answer 的讨论。

简而言之:答案 (0x499602D2) 的作者声称(正确,据我所知)当不跳过空格但下一个字符是空格时,除字符外的所有提取都将失败。

我对此提出质疑,因为我认为提取string 不应该失败,因为流包含一个由开头的空白字符分隔的空字符串。

这发展成为一般讨论是否在字符串中的任何位置都存在空字符串,例如在a 和字符串"ab"b 之间(我说是,0x499602D2 说不是)。 0x499602D2 建议我把它放在一个问题中,所以我这样做了。

我从该线程(包括聊天部分)复制我的立场的主要论点:

让我们首先看一下空字符串的常量。在 C 和 C++ 中,内容由开头和结尾的引号分隔。那么空字符串是什么样的呢?你知道的:""。你看,在最初的引号(delimiter)之后直接跟在最后的引号(delimiter)之后。空字符串位于两个引号之间,两个引号直接紧随其后,因为空字符串没有字符。另请查看 C 表示。那是字符序列,后跟分隔符'\0'。那么空字符串的表示是什么?好吧,空字符串的字符后跟分隔符。这意味着,第一个字符是分隔符(即,与流的情况完全相同)。现在考虑字符串的连接,例如第一个字符串是"a",第二个字符串是空的,第三个字符串是"b"。那么什么是串联呢?好吧,"ab"。很明显,a"ab" 中的 b 之间有一个空字符串(我们明确地把它放在那里!)。当然,在a 之前和b 之后也是如此。也就是说,字符串的任意两个字符之间都有一个空字符串(或两个,或一百万个)。

空字符串没有字符,连续字符之间没有字符。因此在两个字符之间有一个空字符串。另请参阅我之前给出的其他论点。此外,考虑匹配空字符串的正则表达式:它们也匹配任何地方。 例如,/ab*c/ 匹配"ac",因为b* 匹配ac 之间的空字符串

在分隔符(空格)之前有一个空字符串(即没有字符),就像在空字符串的 C 表示中一样,\0 分隔符之前没有字符。另请注意,readline 也与\n 分隔符相同:如果\n 紧随其后,它不会失败,而是给出一个空字符串。

感觉无法识别0x499602D2在讨论中的主要论点,所以我不尝试以免在选择时无意中出现不公平。您应该能够在 cmets 中看到它们(也可能在聊天室中 — 我不知道是否每个人都可以访问)。 @0x499602D2:如果你愿意,你也可以自己在这一段之后添加你的主要论点。

与此相关的实际问题是:如果分隔符之前没有字符,那么设计良好的字符串提取函数是否会失败(如 operator>> 字符串那样),还是成功并返回一个空字符串(如 readline有)吗?

【问题讨论】:

  • 我没有看到解决实际问题的问题?是否有您想要解决的特定算法、标准条款或函数来使这个问题成为一个好的 SO 问题?
  • @Yakk:我添加了一段关于与之相关的实际问题。
  • @celtschk 你好。我认为 kol 的回答只是证明了这个概念,但实际上并没有表明这实际上是如何实现的。你能给我一个在实际意义上证明这一点的程序吗?
  • 您是否也会质疑1 > 0“在实际意义上”是真的,并要求一个程序来演示它?无论如何,我在右侧的链接中找到了this。不是完全相同的问题,而是一种特殊情况(即空字符串中的空字符串),有几个答案给出了明确的代码示例。

标签: c++ string


【解决方案1】:

定理

在字符串s的任意位置都有一个空字符串ε

证明

1. 如果 |s| = 0(s 的长度为零),则 s = ε,则该声明成立。

2. 如果 |s| > 0,则 s 有两个边缘位置:一个在其第一个符号之前,另一个在最后一个符号之后。由于 ε 是串联运算的标识元素,即 εs = = s,因此主张对开始位置和结束位置都成立。

3. 如果 |s| > 1,则s可以写成两个非空字符串的串联:s = pq,其中|p| > 0 和 |q| > 0. 利用ε的单位元性质,pεq = (pε) q = pq = s,这意味着该声明适用于 s 中的位置,该位置将其分为 pq。该划分的位置可以是s的任何内部位置,因此该声明也适用于每个内部位置。

推论

恒等元性质意味着ε = εε = εεε = etc. 替换ε后重复上述证明em> 和 ε^n,其中 n 是一个正整数,我们发现在任何字符串的任何位置都有无数个空字符串。

备注

这里“位置”一词的意思是“插入符号位置”(text insertion cursor 位置)。插入符号可以放在第一个符号之前(索引:0)、连续符号之间和最后一个符号之后(索引:|s|)。插入符号位置的数量为 |s| + 1。

上面的证明表明,符号之间的这些“零宽度间隙”可以想象为用任意数量的 empty 字符串填充。 (这很奇怪,因为空集是每个集合的子集,包括它自己。)

【讨论】:

  • 连续位置存储的两个连续字符之间怎么会有addressable空字符串?
  • @ThomasMatthews 我在答案末尾添加了一些注释,以澄清索引/寻址问题。
猜你喜欢
  • 1970-01-01
  • 2011-11-09
  • 2013-05-18
  • 1970-01-01
  • 2021-12-20
  • 2023-04-09
  • 2020-08-26
  • 2014-11-22
  • 2022-01-13
相关资源
最近更新 更多