什么是将':'分隔的字符串拆分为给定数量的块的最快方法,其中结果/记录长度是可变的

时间:2012-07-09 11:19:35

标签: c#

我从TCP listner接受了一个大字符串,格式如下

“1,7620257787,0123456789,99,0922337203,9223372036,32.5455,87,12.7857,1 / 1 / 2012,9223372036:1,7620257787,0123456789,99,0922337203,9223372036,32.5455,87,12.7857:2 / 1 / 2012,234234234:3,7620257787,01234343456789,99,0922337203,9223372036,32.5455,87,12.7857,1 / 1 / 2012,9223372036:34,76202343457787,012434343456789,93339,34340922337203,9223372036,32.5455,87,12.7857, 1/1 / 2012,9223372036"

你可以看到这是一个:分隔的字符串,其中包含作为逗号分隔字段的记录。

我正在寻找以给定数量的块分割字符串的最佳(最快)方法,并注意一个块应该包含完整记录(字符串upto':')

或其他说法,不应该有任何结尾的结果:

e.g。 20 MB字符串到4个5 MB的块,每个块有适当的记录(因此每个块的大小可能不是5 MB但非常接近它,所有4个块的总数将是20 MB)

我希望你能理解我的问题(抱歉英语不好)

我喜欢以下链接,但它不会完全记录,而分割也不知道这是否是最好和最快的方式。

Split String into smaller Strings by length variable

5 个答案:

答案 0 :(得分:3)

我不知道'大字符串'有多大,但最初我只是尝试使用String.Split方法。

答案 1 :(得分:1)

我们的想法是将数据的长度除以所需的块数,然后向后看以搜索当前块中的最后一个sep。

    private string[] splitToBlocks(string data, int numBlocks, char sep)
    {
        // We return an array of the request length
        if (numBlocks <= 1 || data.Length == 0)
        {
            return new string [] { data };
        }

        string[] result = new string[numBlocks];

        // The optimal size of each block
        int blockLen = (data.Length / numBlocks);

        int idx = 0; int pos = 0; int lastSepPos = blockLen;
        while (idx < numBlocks)
        {
            // Search backwards for the first sep starting from the lastSepPos
            char c = data[lastSepPos];
            while (c != sep) { lastSepPos--; c = data[lastSepPos]; }

            // Get the block data in the result array
            result[idx] = data.Substring(pos, (lastSepPos + 1) - pos);

            // Reposition for then next block
            idx++;
            pos = lastSepPos + 1;

            if(idx == numBlocks-1)
                lastSepPos = data.Length - 1;
            else
                lastSepPos = blockLen * (idx + 1);
        }
        return result;
    }

请测试一下。我没有完全测试边缘情况。

答案 2 :(得分:1)

好的,我建议您分两步:

  1. 将字符串拆分为块(见下文)
  2. 检查块是否完整
  3. 在linq的帮助下将字符串拆分成块(linq扩展方法取自Split a collection into `n` parts with LINQ?):

    string tcpstring = "chunk1 : chunck2 : chunk3: chunk4 : chunck5 : chunk6";
    int numOfChunks = 4;
    
    var chunks = (from string z in (tcpstring.Split(':').AsEnumerable()) select z).Split(numOfChunks);
    
    List<string> result = new List<string>();
    foreach (IEnumerable<string> chunk in chunks)
    {
        result.Add(string.Join(":",chunk));                             
    }
    
    .......
    
    static class LinqExtensions
    {
        public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> list, int parts)
        {
            int i = 0;
            var splits = from item in list
                         group item by i++ % parts into part
                         select part.AsEnumerable();
            return splits;
        }
    }
    

    我清楚地了解你的目标吗?

    <强> [编辑] 在我看来,在性能考虑的情况下,更好的方法是使用String.Split方法进行分块

答案 3 :(得分:0)

似乎你想要拆分“:”(你可以使用Split方法)。 然后,您必须在拆分到已拆分的每个块后添加“:”。 (然后你可以用“,”分割所有被“:”拆分的字符串。

答案 4 :(得分:0)

int index = yourstring.IndexOf(":");

string[] whatever = string.Substring(0,index);

yourstring = yourstring.Substring(index); //make a new string without the part you just cut out.

这是一个通用视图示例,您需要做的就是建立一个在遇到“:”字符时运行的迭代;欢呼声...