/// <summary>
/// The method "MostFrequentTriplet" should implement cancellation by token and return the most frequent triplet(s) from incoming words
/// </summary>
/// <param name="str">The string which contain only letters and commas </param>
/// <param name="ct">Incoming cancellation token</param>
/// <returns>All most frequent triplets and maximum frequency. For example, if str = "ala,bala,lylkuk,kukkuklyl,lyl", the method will return "lyl,kuk 3"</returns>
public string MostFrequentTriplet(string str, CancellationToken ct)
{
/// <summary>
/// The method will handle cancellation
/// </summary>
if (ct.IsCancellationRequested) //return string "Cenceled!" if cancellation was requested
{
try
{
ct.ThrowIfCancellationRequested();
}
catch (OperationCanceledException)
{
return "Canceled!"; //if method CancellationTokenSource.Cancel() was called ,the method will return "Canceled!"
}
}
/// <summary>
/// The method will handle wrong "str" values
/// </summary>
/// <param name="match">A flag which defines do "str" belongs to the pattern @"^[A-Za-z,]+$" or not </param>
Match match = Regex.Match(str, @"^[A-Za-z,]+$");
if (match.Success)
{
//if "str" belongs to the pattern @"^[A-Za-z,]+$, nothing happen
}
else
try
{
throw new RegexMatchTimeoutException
(); //if "str" doesn't belong to the pattern @"^[A-Za-z,]+$, the method will handle RegexMatchTimeoutException
}
catch (RegexMatchTimeoutException)
{
return "Wrong 'str' argument, 'str' should contain only letters and commas";
}
/// <summary>
/// Find most frequent triplets in the array "words"
/// </summary>
/// <param name="words">Array of words from "str"</param>
/// <param name="triplet">Triplet is a combination of three adjoining letters</param>
/// <param name="mostFrequentTriplets">Dictionary of most frequent triplets (frequency is maximium and same for all these triplets)</param>
/// <param name="tripletFrequency">Frequency of a current triplet</param>
/// <param name="maxFrequency">Current maximum frequency</param>
string[] words = str.Split(','); //get array of words from "str"
string triplet;
Dictionary
<string,
int> mostFrequentTriplets
= new Dictionary
<string,
int>();
int tripletFrequency, maxFrequency = 0;
foreach (var word in words) //will get triplets from incoming words
{
for (int i = 0; i < word.Length - 2; i++) //will find most frequent triplets in the "str" by regular expression
{
triplet = word.Substring(i, 3); //get a triplet
tripletFrequency = Regex.Matches(str, $"{triplet}").Count; //get frequency of a triplet
if (tripletFrequency >= maxFrequency)
{
maxFrequency = tripletFrequency; //find maximum frequency of triplets
try
{
mostFrequentTriplets.Add(triplet, tripletFrequency); //add triplets to dictionary
}
catch (ArgumentException) //handle ArgumentException to ignore same triplets
{ continue; }
}
}
}
foreach (var item in mostFrequentTriplets.Where(kvp => kvp.Value < maxFrequency).ToList()) //remove all not most frequent triplets(their frequency < maximum frequency)
{
mostFrequentTriplets.Remove(item.Key); //remove unnecessary triplets from dictionary
}
return string.Format($"{string.Join(",", mostFrequentTriplets.Keys.ToArray())}\t{maxFrequency}"); //return all most frequent triplets and maximum frequency. For example, if str = "ala,bala,lylkuk,kukkuklyl,lyl", the method will return "lyl,kuk 3"
}