错误拆分字符串索引和长度必须引用一个位置

Posted

技术标签:

【中文标题】错误拆分字符串索引和长度必须引用一个位置【英文标题】:Error split string index and length must refer to a location 【发布时间】:2021-11-12 22:43:27 【问题描述】:

我想在删除空格后根据数字(大小)拆分字符串,例如:

我有 "1254k 698 77" 大小 "3" ,我的方法应该返回:

125

4k6

987

7

这是我的代码,我在 for 循环中指出了一个错误,其中 i = 12 ,字符串索引和长度必须引用一个位置:

 public string Reshape()
    
        string str = "1254k 698 7785";

        str = str.Replace(" ", "");

        int size = 3;

        List<string> ListFormat = new List<string>();


        for (int i = 0; i <= str.Length; i += size)
        
            ListFormat.Add( str.Substring(i, size));

        

        string output = string.Join(Environment.NewLine, ListFormat.ToArray());

        return output;
            
    

如果有更有效的方法,我想重构我的代码。

会有什么问题? 我

【问题讨论】:

@Llama:没有 Llama,我实际上看到的是一个错误的代码。我不相信它有效。看看循环部分。 @Transcendent 我的错。我显然错过了这一点,只看到了“有没有更有效的方法来做到这一点”部分。 【参考方案1】:

考虑以下较短的版本。 删除空格后,我们运行一个 for 循环来遍历格式化的输入。通过使用所需的块大小递增计数器,我们可以通过在每个块的开头步进来安全地遍历字符串。我们使用String.Substring() 方法将块切割成所需的大小。 Math.Min() 方法用于判断是否有足够的字符来取。当字符小于所需大小时,Substring() 将返回输入中剩下的任何内容(在您的情况下,即最后一个“7”)。

public string Reshape(string input, int size)
    
        var result = new StringBuilder();

        input = input.Replace(" ", "");

        for (int i = 0; i < input.Length; i += size)
        
            result.AppendLine(input.Substring(i, Math.Min(size, input.Length - i)));
        

        return result.ToString();
    

另外请记住,这可能比@mecab95 的解决方案执行得慢一些,因为我们将为每个子字符串调用Math.Min() 方法。

【讨论】:

【参考方案2】:

您必须计算每次迭代中剩余的字符数。 SubString 方法的第一个参数实际上表示offset,第二个表示take。那就是说;如果您没有足够的字符匹配偏移量并接受您的字符串,那么您将遇到错误。

【讨论】:

谢谢你,看我的回答,我已经改变了方法【参考方案3】:

在效率和重构方面,我提出了这个解决方案。

您应该能够构造出最多两次传递的结果,如下所示:

string input = "1254k 698 7785";
int size = 3;
string spacer = Environment.NewLine;
// Assuming no characters are space, then there should be (length - size) / size spaces between
// so the total size should be length + (spacer count * spacer length)
int maxResultSize = input.Length + (((input.Length - size) / size) * spacer.Length);

// initialize the capacity of StringBuilder so that it doesn't need to be expanded during execution of our method
StringBuilder resultBuilder = new StringBuilder(maxResultSize);

int found = 0;
int i = 0;
do

    // Skip through the empty spaces
    while (input[i] == ' ' && i < input.Length)  ++i; 

    // If we're at the end of the string, exit the loop
    if (i == input.Length)  break; 

    // If in the previous iteration we reached a block of the max size then
    // we should add a space before writing the next character
    if (found == size)
    
        found = 0;
        resultBuilder.Append(spacer);
    

    // write the character and then increment found and our position
    resultBuilder.Append(input[i]);
    ++found;
    ++i;

while (i < input.Length);

// Build a string
string result = resultBuilder.ToString();

// Write to console
Console.WriteLine(result);

在第一遍中,我们附加输入字符串的每个非空格字符和我们想要引入的换行符。

第二遍是 StringBuilder 内部的 .ToString() 方法,并返回结果字符串。

Try it online

【讨论】:

谢谢你的分享,你觉得rextester.com/NYSP68836怎么样? @mecab95 可以,但是str = str.Replace(" ", ""); 会遍历整个字符串并构造一个没有空格的新字符串。您还在字符串末尾添加了一个换行符。【参考方案4】:

我在我的代码中改变了什么,但我觉得我们可以重构这个方法:

public string Reshape()
    
        string str = "1254k 698 77";
        str = str.Replace(" ", "");
        int size = 3;
        int RemainString = str.Length;
        StringBuilder Result = new StringBuilder();

        for (int i = 0; i <= str.Length; i += size)
        
            if (RemainString >= size)
            
                Result.AppendLine(str.Substring(i, size));
                RemainString -= size;
            
            else if (RemainString != 0)
            
                Result.AppendLine(str.Substring(i, RemainString));
                RemainString = 0;
            
        
        return Result.ToString();
    

Try it online

【讨论】:

以上是关于错误拆分字符串索引和长度必须引用一个位置的主要内容,如果未能解决你的问题,请参考以下文章

索引和长度必须引用该字符串内的位置--ArgumentOutOfRangeException

子字符串索引和长度必须引用字符串中的位置

索引和长度必须引用该字符串内的位置。 参数名: length

MySQL InnoDB引擎索引长度受限怎么办

MySQL InnoDB引擎索引长度受限怎么办

MySQL InnoDB引擎索引长度受限怎么办