Sinh tất cả substring (chuỗi con liên tiếp) của một chuỗi. Ví dụ "xyz" có 6 substring: x, y, z, xy, yz, xyz.
Thuật toán
- Vòng lặp ngoài: độ dài substring
i = 1 .. Length-1 - Vòng lặp trong: vị trí bắt đầu
start = 0 .. Length-i - Lấy substring:
str.Substring(start, i)
Mã nguồn
using System;
class Demo {
static void Main() {
string str = "xyz";
// i = độ dài substring (1 đến Length-1)
for (int i = 1; i < str.Length; i++) {
// start = vị trí bắt đầu
for (int start = 0; start <= str.Length - i; start++) {
string substr = str.Substring(start, i);
Console.WriteLine(substr);
}
}
}
}
Kết quả
x
y
z
xy
yz
Lưu ý: Chuỗi "xyz" (length=3) không in ra "xyz" vì vòng lặp ngoài chỉ đến i < str.Length (chỉ 1, 2). Để có cả chuỗi gốc, đổi thành i <= str.Length.
Phiên bản hoàn chỉnh (có cả chuỗi gốc)
static void PrintAllSubstrings(string str) {
for (int len = 1; len <= str.Length; len++) {
for (int start = 0; start <= str.Length - len; start++) {
Console.WriteLine(str.Substring(start, len));
}
}
}
// Test
PrintAllSubstrings("abc");
// a, b, c, ab, bc, abc
Số lượng substring
Chuỗi độ dài n có n*(n+1)/2 substring (tính cả chuỗi rỗng thì +1).
Lưu ý
Substring(start, length)némArgumentOutOfRangeExceptionnếu vượt giới hạn.- Cách này cấp phát string mới cho mỗi substring — tốn bộ nhớ nếu chuỗi lớn. Dùng
ReadOnlySpan<char>(.NET Core 2.1+) để zero-allocation. - Để tìm substring không trùng lặp (distinct), dùng
HashSet<string>.