C# 对列表排序<;StringBuilder>;
要求:遍历已排序的字符串列表,在每个字符串的开头添加一个字符,然后重新排序。这可能需要做几千次。我尝试使用一个常规的字符串列表,但正如预期的那样,这个过程太慢了 我打算尝试一个StringBuilder列表,但是没有直接的方法对列表进行排序。想到什么解决方法了吗?字符串生成器将比字符串快一点,但仍然很慢,因为您必须复制整个缓冲区以在开始添加字符 您可以创建自定义比较方法(或比较器对象,如果愿意),并将其传递给列表。排序方法:C# 对列表排序<;StringBuilder>;,c#,list,stringbuilder,C#,List,Stringbuilder,要求:遍历已排序的字符串列表,在每个字符串的开头添加一个字符,然后重新排序。这可能需要做几千次。我尝试使用一个常规的字符串列表,但正如预期的那样,这个过程太慢了 我打算尝试一个StringBuilder列表,但是没有直接的方法对列表进行排序。想到什么解决方法了吗?字符串生成器将比字符串快一点,但仍然很慢,因为您必须复制整个缓冲区以在开始添加字符 您可以创建自定义比较方法(或比较器对象,如果愿意),并将其传递给列表。排序方法: int CompareStringBuilders(StringBui
int CompareStringBuilders(StringBuilder a, StringBuilder b)
{
for (int i = 0; i < a.Length && i < b.Length; i++)
{
var comparison = a[i].CompareTo(b[i]);
if (comparison != 0)
return comparison;
}
return a.Length.CompareTo(b.Length);
}
int比较构建器(StringBuilder a、StringBuilder b)
{
对于(int i=0;i
像这样调用它:
var list = new List<StringBuilder>();
//...
list.Sort(CompareStringBuilders);
var list=newlist();
//...
list.Sort(CompareStringBuilders);
然而,您可能会更好地为您的问题寻找不同的解决方案
链表提供了快速的预结束功能,那么使用LinkedList
怎么样?当然,如果您需要其他StringBuilder函数,这可能不起作用
StringBuilder是为.NET4重写的,所以我删除了我之前关于字符前置速度慢的评论。如果性能是一个问题,您应该进行测试,看看问题究竟出在哪里。您已经声明无法对链接进行排序-但是,如果您可以提供自己的排序比较,您可以:
List<StringBuilder> strings = new List<StringBuilder>();
// ...
strings.Sort((s1, s2) => s1.ToString().CompareTo(s2.ToString()));
我们将发现结果:
List<StringBuilder> - Elapsed Milliseconds: 27,678
List<string> - Elapsed Milliseconds: 2,932
LinkedList<char> - Elapsed Milliseconds: 912
列表-已用毫秒数:27678
列表-已用毫秒数:2932
LinkedList-已用毫秒数:912
编辑2:当我将两个值分别增加到3000和3000时
List<StringBuilder> - Elapsed Milliseconds: // Had to comment out - was taking several minutes
List<string> - Elapsed Milliseconds: 45,928
LinkedList<char> - Elapsed Milliseconds: 6,823
List-appeated millizes://不得不注释掉-花费了几分钟时间
列表-已用毫秒数:45928
LinkedList-已用毫秒数:6823
按照Phoog的回答对StringBuilder
进行排序,但在StringBuilder
实例中按相反顺序保留字符串-通过这种方式,您可以通过将每个新字符的“前置”添加到StringBuilder
的当前值的末尾来优化它:
更新:使用测试程序
class Program
{
static readonly Random _rng = new Random();
static void Main(string[] args)
{
int stringCount = 2500;
int initialStringSize = 100;
int maxRng = 4;
int numberOfPrepends = 2500;
int iterations = 5;
Console.WriteLine( "String Count: {0}; # of Prepends: {1}; # of Unique Chars: {2}", stringCount, numberOfPrepends, maxRng );
var startingStrings = new List<string>();
for( int i = 0; i < stringCount; ++i )
{
var sb = new StringBuilder( initialStringSize );
for( int j = 0; j < initialStringSize; ++j )
{
sb.Append( _rng.Next( 0, maxRng ) );
}
startingStrings.Add( sb.ToString() );
}
for( int i = 0; i < iterations; ++i )
{
TestUsingStringBuilderAppendWithReversedStrings( startingStrings, maxRng, numberOfPrepends );
TestUsingStringBuilderPrepend( startingStrings, maxRng, numberOfPrepends );
}
var input = Console.ReadLine();
}
private static void TestUsingStringBuilderAppendWithReversedStrings( IEnumerable<string> startingStrings, int maxRng, int numberOfPrepends )
{
var builders = new List<StringBuilder>();
var start = DateTime.Now;
foreach( var str in startingStrings )
{
builders.Add( new StringBuilder( str ).Reverse() );
}
for( int i = 0; i < numberOfPrepends; ++i )
{
foreach( var sb in builders )
{
sb.Append( _rng.Next( 0, maxRng ) );
}
builders.Sort( ( x, y ) =>
{
var comparison = 0;
var xOffset = x.Length;
var yOffset = y.Length;
while( 0 < xOffset && 0 < yOffset && 0 == comparison )
{
--xOffset;
--yOffset;
comparison = x[ xOffset ].CompareTo( y[ yOffset ] );
}
if( 0 != comparison )
{
return comparison;
}
return xOffset.CompareTo( yOffset );
} );
}
builders.ForEach( sb => sb.Reverse() );
var end = DateTime.Now;
Console.WriteLine( "StringBuilder Reverse Append - Total Milliseconds: {0}", end.Subtract( start ).TotalMilliseconds );
}
private static void TestUsingStringBuilderPrepend( IEnumerable<string> startingStrings, int maxRng, int numberOfPrepends )
{
var builders = new List<StringBuilder>();
var start = DateTime.Now;
foreach( var str in startingStrings )
{
builders.Add( new StringBuilder( str ) );
}
for( int i = 0; i < numberOfPrepends; ++i )
{
foreach( var sb in builders )
{
sb.Insert( 0, _rng.Next( 0, maxRng ) );
}
builders.Sort( ( x, y ) =>
{
var comparison = 0;
for( int offset = 0; offset < x.Length && offset < y.Length && 0 == comparison; ++offset )
{
comparison = x[ offset ].CompareTo( y[ offset ] );
}
if( 0 != comparison )
{
return comparison;
}
return x.Length.CompareTo( y.Length );
} );
}
var end = DateTime.Now;
Console.WriteLine( "StringBulder Prepend - Total Milliseconds: {0}", end.Subtract( start ).TotalMilliseconds );
}
}
public static class Extensions
{
public static StringBuilder Reverse( this StringBuilder stringBuilder )
{
var endOffset = stringBuilder.Length - 1;
char a;
for( int beginOffset = 0; beginOffset < endOffset; ++beginOffset, --endOffset )
{
a = stringBuilder[ beginOffset ];
stringBuilder[ beginOffset ] = stringBuilder[ endOffset ];
stringBuilder[ endOffset ] = a;
}
return stringBuilder;
}
}
类程序
{
静态只读随机_rng=new Random();
静态void Main(字符串[]参数)
{
int stringCount=2500;
int initialStringSize=100;
int maxRng=4;
int numberOfPrepends=2500;
int迭代次数=5;
WriteLine(“字符串计数:{0};#前置字符数:{1};#唯一字符数:{2}”,stringCount,numberOfPrepends,maxRng);
var startingStrings=新列表();
对于(int i=0;i
{
var比较=0;
var xOffset=x.长度;
var yOffset=y.长度;
而(0sb.Reverse());
var end=DateTime.Now;
WriteLine(“StringBuilder反向追加-总毫秒:{0}”,end.Subtract(start.totalmillizes);
}
使用StringBuilderPrepend的私有静态无效测试(IEnumerable startingStrings、int maxRng、int numberOfPrepends)
{
var builders=新列表();
var start=DateTime.Now;
foreach(起始字符串中的var str)
{
添加(新的StringBuilder(str));
}
对于(int i=0;i
{
var比较=0;
对于(int offset=0;offsetclass Program
{
static readonly Random _rng = new Random();
static void Main(string[] args)
{
int stringCount = 2500;
int initialStringSize = 100;
int maxRng = 4;
int numberOfPrepends = 2500;
int iterations = 5;
Console.WriteLine( "String Count: {0}; # of Prepends: {1}; # of Unique Chars: {2}", stringCount, numberOfPrepends, maxRng );
var startingStrings = new List<string>();
for( int i = 0; i < stringCount; ++i )
{
var sb = new StringBuilder( initialStringSize );
for( int j = 0; j < initialStringSize; ++j )
{
sb.Append( _rng.Next( 0, maxRng ) );
}
startingStrings.Add( sb.ToString() );
}
for( int i = 0; i < iterations; ++i )
{
TestUsingStringBuilderAppendWithReversedStrings( startingStrings, maxRng, numberOfPrepends );
TestUsingStringBuilderPrepend( startingStrings, maxRng, numberOfPrepends );
}
var input = Console.ReadLine();
}
private static void TestUsingStringBuilderAppendWithReversedStrings( IEnumerable<string> startingStrings, int maxRng, int numberOfPrepends )
{
var builders = new List<StringBuilder>();
var start = DateTime.Now;
foreach( var str in startingStrings )
{
builders.Add( new StringBuilder( str ).Reverse() );
}
for( int i = 0; i < numberOfPrepends; ++i )
{
foreach( var sb in builders )
{
sb.Append( _rng.Next( 0, maxRng ) );
}
builders.Sort( ( x, y ) =>
{
var comparison = 0;
var xOffset = x.Length;
var yOffset = y.Length;
while( 0 < xOffset && 0 < yOffset && 0 == comparison )
{
--xOffset;
--yOffset;
comparison = x[ xOffset ].CompareTo( y[ yOffset ] );
}
if( 0 != comparison )
{
return comparison;
}
return xOffset.CompareTo( yOffset );
} );
}
builders.ForEach( sb => sb.Reverse() );
var end = DateTime.Now;
Console.WriteLine( "StringBuilder Reverse Append - Total Milliseconds: {0}", end.Subtract( start ).TotalMilliseconds );
}
private static void TestUsingStringBuilderPrepend( IEnumerable<string> startingStrings, int maxRng, int numberOfPrepends )
{
var builders = new List<StringBuilder>();
var start = DateTime.Now;
foreach( var str in startingStrings )
{
builders.Add( new StringBuilder( str ) );
}
for( int i = 0; i < numberOfPrepends; ++i )
{
foreach( var sb in builders )
{
sb.Insert( 0, _rng.Next( 0, maxRng ) );
}
builders.Sort( ( x, y ) =>
{
var comparison = 0;
for( int offset = 0; offset < x.Length && offset < y.Length && 0 == comparison; ++offset )
{
comparison = x[ offset ].CompareTo( y[ offset ] );
}
if( 0 != comparison )
{
return comparison;
}
return x.Length.CompareTo( y.Length );
} );
}
var end = DateTime.Now;
Console.WriteLine( "StringBulder Prepend - Total Milliseconds: {0}", end.Subtract( start ).TotalMilliseconds );
}
}
public static class Extensions
{
public static StringBuilder Reverse( this StringBuilder stringBuilder )
{
var endOffset = stringBuilder.Length - 1;
char a;
for( int beginOffset = 0; beginOffset < endOffset; ++beginOffset, --endOffset )
{
a = stringBuilder[ beginOffset ];
stringBuilder[ beginOffset ] = stringBuilder[ endOffset ];
stringBuilder[ endOffset ] = a;
}
return stringBuilder;
}
}