我正在考虑使用c#计算字符串长度而不使用Length
属性的解决方案。
我能想到的事情就是这样做
程序在C#中
public static int strlen (string s)
{
string temp = s + '/0';
char [] c = temp.ToCharArray();
int length = 0;
while (c[length]!='/0') length++;
length--;
return length;
}
但这是非常天真的编程,它还使用了1个额外的临时变量 你能想到比这更好的解决方案吗?
答案 0 :(得分:8)
问题在于字符串存储在C#中的方式。虽然在某些语言中需要计算来计算字符串的长度,但在C#中,仅方式通过其Length属性计算字符串的长度。如果关于字符串的存储方式,则有一个字符数组和一个Length。现在,字符串不以null结尾,因此您需要长度字段,以便在开始读取不属于的内存之前知道可以访问多少数组数组。您可以通过抽象隐藏您正在做的事情。例如,您可以调用ToCharArray函数,但是为了生成您使用的以null结尾的字符串,它首先必须访问Length值以为char []数组分配适当的内存量并复制正确的数量字符。或者你可以用一个 对于每个(char c in s)长度++;
正如其他人所说的那样。这是隐藏您访问Length值的另一种方法。为了以这种方式迭代字符,您必须首先访问“长度”值以查看要迭代的字符数。无论是在库调用中执行此操作,还是将其编译为不同的构造,我都不确定,但最终结果是相同的。答案 1 :(得分:5)
你可以使用不安全的代码获得O(1)速度的长度,因为C#字符串的前缀是它们的长度 - 这可能是get_Length函数在内部的作用(这就是为什么你应该使用内置方式而不是写你自己的):
public static unsafe int strlen(string s)
{
if(s == null) {
// Handle the error here
}
int length = 0;
fixed(char *pStr = s) {
length = *(((int *)pStr) - 1);
}
return length;
}
或者如果你更喜欢更老的学校教育方法:
public static unsafe int strlen(string s)
{
if(s == null) {
// Handle the error here
}
int length = 0;
fixed(char *pStr = s) {
char *pEnd = pStr;
while(*pEnd++ != '\0');
length = (int)((pEnd - pStr) - 1);
}
return length;
}
答案 2 :(得分:3)
public static int strlen2 (string s) {
int length = 0;
foreach (char c in s) length++;
return length
}
我不确定这样做有什么意义。
答案 3 :(得分:3)
我认为要对Leiz的答案进行一些优化,我会在第3行使用预增量而不是后增量来读取:
foreach(char c in s) ++length
这会从中榨取一点点性能。
答案 4 :(得分:2)
如果你想要最有效的方法,你可以尝试模仿微软自己的String.Length函数。启动.NET Reflector并加载一个小样本解决方案,调用String.Length。然后你可以简单地挖掘依赖关系甚至做一些拆解。