C# 检测连续整数并折叠为字符串
免责声明:这是关于C 我有一个包含整数的枚举,例如:C# 检测连续整数并折叠为字符串,c#,list,algorithm,C#,List,Algorithm,免责声明:这是关于C 我有一个包含整数的枚举,例如: [1, 2, 3, 4, 7, 8, 10, 11, 12, 13, 14] 我想获得一个字符串,其中列出了连续整数的范围: 1-4, 7-8, 10-14 我想到了: public static void Main() { System.Diagnostics.Debug.WriteLine(FindConsecutiveNumbers(new int[] { 1,2, 7,8,9, 12, 15, 20,21 })); }
[1, 2, 3, 4, 7, 8, 10, 11, 12, 13, 14]
我想获得一个字符串,其中列出了连续整数的范围:
1-4, 7-8, 10-14
我想到了:
public static void Main()
{
System.Diagnostics.Debug.WriteLine(FindConsecutiveNumbers(new int[] { 1,2, 7,8,9, 12, 15, 20,21 }));
}
private static string FindConsecutiveNumbers(IEnumerable<int> numbers)
{
var sb = new StringBuilder();
int? start = null;
int? lastNumber = null;
const string s = ", ";
const string c = "-";
var numbersPlusIntMax = numbers.ToList();
numbersPlusIntMax.Add(int.MaxValue);
foreach (var number in numbersPlusIntMax)
{
var isConsecutive = lastNumber != null && lastNumber + 1 == number;
if (!isConsecutive)
{
if (start != null)
{
if (sb.Length > 0) { sb.Append(s); }
if (start == lastNumber)
{
sb.Append(start); ;
}
else
{
sb.Append(start + c + lastNumber); ;
}
}
start = number;
}
lastNumber = number;
}
return sb.ToString();
}
该算法适用于有序输入。是否有一种内置的/LINQ/C更短的方法来实现这一点?我建议分解:让我们将初始例程拆分为逻辑:
如果我们可以获得列表中的数字而不是枚举,那么我们就不需要访问所有的数字。前面的答案是时间复杂度为On,其中n是数组的大小。然而,如果我们有一个列表,这个问题可以在Oklogn中解决,其中k是组的数量
基本上,您可以使用稍加修改的二进制搜索来查找一个组的端点,这可以在Ologn中完成,然后从end+1开始,您可以对下一个组执行相同的操作。很好的解决方案+1.选择g=>g.First.value==g.Last.value${g.First.value}:${g.First.value}-{g.Last.value}为了坚持要求的格式,很好地使用了!二进制搜索。这也是个好主意。但如果我正确理解了这个方法,那么只有在团队数量少的情况下,这才会证明它的优势。没错。如果期望每个组都有很少的元素,这意味着有很多组,那么使用这种方法是没有意义的。@JackMiller,我们也可以修改二进制搜索,在最坏的情况下,它将打开,而不是在k=n的情况下打开。因此,复杂性将优于Oklogn和On。
private static IEnumerable<(int left, int right)> Consecutive(IEnumerable<int> numbers) {
int start = -1;
int stop = -2;
foreach (var item in numbers) // numbers.OrderBy(x => x) to sort numbers
if (item == stop + 1)
stop = item;
else {
if (stop >= start)
yield return (start, stop);
start = item;
stop = item;
}
if (stop >= start)
yield return (start, stop);
}
private static string FindConsecutiveNumbers(IEnumerable<int> numbers) =>
string.Join(", ", Consecutive(numbers)
.Select(item => item.left == item.right
? $"{item.left}"
: $"{item.left}-{item.right}"));
public static void Main()
{
// 1-2, 7-9, 12, 15, 20-21
System.Diagnostics.Debug.WriteLine(FindConsecutiveNumbers(new int[] {
1, 2,
7, 8, 9,
12,
15,
20, 21 }
));
}
int[] numbers = { 1, 2, 3, 4, 7, 8, 10, 11, 12, 13, 14 };
return string.Join(", ",
numbers
.Select((n, i) => new { value = n, group = n - i })
.GroupBy(o => o.group)
.Select(g => g.First().value + "-" + g.Last().value)
);