C#-优化代码以从字符串中获取所有子字符串

C#-优化代码以从字符串中获取所有子字符串,c#,optimization,C#,Optimization,我正在编写一个代码片段,以从给定字符串中获取所有子字符串 这是我使用的代码 var stringList = new List<string>(); for (int length = 1; length < mainString.Length; length++) { for (int start = 0; start <= mainString.Length - length; start++) { var substring =

我正在编写一个代码片段,以从给定字符串中获取所有子字符串

这是我使用的代码

 var stringList = new List<string>();
 for (int length = 1; length < mainString.Length; length++)
 {
    for (int start = 0; start <= mainString.Length - length; start++)
    {
       var substring = mainString.Substring(start, length);
       stringList.Add(substring);
    }
 }
var stringList=newlist();
对于(int-length=1;长度对于(int start=0;start字符串中的子字符串数是
O(n^2)
,因此一个循环在另一个循环中是最好的。您的代码结构是正确的

下面是我对您的代码的措辞:

void Main()
{
    var stringList = new List<string>();
    string s = "1234";
    for (int i=0; i <s.Length; i++)
        for (int j=i; j < s.Length; j++)
            stringList.Add(s.Substring(i,j-i+1));
}
void Main()
{
var stringList=新列表();
字符串s=“1234”;

对于(int i=0;i您确实需要2个
用于
循环

var input=“asd sdf dfg”;
var stringList=新列表();
for(int i=0;i
更新

您无法改进迭代


但是,您可以通过使用
固定的
数组和指针来提高性能。在某些情况下,您可以通过减少对象分配来显著提高执行速度
和处理子字符串。这还将减少地址空间的使用,并减少垃圾收集器的负载

Microsoft文档页面的相关摘录:

该对象是不可变的。每次使用类中的一个方法时,都会在内存中创建一个新的string对象,这需要为该新对象分配新的空间。在需要重复修改字符串的情况下,与创建新对象相关的开销可能会很高

实施示例:

static List<ArraySegment<char>> SubstringsOf(char[] value)
{
    var substrings = new List<ArraySegment<char>>(capacity: value.Length * (value.Length + 1) / 2 - 1);
    for (int length = 1; length < value.Length; length++)
        for (int start = 0; start <= value.Length - length; start++)
            substrings.Add(new ArraySegment<char>(value, start, length));
    return substrings;
}
微软文档上的静态列表页面、StackOverflow讨论、MSDN页面和MSDN页面。

好吧,
O(n**2)
时间复杂性是不可避免的,但是你可以尝试提高空间消耗。在许多情况下,你不希望所有的子字符串都被具体化,比如说,作为
列表

var stringList = AllSubstrings(mainString).ToList(); 
如果出于任何原因需要
列表
,只需添加
.ToList()


使用子字符串方法,即使您为循环编写错误。代码丢失这听起来像是XY问题。您打算如何处理所有这些子字符串?来自给定输入的每个可能的子字符串?@MichaelRandall Yes。Exactly@Shyamsundarshah我添加了mainString.Substring(开始,长度).代码到底缺少了什么?谢谢Phillip!所以我们没有办法改进O(n^2)?不,你不能改进O(n^2),因为有(n(n+1))/2个子字符串,用大O表示法就是O(n^2).答案的数量设置了复杂性的下限,因此您无法改进。我明白了。谢谢@phillip nganThanks的努力Michael!我只是想知道是否有任何方法可以改进时间复杂性。这里,它将与我使用的方法相同wrote@PraneetNadkar没有,谢谢迈克尔:)谢谢Leonid!我可以知道这个ArraySegment在搜索或插入方面是否比List快吗?它们用于不同的目的。
ArraySegment
表示单个子字符串,
List
表示一组子字符串。可能
if(allsubstring(“abracadabra”)。Any(“abc”){…}
不是最好的例子,因为它相当于
if(“abracadabra.Contains”(“abc”){…}
,速度更快,可读性更强。@Leonid Vasilyev:非常同意,谢谢!我提供了一个更复杂的例子(在一行中实现起来不是那么容易)根据
子字符串
方法的实现方式,这可能是O(N^3)
public static IEnumerable<string> AllSubstrings(string value) {
  if (value == null) 
    yield break; // Or throw ArgumentNullException

  for (int length = 1; length < value.Length; ++length)
    for (int start = 0; start <= value.Length - length; ++start)
      yield return value.Substring(start, length);
}
int count = AllSubstrings("abracadabra")
  .Count(item => item.StartsWith("a") && item.Length > 3);
var stringList = AllSubstrings(mainString).ToList();