繁体   English   中英

如何在C#中实现strlen()?

[英]how to implement strlen() in c#?

我在考虑一种不使用Length属性就可以在c#中计算字符串长度的解决方案。

我能想到的是完成此操作的方法是

程序在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个额外的临时变量。你们能想到比这更好的解决方案吗?

问题是字符串在C#中的存储方式。 尽管在某些语言中,需要花大量时间才能计算出字符串的长度,但是在C#中,确定字符串长度的唯一方法是通过其Length属性。 如果要考虑字符串的存储方式,则有一个字符数组和一个Length。 现在,字符串不是以空值结尾的,因此在开始读取不属于数组的内存之前,您需要使用Length字段来知道可以访问多少数组。 您可以通过抽象隐藏您正在做什么。 例如,您可以调用ToCharArray函数,但是为了生成您使用的以null终止的字符串,它首先必须访问Length值,以为char []数组分配正确的内存量,并复制正确的字符。 或者,您可以对每个长度(单位为s的长度)使用a ++;

正如其他人所建议的。 这是隐藏您正在访问“长度”值的事实的另一种方法。 为了以这种方式遍历字符,必须首先访问Length值以查看要遍历的字符数。 我不确定是在库调用中执行此操作,还是将其编译为其他结构,但最终结果是相同的。

您可以使用不安全的代码以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;
}
public static int strlen2 (string s) {
    int length = 0;
    foreach (char c in s) length++;
    return length
}

我不确定这样做有什么意义。

我想对Leiz的答案进行一些优化,我将在第3行中使用pre-increment而非post post来读取:

foreach(char c in s) ++length

这会从中挤出一点点性能。

如果您想要最有效的方法,可以尝试模仿微软自己的String.Length函数。 启动.NET Reflector并加载一个名为String.Length的小示例解决方案。 然后,您可以简单地钻入依赖项,甚至进行一些分解。

替代文字

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM