Home > Article > Web Front-end > Data structures and algorithms in JavaScript (4): String (BF)_javascript skills
A string is a finite sequence of zero or more characters, also called a string
The logical structure of a string is very similar to that of a linear table. The difference is that a string is a character set, so its operation is quite different from that of a linear table. Linear tables focus more on the operation CURD of a single element, while strings focus on operations such as finding the position of substrings and replacing them.
Of course, different high-level languages have different definitions of basic string operations, but in general the essence of the operations is similar. For example, javascript search is indexOf, blank removal is trim, case conversion toLowerCase/toUpperCase, etc.
Here we mainly discuss several classic algorithms for string pattern matching: BF, BM, KMP
BF (Brute Force) algorithm
Basic idea of Brute-Force algorithm:
Compare the first character of the target string s with the first character of the pattern string t. If they are equal, continue to compare the subsequent characters one by one. Otherwise, start from the second character of the string s and restart the string t. Make a comparison.
And so on, until each character in string t is equal to a continuous character sequence in string s, the pattern matching is said to be successful. At this time, the position of the first character of string t in string s is t position in s, otherwise pattern matching fails
It can be seen that the BF algorithm is a brute force algorithm, also known as the naive matching algorithm or brute force algorithm.
Main string BBC ABB ABCF
Substring ABC
Finding the position of the substring in the main string corresponds to the implementation of the indexOf search method of javascript
var sourceStr = "BBC ABB ABCF"; var searchStr = "ABC"; function BF_Ordinary(sourceStr, searchStr) { var sourceLength = sourceStr.length; var searchLength = searchStr.length; var padding = sourceLength - searchLength; //循环的次数 //BBC ABB ABCF =>ABC => 搜索9次 for (var i = 0; i <= padding; i++) { //如果满足了第一个charAt是相等的 //开始子循环检测 //其中sourceStr的取值是需要叠加i的值 if (sourceStr.charAt(i) == searchStr.charAt(0)) { //匹配成功的数据 var complete = searchLength; for (var j = 0; j < searchLength; j++) { if (sourceStr.charAt(i + j) == searchStr.charAt(j)) { --complete if (!complete) { return i; } } } } } return -1; }
The BF algorithm is simple and crude. It directly takes out the table below for each character of the BBC ABB ABCF parent string and matches it with the first character of the pattern string. If they are equal, the string is matched again
It’s worth noting here:
1: The number of times of the outermost loop sourceLength - searchLength, because the parent string we match must be at least greater than or equal to the substring
2: In the continued matching of substrings, the starting point of the parent string needs to be superimposed (i j)
3: Determine whether it matches complete through a condition. In BBC ABB ABCF, we need to jump over when we are in ABB
The above is the simplest algorithm, and there are better processing methods in the code. For example, the inversion algorithm can be used to match self-strings
Optimization Algorithm (1)
function BF_Optimize(sourceStr, searchStr) { var mainLength = sourceStr.length; var searchLength = searchStr.length; var padding = mainLength - searchLength; for (var offset = 0; offset <= padding; offset++) { var match = true; for (var i = 0; i < searchLength; i++) { //取反,如果只要不相等 if (searchStr.charAt(i) !== sourceStr.charAt(offset + i)) { match = false; break; } } if (match) return offset; } return -1; }
We don’t need to judge the situation as true, we only need to judge the situation as false. When the match is not modified after the sub-match is completed, it means that the match is a complete match
We have used sub-loops in the above two methods. Can we change it into a loop body?
In fact, we can see the pattern. The main string will only increase by 1 every time, and the substring will be matched from the beginning every time, so we can change it to a while and control the subscript pointer.
Optimization Algorithm (2)
function BF_Optimize_2(sourceStr, searchStr) { var i = 0, j = 0; while (i < sourceStr.length) { // 两字母相等则继续 if (sourceStr.charAt(i) == searchStr.charAt(j)) { i++; j++; } else { // 两字母不等则角标后退重新开始匹配 i = i - j + 1; // i 回退到上次匹配首位的下一位 j = 0; // j 回退到子串的首位 } if (j == searchStr.length) { return i - j; } } }
i is the subscript positioning of the main string, j is the subscript positioning of the substring
When the main string and substrings are equal, it enters the loop mode of the substring. When the number of subloops j satisfies the length of the substring, it is verified that it is a complete match
When the main string and the substring are not equal, you need to move the subscript of the main string back one bit. Of course, when i is used, it may be processed by the substring, so i-j 1 is needed, and then the substring is reset
For details, we can look at the code comparison
Four structures based on BF algorithm, for/while/recursion
<!doctype html>由于电脑性能的不断提高,测试的数据量的大小,可能会导致得到的结果不太准确;<script type="text/javascript"> ///////// //暴力算法 // //普通版 ///////// function BF_Ordinary(sourceStr, searchStr) { var sourceLength = sourceStr.length; var searchLength = searchStr.length; var padding = sourceLength - searchLength; //循环的次数 //BBC ABB ABCF =>ABC => 搜索9次 for (var i = 0; i <= padding; i++) { //如果满足了第一个charAt是相等的 //开始子循环检测 //其中sourceStr的取值是需要叠加i的值 if (sourceStr.charAt(i) == searchStr.charAt(0)) { //匹配成功的数据 var complete = searchLength; for (var j = 0; j < searchLength; j++) { if (sourceStr.charAt(i + j) == searchStr.charAt(j)) { --complete if (!complete) { return i; } } } } } return -1; } ///////// //暴力算法 // //优化版 ///////// function BF_Optimize_1(sourceStr, searchStr) { var mainLength = sourceStr.length; var searchLength = searchStr.length; var padding = mainLength - searchLength; for (var offset = 0; offset <= padding; offset++) { var match = true; for (var i = 0; i < searchLength; i++) { //取反,如果只要不相等 if (searchStr.charAt(i) !== sourceStr.charAt(offset + i)) { match = false; break; } } if (match) return offset; } return -1; } //////// //优化版 // //while //////// function BF_Optimize_2(sourceStr, searchStr) { var i = 0, j = 0; while (i < sourceStr.length) { // 两字母相等则继续 if (sourceStr.charAt(i) == searchStr.charAt(j)) { i++; j++; } else { // 两字母不等则角标后退重新开始匹配 i = i - j + 1; // i 回退到上次匹配首位的下一位 j = 0; // j 回退到子串的首位 } if (j == searchStr.length) { return i - j; } } } ///////// //暴力算法 //递归版本 ///////// function BF_Recursive(sourceStr, searchStr, offset) { var mainLength = sourceStr.length; var searchLength = searchStr.length; if (searchLength > mainLength - offset) { return -1; } offset = offset || 0; for (var i = 0; searchLength > i; i++) { if (searchStr.charAt(i) !== sourceStr.charAt(offset + i)) { return BF_Recursive(sourceStr, searchStr, offset + 1) } } return offset; } var sourceStr = "There are some times wThere are some times when clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer that that Facebook would “definitely thinkThere are some times when clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer that that Facebook would “definitely thinkThere are some times when clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer that that Facebook would “definitely thinkThere are some times when clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer that that Facebook would “definitely thinkThere are some times when clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer that that Facebook would “definitely thinkThere are some times when clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer that that Facebook would “definitely thinkhen clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer There are some times when clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer that that Facebook would “definitely thinkThere are some times when clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer that that Facebook would “definitely thinkThere are some times when clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer that that Facebook would “definitely thinkThere are some times when clicking “like” on a friend's Facebook status doesn't feel appropriate. A bad day. A loved one lost. A break up. It only seems natural that a “dislike” button could solve the conundrum of wanting to empathize but not seem inappropriate by clicking “like.” Mark Zuckerberg Puts the Rest of Us to Shame by Speaking Fluent Chinese. Mark Zuckerberg: Facebook Founder and Animal Butcher. Mark Zuckerberg and That Shirt. The idea has been on Mark Zuckerberg's radar for a while, he said. In 2010, he told ABC News' Diane Sawyer that that Facebook would “definitely think that that Facebook would “definitely think about” adding a dislike button. “People definitely seem to want it,” Zuckerberg said. Four years later — Zuckerberg says Facebook is still “thinking about” adding the oft-requested sdfafd button, Zuckerberg says Facebook is still “thinking about” adding the oft-requested button. At a town hall meeting on Thursday, the CEO revealed he has some reservations about the feature. “There are two things that it can mean,” Zuckerberg said of the potential button, which could be used in a mean spirited way or to express empathy. Finding how to limit it to the latter is the challenge. Zuckerberg said he doesn't want the button to turn into a “voting mechanism” or something that isn't “socially valuable.” “Often people will tell us they don't feel comfortable pressing ‘like,'” Zuckerberg said. “What's the right way to make it so people can easier express a wide range of emotions?” One suggestion percolating online: Aaron Roll out the feature under a different name. However, an “empathy button” just may not have the same ring to it as “dislike.”"; var searchStr = "adding the oft-requested sdf"; function show(bf_name,fn) { var myDate = +new Date() var r = fn(); var div = document.createElement('div') div.innerHTML = bf_name +'算法,搜索位置:' + r + ",耗时" + (+new Date() - myDate) + "ms"; document.body.appendChild(div); } show('BF_Ordinary',function() { return BF_Ordinary(sourceStr, searchStr) }) show('BF_Optimize_1',function() { return BF_Optimize_1(sourceStr, searchStr) }) show('BF_Optimize_2',function() { return BF_Optimize_2(sourceStr, searchStr) }) show('BF_Recursive',function() { return BF_Recursive(sourceStr, searchStr) }) </script>
BF is also a classic prefix matching algorithm. The prefix also includes KMP. We can see that the biggest disadvantage of this algorithm is that the pointer must be backtracked if the character matching fails, so the performance is very low. I will write about the upgrade of KMP and BM algorithms for BF later.
git code download: https://github.com/JsAaron/data_structure