{"id":55,"date":"2020-06-07T09:09:43","date_gmt":"2020-06-07T09:09:43","guid":{"rendered":"https:\/\/michaeljohnsteiner.com\/?p=55"},"modified":"2020-06-07T09:09:43","modified_gmt":"2020-06-07T09:09:43","slug":"bmpartialpatternsearch-cs","status":"publish","type":"post","link":"https:\/\/michaeljohnsteiner.com\/index.php\/2020\/06\/07\/bmpartialpatternsearch-cs\/","title":{"rendered":"BMPartialPatternSearch.cs"},"content":{"rendered":"\n<p>Boyer Moore Partial Pattern Search<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.Collections.Generic;\npublic class BMPartialPatternSearch\n{\n    public int MinimumSearchLength;\n    public BMPartialPatternSearch(int min = 5)\n    {\n        MinimumSearchLength = min;\n    }\n    public (byte[] partialPattern, int idx) SearchPartial(byte[] pattern, byte[] searchArray)\n    {\n        var bm   = new BoyerMoore(pattern);\n        var len  = pattern.Length;\n        var tree = new List&lt;byte[]>();\n        if (len &lt; MinimumSearchLength)\n            throw new Exception(\"Search Pattern less than minimum search length.\");\n        var offset = 0;\n        var wl     = MinimumSearchLength;\n        do\n        {\n            var tpat = new byte[wl];\n            Array.Copy(pattern, offset, tpat, 0, wl);\n            tree.Add(tpat);\n            bm.SetPattern(tpat);\n            var idx = bm.Search(searchArray);\n            if (idx != -1)\n                return (tpat, idx);\n            if (offset + wl >= len)\n            {\n                offset = 0;\n                wl++;\n                continue;\n            }\n            offset++;\n        } while (wl != len + 1);\n        return (pattern, -1);\n    }\n    public List&lt;(byte[] partialPattern, int idx)> SearchPartialFirst(byte[] pattern, byte[] searchArray)\n    {\n        var bm   = new BoyerMoore(pattern);\n        var len  = pattern.Length;\n        var lst  = new List&lt;(byte[] partialPattern, int idx)>();\n        var tree = new List&lt;byte[]>();\n        if (len &lt; MinimumSearchLength)\n            throw new Exception(\"Search Pattern less than minimum search length.\");\n        var offset = 0;\n        var wl     = MinimumSearchLength;\n        do\n        {\n            var tpat = new byte[wl];\n            Array.Copy(pattern, offset, tpat, 0, wl);\n            tree.Add(tpat);\n            bm.SetPattern(tpat);\n            var idx = bm.Search(searchArray);\n            if (idx != -1)\n                lst.Add((tpat, idx));\n            if (offset + wl >= len)\n            {\n                offset = 0;\n                wl++;\n                continue;\n            }\n            offset++;\n        } while (wl != len + 1);\n        return new List&lt;(byte[] partialPattern, int idx)> {(pattern, -1)};\n    }\n    public List&lt;(byte[] partialPattern, int idx)> SearchPartialAll(byte[] pattern, byte[] searchArray)\n    {\n        var bm   = new BoyerMoore(pattern);\n        var len  = pattern.Length;\n        var lst  = new List&lt;(byte[] partialPattern, int idx)>();\n        var tree = new List&lt;byte[]>();\n        if (len &lt; MinimumSearchLength)\n            throw new Exception(\"Search Pattern less than minimum search length.\");\n        var offset = 0;\n        var wl     = MinimumSearchLength;\n        do\n        {\n            var tpat = new byte[wl];\n            Array.Copy(pattern, offset, tpat, 0, wl);\n            tree.Add(tpat);\n            bm.SetPattern(tpat);\n            var idxl = bm.SearchAll(searchArray);\n            if (idxl.Item1.Count > 0)\n                foreach (var idx in idxl.Item1)\n                    lst.Add((tpat, idx));\n            if (offset + wl >= len)\n            {\n                offset = 0;\n                wl++;\n                continue;\n            }\n            offset++;\n        } while (wl != len + 1);\n        return lst;\n    }\n    public static Dictionary&lt;string, int> SearchPartialSubSet(byte[] searchArray, int startLength, int endLength)\n    {\n        var pattern = (byte[]) searchArray.Clone();\n        var bm      = new BoyerMoore(pattern);\n        var pLen    = pattern.Length;\n        var lst     = new Dictionary&lt;string, int>();\n        var tree    = new List&lt;byte[]>();\n        if (pLen &lt; endLength)\n            throw new Exception(\"Search Pattern less than minimum search length.\");\n        var offset = 0;\n        var wl     = startLength;\n        do\n        {\n            var tpat = new byte[wl];\n            Array.Copy(pattern, offset, tpat, 0, wl);\n            tree.Add(tpat);\n            bm.SetPattern(tpat);\n            var idxl = bm.SearchAll(searchArray);\n            if (idxl.Item1.Count > 1)\n            {\n                var sapat = tpat.ToHexString();\n                if (!lst.ContainsKey(sapat))\n                    lst.Add(sapat, idxl.Item1.Count);\n            }\n            if (offset + wl >= pLen)\n            {\n                offset = 0;\n                wl++;\n                if (wl > endLength)\n                    break;\n                continue;\n            }\n            offset++;\n        } while (wl != pLen + 1);\n        return lst;\n    }\n    public static Dictionary&lt;string, int> SearchPartialSubSet(byte[] searchArray1, byte[] searchArray2, int startLength, int endLength)\n    {\n        var bm   = new BoyerMoore(searchArray2);\n        var pLen = searchArray2.Length;\n        var lst  = new Dictionary&lt;string, int>();\n        var tree = new List&lt;byte[]>();\n        if (pLen &lt; endLength)\n            throw new Exception(\"Search Pattern less than minimum search length.\");\n        var offset = 0;\n        var wl     = startLength;\n        do\n        {\n            var tpat = new byte[wl];\n            Array.Copy(searchArray2, offset, tpat, 0, wl);\n            tree.Add(tpat);\n            bm.SetPattern(tpat);\n            var idxl = bm.SearchAll(searchArray1);\n            if (idxl.Item1.Count > 1)\n            {\n                var sapat = tpat.ToHexString();\n                if (!lst.ContainsKey(sapat))\n                    lst.Add(sapat, idxl.Item1.Count);\n            }\n            if (offset + wl >= pLen)\n            {\n                offset = 0;\n                wl++;\n                if (wl > endLength)\n                    break;\n                continue;\n            }\n            offset++;\n        } while (wl != pLen + 1);\n        return lst;\n    }\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Boyer Moore Partial Pattern Search<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/55"}],"collection":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/comments?post=55"}],"version-history":[{"count":1,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/55\/revisions"}],"predecessor-version":[{"id":56,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/55\/revisions\/56"}],"wp:attachment":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/media?parent=55"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/categories?post=55"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/tags?post=55"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}