輸入如 "0000111000111000" 的字符串,輸出:
第1段:起始索引 4,結束索引 6
第2段:起始索引 10,結束索引 12
inSegment 布爾標記。'1' 且 !inSegment → **段開始**,記錄起始索引,置 inSegment=true。'0' 且 inSegment → **段結束**,記錄結束索引 (i-1),置 inSegment=false。inSegment 仍為真 → 最後一段延伸到末尾,記錄結束索引。using System;
using System.Collections.Generic;
public class SegmentFinder
{
public static void Main()
{
Console.Write("請輸入 0/1 字符串:");
string input = Console.ReadLine()?.Trim();
if (string.IsNullOrEmpty(input))
{
Console.WriteLine("輸入為空。");
return;
}
var segments = new List<(int Start, int End)>();
bool inSegment = false;
int start = -1;
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (c == '1')
{
if (!inSegment)
{
start = i;
inSegment = true;
}
}
else // c == '0'
{
if (inSegment)
{
segments.Add((start, i - 1));
inSegment = false;
}
}
}
// 處理以 1 結尾的情況
if (inSegment)
{
segments.Add((start, input.Length - 1));
}
// 輸出結果
if (segments.Count == 0)
{
Console.WriteLine("未發現連續 1 段。");
}
else
{
Console.WriteLine($"共發現 {segments.Count} 段連續 1:");
for (int i = 0; i < segments.Count; i++)
{
var seg = segments[i];
Console.WriteLine($"第 {i + 1} 段:起始索引 {seg.Start},結束索引 {seg.End} (長度 {seg.End - seg.Start + 1})");
}
}
}
}
輸入:0000111000111000
輸出:
共發現 2 段連續 1:
第 1 段:起始索引 4,結束索引 6 (長度 3)
第 2 段:起始索引 10,結束索引 12 (長度 3)
var segments = input
.Select((c, i) => (c, i))
.GroupAdjacent(x => x.c == '1') // 需自定義 GroupAdjacent 或用 MoreLINQ
.Where(g => g.Key)
.Select(g => (Start: g.First().i, End: g.Last().i))
.ToList();
| 指標 | 值 |
|---|---|
| 時間複雜度 | O(n) — 單次遍歷 |
| 空間複雜度 | O(k) — k 為段數,極端情況 O(n) |
byte[]:將 c == '1' 改為 b == 1。FindSegments(input.Replace('1','2').Replace('0','1').Replace('2','0'))。List 或自定義結構體。狀態機遍歷是處理「連續段」問題的通用模板,清晰、高效、易擴展。