如何修改C#代码获取单词中原顺序的连续字符组合?
生成字符串中所有连续字符组合的实现方案
你现在遇到的问题很明确:原来的代码生成的是所有字符子集(包括跳过中间字符的情况,比如"ac"),但你需要的是原顺序下的连续子串——比如"abc"要返回a、b、c、ab、bc、abc这类连续的组合。
咱们先理清楚连续子串的规律:对于一个长度为n的字符串,连续子串就是从每个起始索引start开始,取长度从1到n-start的子串。比如"abc":
- 从索引0开始:取1个字符→"a",2个→"ab",3个→"abc"
- 从索引1开始:取1个→"b",2个→"bc"
- 从索引2开始:取1个→"c"
基于这个规律,我们可以写出更直接的代码,不需要用二进制掩码的思路(那是生成所有子集的方法)。
写法一:常规循环实现
public List<string> FindAllContinuousSubstrings(string str) { var continuousSubstrings = new List<string>(); // 遍历每个起始位置 for (int start = 0; start < str.Length; start++) { // 遍历从当前起始位置开始的所有可能长度 for (int length = 1; length <= str.Length - start; length++) { continuousSubstrings.Add(str.Substring(start, length)); } } return continuousSubstrings; }
写法二:LINQ简洁实现
如果喜欢用LINQ,可以把嵌套循环转换成链式调用:
public List<string> FindAllContinuousSubstrings(string str) { return Enumerable.Range(0, str.Length) // 对每个起始位置,生成所有可能长度的子串 .SelectMany(start => Enumerable.Range(1, str.Length - start) .Select(length => str.Substring(start, length))) .ToList(); }
调整结果顺序(可选)
上面的代码返回的顺序是a、ab、abc、b、bc、c,如果你需要和示例完全一致的a、b、c、ab、bc、abc,可以加个排序:
return Enumerable.Range(0, str.Length) .SelectMany(start => Enumerable.Range(1, str.Length - start) .Select(length => str.Substring(start, length))) // 先按长度排序,再按字符串本身排序 .OrderBy(s => s.Length) .ThenBy(s => s) .ToList();
为什么原来的代码不符合需求?
原来的代码用二进制数的每一位表示是否选中对应位置的字符,比如数字5(二进制101)会选中第0和第2位字符,也就是"a"和"c",所以会生成非连续的组合。这种思路是用来生成所有字符子集的,和你要的连续子串逻辑完全不同~
内容的提问来源于stack exchange,提问作者Chor Wai Chun
相关产品推荐
相关产品推荐

