我需要计算一个字符串中的行数。任何换行符都可以出现在字符串中(CR,LF或CRLF)。
So possible new line chars:
* \n
* \r
* \r\n
例如,使用以下输入:
This is [\n]
an string that [\r]
has four [\r\n]
lines
该方法应该返回4行。你知道任何内置函数,或者有人已经实现了它吗?
static int GetLineCount(string input)
{
// could you provide a good implementation for this method?
// I want to avoid string.split since it performs really bad
}
注意:性能对我来说很重要,因为我可以阅读大字符串。
int count = 0;
int len = input.Length;
for(int i = 0; i != len; ++i)
switch(input[i])
{
case '\r':
++count;
if (i + 1 != len && input[i + 1] == '\n')
++i;
break;
case '\n':
// Uncomment below to include all other line break sequences
// case '\u000A':
// case '\v':
// case '\f':
// case '\u0085':
// case '\u2028':
// case '\u2029':
++count;
break;
}
只需扫描,计算换行符,并在\r
的情况下测试下一个字符是否为\n
,如果是,则跳过它。
性能对我来说很重要,因为我可以阅读大字符串。
如果可能的话,尽量避免阅读大字符串。例如。如果它们来自流,这很容易直接在流上进行,因为只需要一个字符的预读。
这是另一个不在字符串最末端计算换行符的变体:
int count = 1;
int len = input.Length - 1;
for(int i = 0; i < len; ++i)
switch(input[i])
{
case '\r':
if (input[i + 1] == '\n')
{
if (++i >= len)
{
break;
}
}
goto case '\n';
case '\n':
// Uncomment below to include all other line break sequences
// case '\u000A':
// case '\v':
// case '\f':
// case '\u0085':
// case '\u2028':
// case '\u2029':
++count;
break;
}
因此,将""
,"a line"
,"a line\n"
和"a line\r\n"
视为仅一行,依此类推。
你的字符串来自一个文件?
我认为这个人能做到这一点并且做得非常快:
int count = File.ReadLines(path).Count();
简单
private static int Count4(string s)
{
int n = 0;
foreach( var c in s )
{
if ( c == '\n' ) n++;
}
return n+1;
}
应该非常快,即使使用更大的字符串...在那里测试了许多其他算法。有什么可以反对这种实施?如果你不扩展使用并行执行,我会尝试这种非常简单的方法。
完全手动实施:(你不会比这更快)
public static int GetLineCount(string input)
{
int lineCount = 0;
for (int i = 0; i < input.Length; i++)
{
switch (input[i])
{
case '\r':
{
if (i + 1 < input.Length)
{
i++;
if (input[i] == '\r')
{
lineCount += 2;
}
else
{
lineCount++;
}
}
else
{
lineCount++;
}
}
break;
case '\n':
lineCount++;
break;
default:
break;
}
}
Regex.Matches(input, "\n|\r|\n\r").Count
这是一个类似于Microsoft在从文件中读取行时如何操作的示例:
int numberOfLines = 0;
using (StreamReader sr = new StreamReader(path, encoding))
while ((line = sr.ReadLine()) != null)
numberOfLines += 1;
供参考/阅读:http://referencesource.microsoft.com/#mscorlib/system/io/file.cs,8d10107b7a92c5c2 http://referencesource.microsoft.com/#mscorlib/system/io/file.cs,675b2259e8706c26
如果你想获得行数,你应该只计算\n
,因为\r
表示回车并且没有前进到新行:
static int GetLineCount(string input)
{
return input.Count(c => c == '\n');
}