Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对列表排序<;StringBuilder>;_C#_List_Stringbuilder - Fatal编程技术网

C# 对列表排序<;StringBuilder>;

C# 对列表排序<;StringBuilder>;,c#,list,stringbuilder,C#,List,Stringbuilder,要求:遍历已排序的字符串列表,在每个字符串的开头添加一个字符,然后重新排序。这可能需要做几千次。我尝试使用一个常规的字符串列表,但正如预期的那样,这个过程太慢了 我打算尝试一个StringBuilder列表,但是没有直接的方法对列表进行排序。想到什么解决方法了吗?字符串生成器将比字符串快一点,但仍然很慢,因为您必须复制整个缓冲区以在开始添加字符 您可以创建自定义比较方法(或比较器对象,如果愿意),并将其传递给列表。排序方法: int CompareStringBuilders(StringBui

要求:遍历已排序的字符串列表,在每个字符串的开头添加一个字符,然后重新排序。这可能需要做几千次。我尝试使用一个常规的字符串列表,但正如预期的那样,这个过程太慢了

我打算尝试一个StringBuilder列表,但是没有直接的方法对列表进行排序。想到什么解决方法了吗?

字符串生成器将比字符串快一点,但仍然很慢,因为您必须复制整个缓冲区以在开始添加字符

您可以创建自定义比较方法(或比较器对象,如果愿意),并将其传递给列表。排序方法:

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;
    }
}