【发布时间】:2010-09-13 19:35:04
【问题描述】:
标题是整个问题。谁能告诉我为什么会发生这种情况?
【问题讨论】:
标签: c# java startswith
标题是整个问题。谁能告诉我为什么会发生这种情况?
【问题讨论】:
标签: c# java startswith
是的 - 因为它确实以空字符串开头。事实上,空字符串逻辑上出现在每对字符之间。
这样说吧:你能给出什么“开始于”的定义来排除这种情况?以下是“开头”的简单定义:
"如果 x 的第一个 y.Length 字符与 y 匹配,则 x 以 y 开头。"
另一种(等效)定义:
"如果x.Substring(0, y.Length).Equals(y),则x以y开头"
【讨论】:
我将尝试详细说明 Jon Skeet 所说的内容。
假设x、y和z是字符串,而+运算符实际上是连接,那么:
如果我们可以将 z 拆分为 z = x + y,这意味着 z 以 x 开头。 因为每个字符串 z 都可以拆分为 z = "" + z,所以每个字符串都以 "" 开头。
所以,因为 ("" + "abcd") == "abcd" 所以 "abcd" 以 "" 开头
【讨论】:
我将从一个更容易理解的相关事实开始。
空集是每个集的子集。
为什么?如果A 的每个元素都是B 的元素,则子集 的definition 声明A 是B 的子集。相反,如果A 的元素不是B 的元素,则A 不是B 的子集。
现在修复一组B。我将确定空集是B 的子集。我将通过证明空集不是B 的子集的情况来做到这一点。如果空集不是B 的子集,那么我可以找到不在B 中的空集元素。但是空集没有任何元素,因此我找不到不在B 中的元素。因此,空集并不是B 的子集。因此,空集必须是B 的子集。
任何字符串都以空字符串开头。
首先,我们必须就以开头的定义达成一致。让s 和t 成为strings 我们说s 以 t 如果s.Length >= t.Length 和t 的第一个t.Length 字符匹配@ 987654348@。也就是说,s.Length >= t.Length 和每个Int32 index 使得0 <= index < t.Length、s[index] == t[index] 为真。相反,我们会说s 不是以t 开头的 if 语句
s.Length < t.Length 或 s.Length >= t.Length 并且有一个 Int32 index 使得 0 <= index < t.Length 和 s[index] != t[index]
是真的。在简单的英语中,s 比t 短,或者,如果不是,则t 中的字符与s 中的相同位置的字符不匹配。
现在修复一个字符串s。我将确定s 以空字符串开头。我将通过证明s 不是以空字符串开头的情况来做到这一点。如果s 不以空字符串开头,则s.Length < String.Empty.Length 或s.Length >= String.Empty.Length 并且有一个Int32 index 使得0 <= index < String.Empty.Length。但是s.Length >= 0 和String.Empty.Length 等于零,所以s.Length < String.Empty.Length 不可能为真。同样,由于“String.Empty.Lengthis equal to zero, there is noInt32 indexsatisfying0
s.Length < String.Empty.Length 或 s.Length >= String.Empty.Length 并且有一个 Int32 index 这样0 <= index < String.Empty.Length
是假的。因此,s 并非不以空字符串开头。因此,s 必须以空字符串开头。
以下是以开头的实现,编码为string的扩展。
public static bool DoStartsWith(this string s, string t) {
if (s.Length >= t.Length) {
for (int index = 0; index < t.Length; index++) {
if (s[index] != t[index]) {
return false;
}
}
return true;
}
return false;
}
以上两个加粗的事实是vacuously true statements的例子。它们是正确的,因为定义它们的语句(子集和以开头)在空域上是universal quantifications。空集中没有元素,所以不能有任何不在其他固定集中的空集元素。空字符串中没有字符,所以不能有一个字符作为空字符串中的某个位置与其他某个固定字符串中相同位置的字符不匹配。
【讨论】:
该方法将value参数与该字符串开头与value长度相同的子字符串进行比较,并返回一个值,表示它们是否相等。 要相等,value 必须是空字符串(Empty)、对同一个实例的引用,或者匹配这个实例的开头。
如果参数表示的字符序列是该字符串表示的字符序列的前缀,则为true;否则为假。 另请注意,如果参数为空字符串或等于由 equals(Object) 方法确定的此 String 对象,则将返回 true。
【讨论】:
假设 "abcd".StartsWith("") 返回 false。
如果是这样,那么下面的表达式 eval 是什么,是真还是假:
("abcd".Substring(0,0) == "")
原来 eval 为真,所以字符串确实以空字符串开头 ;-),或者换句话说,“abcd”的子字符串从位置 0 开始并且长度为 0 等于空字符串“” .非常合乎逻辑。
【讨论】:
null 将是一个同样合适的返回值。
在 C# 中,这是 specification 告诉它做出反应的方式;
要相等,value 必须是空字符串(Empty)、对同一个实例的引用,或者匹配这个实例的开头。
【讨论】:
两个字符串的前 N 个字符相同。 N是第二个字符串的长度,即零。
【讨论】:
为什么“abcd”.StartsWith(“”) 返回 true?
真正的答案:
必须是这样,否则你会遇到这种情况
"".startsWith("") == false
"".equals("") == true
but yet
"a".startsWith("a") == true
"a".equals("a") == true
然后我们将再次拥有千年虫,因为所有依赖于以自身开头的相同字符串的银行软件都会混淆我们的帐户,突然间比尔盖茨将拥有我的财富,而我将拥有他的,该死的!命运对我并不那么好。
【讨论】:
为了记录,String.StartsWith() 内部调用了方法System.Globalization.CultureInfo.IsPrefix(),它显式地进行了以下检查:
if (prefix.Length == 0)
{
return true;
}
【讨论】:
因为字符串以“nothing”开头。
【讨论】:
如果你用正则表达式来思考它,它是有道理的。 每个字符串(不仅仅是“abcd”,还有“”和“sdf\nff”), 在评估 'starts with empty string' 的正则表达式时返回 true。
【讨论】: