91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

泛型KMP算法

發布時間:2020-07-24 14:46:11 來源:網絡 閱讀:316 作者:zhuweisky 欄目:編程語言

當我們需要從一個字符串(主串)中尋找一個模式串(子串)時,使用KMP算法可以極大地提升效率。KMP是一個高效的字符串匹配算法,它巧妙的消除了在匹配的過程中指針回溯的問題,關于KMP算法的更多介紹,可以參考這里。

原始的KMP算法適用的對象是字符串的匹配搜索,其實針對任意類型的串(實際上就是一個數組)的子串搜索,都可以使用KMP算法。比如,我們可能需要在byte[]中查找一個特定的字節數組,這同樣可以使用KMP算法來提升匹配性能。為此,我實現了泛型的KMP算法,使之可以應用于任意類型的串匹配。下面是該算法的完整實現。

/// <summary>
    /// 泛型KMP算法。
    /// zhuweisky 2013.06.06
    /// </summary>
    public static class GenericKMP
    {
        /// <summary>
        /// Next函數。
        /// </summary>
        /// <param name="pattern">模式串</param>
        /// <returns>回溯函數</returns>
        public static int[] Next<T>(T[] pattern) where T : IEquatable<T>
        {
            int[] nextFunction = new int[pattern.Length];
            nextFunction[0] = -1;
            if (pattern.Length < 2)
            {
                return nextFunction;
            }
            nextFunction[1] = 0;
            int computingIndex = 2; 
            int tempIndex = 0; 
            while (computingIndex < pattern.Length)  
            {
                if (pattern[computingIndex - 1].Equals(pattern[tempIndex]))  
                { 
                    nextFunction[computingIndex++] = ++tempIndex;
                }
                else
                {  
                    tempIndex = nextFunction[tempIndex];
                    if (tempIndex == -1)   
                    {  
                        nextFunction[computingIndex++] = ++tempIndex;
                    }
                }
            }
            return nextFunction;
        }
        /// <summary>
        /// KMP計算
        /// </summary>
        /// <param name="source">主串</param>      
        /// <param name="pattern">模式串</param>
        /// <returns>匹配的第一個元素的索引。-1表示沒有匹配</returns>
        public static int ExecuteKMP<T>(T[] source, T[] pattern) where T : IEquatable<T>
        {
            int[] next = Next(pattern);
            return ExecuteKMP(source, 0, source.Length, pattern, next);
        }
        /// <summary>
        /// KMP計算
        /// </summary>
        /// <param name="source">主串</param>
        /// <param name="sourceOffset">主串起始偏移</param>
        /// <param name="sourceCount">被查找的主串的元素個數</param>
        /// <param name="pattern">模式串</param>
        /// <returns>匹配的第一個元素的索引。-1表示沒有匹配</returns>
        public static int ExecuteKMP<T>(T[] source, int sourceOffset, int sourceCount, T[] pattern) where T : IEquatable<T>
        {
            int[] next = Next(pattern);
            return ExecuteKMP(source, sourceOffset, sourceCount, pattern, next);
        }
        /// <summary>
        /// KMP計算
        /// </summary>
        /// <param name="source">主串</param>      
        /// <param name="pattern">模式串</param>
        /// <param name="next">回溯函數</param>
        /// <returns>匹配的第一個元素的索引。-1表示沒有匹配</returns>
        public static int ExecuteKMP<T>(T[] source, T[] pattern, int[] next) where T : IEquatable<T>
        {           
            return ExecuteKMP(source, 0, source.Length, pattern, next);
        }
        /// <summary>
        /// KMP計算
        /// </summary>
        /// <param name="source">主串</param>
        /// <param name="sourceOffset">主串起始偏移</param>
        /// <param name="sourceCount">被查找的主串的元素個數</param>
        /// <param name="pattern">模式串</param>
        /// <param name="next">回溯函數</param>
        /// <returns>匹配的第一個元素的索引。-1表示沒有匹配</returns>
        public static int ExecuteKMP<T>(T[] source, int sourceOffset, int sourceCount, T[] pattern, int[] next) where T : IEquatable<T>
        {
            int sourceIndex = sourceOffset; 
            int patternIndex = 0;            
            while (patternIndex < pattern.Length && sourceIndex < sourceOffset + sourceCount)
            {
                if (source[sourceIndex].Equals(pattern[patternIndex]))  
                {
                    sourceIndex++;
                    patternIndex++;
                }
                else
                {
                    patternIndex = next[patternIndex];
                    if (patternIndex == -1)
                    {
                        sourceIndex++;
                        patternIndex++;
                    }
                }
            }        
            return patternIndex < pattern.Length ? -1 : sourceIndex - patternIndex;
        }
    }


說明:

(1)串中的每個元素必須能夠被比較是否相等,所以,泛型T必須實現IEquatable接口。

(2)之所以將Next函數暴露為public,是為了在外部可以緩存回溯函數,以供多次使用。因為,我們可能經常會在不同的主串中搜索同一個模式串。

(3)如果要將GenericKMP應用于字符串的匹配搜索,可以先將字符串轉換為字符數組,再調用GenericKMP算法。就像下面這樣:

string source = "..............";    

string pattern = "*****";    

int index = GenericKMP.ExecuteKMP<char>(source.ToCharArray(),pattern.ToCharArray()) ;


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

资溪县| 德江县| 南雄市| 泰宁县| 连山| 诏安县| 云浮市| 泽库县| 中宁县| 青川县| 象山县| 藁城市| 黄平县| 咸阳市| 张家港市| 苏尼特右旗| 广宗县| 时尚| 乌恰县| 富阳市| 剑川县| 伊金霍洛旗| 娱乐| 二连浩特市| 桑日县| 张家川| 邵阳市| 射洪县| 永善县| 湟源县| 平泉县| 安福县| 孝义市| 葫芦岛市| 汽车| 潼关县| 霞浦县| 遵义市| 东乡县| 涞水县| 紫金县|