using System.Collections.Generic;
public static void Main() {
Tuple<string, int>[] testTuples = {
Tuple.Create("zfabcde224lkfabc51+crsdtab=", 3),
Tuple.Create("ababa", 3),
Tuple.Create("abcAbc", 3),
Tuple.Create("alabama", 3),
Tuple.Create("arearea", 4),
Tuple.Create("zfabcde224lkfabc51+crsdtab=", 1),
Tuple.Create("longtest", 20)
Solution sol = new Solution();
foreach(Tuple<string, int> tuple in testTuples) {
List<Tuple<string, int>> result = sol.getSubstringCounts(tuple.Item1, tuple.Item2);
Console.WriteLine("\"" + tuple.Item1 + "\": (" + tuple.Item2 + ")");
foreach(Tuple<string, int> s in result) {
Console.WriteLine(s.Item1 + " => " + s.Item2);
private readonly bool allowOverlap;
private readonly bool ignoreCase;
private readonly uint minOccurrences;
public Solution(bool allowOverlap, bool ignoreCase, uint minOccurrences) {
this.allowOverlap = allowOverlap;
this.ignoreCase = ignoreCase;
this.minOccurrences = minOccurrences;
public List<Tuple<string, int>> getSubstringCounts(string s, int length) {
List<Tuple<string, int>> result = new List<Tuple<string, int>>();
if (s == null || s.Length < length || length < 1) {
Dictionary<string, Pair<int, int>> stringPairs = new Dictionary<string, Pair<int, int>>();
for (int start=0, end=length; end<=s.Length; start++, end++) {
string sub = s.Substring(start, length);
if (stringPairs.TryGetValue(sub, out val)) {
if (allowOverlap || start >= val.Item2) {
stringPairs.Add(sub, new Pair<int, int>(1, end));
foreach(KeyValuePair<string, Pair<int, int>> entry in stringPairs) {
if (entry.Value.Item1 >= minOccurrences) {
result.Add(Tuple.Create(entry.Key, entry.Value.Item1));
public class Pair<T1, T2> {
public Pair(T1 t1, T2 t2) {
public T1 Item1 { get; set; }
public T2 Item2 { get; set; }