輸入字串 "1334677999",輸出 "134679",即移除重複字元,保留首次出現順序。
public static string RemoveDuplicateChars(string input)
{
if (string.IsNullOrEmpty(input)) return input;
var result = new System.Text.StringBuilder(input.Length);
var seen = new bool[char.MaxValue + 1]; // 或 HashSet
foreach (char c in input)
{
if (!seen[c])
{
seen[c] = true;
result.Append(c);
}
}
return result.ToString();
}
| 指標 | 數值 |
|---|---|
| 時間複雜度 | O(n),n = 字串長度 |
| 空間複雜度 | O(1) 固定陣列 / O(k) HashSet,k = 不重複字元數 |
| 穩定性 | 穩定(保留首現順序) |
/* 原始版本:使用 IndexOf 字串搜尋,O(n²) */
public static string Qu(string lab)
{
string strResult = string.Empty;
for (int i = 0; i < lab.Length; i++)
{
if (strResult.IndexOf(lab.Substring(i, 1)) < 0)
strResult += lab.Substring(i, 1); // 字串不可變,頻繁配置
}
return strResult;
}
IndexOf 每次掃描結果字串,Substring 配置新字串,+= 產生中間字串,效能極差。StringBuilder + bool[] / HashSet<char>,單趟掃描,零額外配置。
public static string RemoveDuplicateCharsUnicode(string input)
{
if (string.IsNullOrEmpty(input)) return input;
var seen = new HashSet();
var sb = new StringBuilder();
foreach (int codePoint in input.EnumerateRunes()) // .NET Core 3.0+ / .NET 5+
{
if (seen.Add(codePoint))
sb.AppendRune(codePoint);
}
return sb.ToString();
}
使用 StringInfo 或 EnumerateRunes 正確處理代理對。
[TestMethod]
public void RemoveDuplicateChars_Test()
{
Assert.AreEqual("134679", RemoveDuplicateChars("1334677999"));
Assert.AreEqual("abc", RemoveDuplicateChars("aaabbbccc"));
Assert.AreEqual("", RemoveDuplicateChars(""));
Assert.AreEqual("中文", RemoveDuplicateChars("中中文文"));
Assert.AreEqual("😀😁", RemoveDuplicateCharsUnicode("😀😀😁😁")); // Emoji
}