Computes a value that indicates the match between two strings. - CSharp System

CSharp examples for System:String Match

Description

Computes a value that indicates the match between two strings.

Demo Code

// This file is subject to the terms and conditions defined in
using System.Globalization;
using System;/*from   w  ww  .j  a va 2s  . co  m*/

public class Main{
        /// <summary>
    /// Computes a value that indicates the match between two strings.
    /// </summary>
    /// <param name="textA">The first string.</param>
    /// <param name="textB">The second string.</param>
    /// <returns>
    /// If the strings have nothing in common 0 is returned. If the strings are identical 1 is
    /// returned. Otherwise a value between 0 and 1 is returned that indicates how similar the
    /// strings are.
    /// </returns>
    /// <remarks>
    /// This method can be used to perform a fuzzy search among keywords.
    /// </remarks>
    /// <exception cref="ArgumentNullException">
    /// <paramref name="textA"/> is <see langword="null"/>.
    /// </exception>
    /// <exception cref="ArgumentNullException">
    /// <paramref name="textB"/> is <see langword="null"/>.
    /// </exception>
    public static float ComputeMatch(string textA, string textB)
    {
      if (textA == null)
        throw new ArgumentNullException("textA");
      if (textB == null)
        throw new ArgumentNullException("textB");

      // See Game Programming Gems 6, "Closest-String Matching Algorithm"

      int maxLength = Math.Max(textA.Length, textB.Length);
      int indexA = 0;
      int indexB = 0;
      float result = 0;

      // Iterate through the left string until we run out of room
      while (indexA < textA.Length && indexB < textB.Length)
      {
        // First, check for a simple left/right match
        if (textA[indexA] == textB[indexB])
        {
          // ----- A simple match:
          // Add a proportional character's value to the match total.
          result += 1.0f / maxLength;
          // Advance both indices.
          indexA++;
          indexB++;
        }
        else if (char.ToUpperInvariant(textA[indexA]) == char.ToUpperInvariant(textB[indexB]))
        {
          // ----- A simple match when upper/lower case is ignored.
          // We'll consider a capitalization mismatch worth 90% 
          // of a normal match
          result += 0.9f / maxLength;
          // Advance both indices.
          indexA++;
          indexB++;
        }
        else
        {
          // ----- Find the next best match position.
          int indexABest = textA.Length;
          int indexBBest = textB.Length;

          int bestCount = int.MaxValue;
          int countA = 0;
          int countB = 0;

          // Here we loop through word A in an outer loop, but we also check for an 
          // early out by ensuring we don't exceed our best current count.
          for (int i = indexA; i < textA.Length && (countA + countB < bestCount); i++)
          {
            // Inner loop counting
            for (int j = indexB; j < textB.Length && (countA + countB < bestCount); j++)
            {
              // At this point, we don't care about case
              if (char.ToUpperInvariant(textA[i]) == char.ToUpperInvariant(textB[j]))
              {
                // This is the fitness measurement
                int totalCount = countA + countB;
                if (totalCount < bestCount)
                {
                  bestCount = totalCount;
                  indexABest = i;
                  indexBBest = j;
                }
              }
              countB++;
            }
            countA++;
            countB = 0;
          }
          indexA = indexABest;
          indexB = indexBBest;
        }
      }

      // Clamp to 0 or 1 to remove numerical errors.
      if (result < 0.01f)
        result = 0;
      else if (result > 0.99f)
        result = 1;

      return result;
    }
}

Related Tutorials