Maison > Article > interface Web > Structures de données et algorithmes en JavaScript (4) : compétences String (BF)_javascript
Une chaîne est une séquence finie de zéro ou plusieurs caractères, également appelée chaîne
La structure logique d'une chaîne est très similaire à celle d'un tableau linéaire. La différence est qu'une chaîne est un jeu de caractères, son fonctionnement est donc assez différent de celui d'un tableau linéaire. Les tableaux linéaires se concentrent davantage sur l'opération CURD d'un seul élément, tandis que les chaînes se concentrent sur des opérations telles que la recherche de la position des sous-chaînes et leur remplacement.
Bien sûr, différents langages de haut niveau ont des définitions différentes des opérations de base sur les chaînes, mais en général, l'essence des opérations est similaire. Par exemple, la recherche javascript est indexOf, la suppression des blancs est trim, la conversion de casse en LowerCase/toUpperCase, etc.
Ici, nous discutons principalement de plusieurs algorithmes classiques pour la correspondance de modèles de chaînes : BF, BM, KMP
Algorithme BF (Brute Force)
Idée de base de l'algorithme Brute-Force :
Comparez le premier caractère de la chaîne cible s avec le premier caractère de la chaîne de modèle t. S'ils sont égaux, continuez à comparer les caractères suivants un par un. Sinon, commencez par le deuxième caractère de la chaîne s et redémarrez. la chaîne t. Faites une comparaison.
Et ainsi de suite, jusqu'à ce que chaque caractère de la chaîne t soit égal à une séquence de caractères continue dans la chaîne s, la correspondance de modèle est dite réussie. À ce stade, la position du premier caractère de la chaîne t dans la chaîne s est. t position dans s, sinon la correspondance de modèle échoue
On peut voir que l'algorithme BF est un algorithme de force brute, également connu sous le nom d'algorithme de correspondance naïve ou d'algorithme de force brute.
Chaîne principale BBC ABB ABCF
Sous-chaîne ABC
Trouver la position de la sous-chaîne dans la chaîne principale correspond à l'implémentation de la méthode de recherche indexOf de 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; }
L'algorithme BF est simple et brut. Il extrait directement le tableau ci-dessous pour chaque caractère de la chaîne parent BBC ABB ABCF et le fait correspondre au premier caractère de la chaîne de modèle. S'ils sont égaux, la chaîne est à nouveau mise en correspondance.
Cela vaut la peine de le noter ici :
1 : Le nombre de fois que la boucle la plus externe sourceLength - searchLength, car la chaîne parent à laquelle nous correspondons doit être au moins supérieure ou égale à la sous-chaîne
2 : Dans la correspondance continue des sous-chaînes, le point de départ de la chaîne parent doit être superposé (i j)
3 : Déterminer si la correspondance est complète grâce à une condition. Dans BBC ABB ABCF, nous devons sauter par-dessus lorsque nous sommes dans ABB
L'algorithme ci-dessus est le plus simple, et il existe de meilleures méthodes de traitement dans le code. Par exemple, l'algorithme d'inversion peut être utilisé pour faire correspondre les auto-chaînes
.Algorithme d'optimisation (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; }
Nous n'avons pas besoin de juger la situation comme vraie, nous devons seulement juger la situation comme fausse. Lorsque le match n'est pas modifié une fois le sous-match terminé, cela signifie que le match est un match complet
Nous avons utilisé des sous-boucles dans les deux méthodes ci-dessus. Pouvons-nous le transformer en corps de boucle ?En fait, nous pouvons voir le modèle. La chaîne principale n'augmentera que de 1 à chaque fois, et la sous-chaîne sera mise en correspondance depuis le début à chaque fois, nous pouvons donc la changer en while et contrôler le pointeur d'indice <.> Algorithme d'optimisation (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 est le positionnement en indice de la chaîne principale, j est le positionnement en indice de la sous-chaîne
Lorsque la chaîne principale et les sous-chaînes sont égales, elle entre dans le mode boucle de la sous-chaîne. Lorsque le nombre de sous-boucles j satisfait la longueur de la sous-chaîne, il est vérifié qu'il s'agit d'une correspondance complète
Lorsque la chaîne principale et la sous-chaîne ne sont pas égales, vous devez reculer d'un bit l'indice de la chaîne principale. Bien sûr, lorsque i est utilisé, il peut être traité par la sous-chaîne, donc i-j 1 est nécessaire, puis la sous-chaîne est réinitialisée
Pour plus de détails, nous pouvons regarder la comparaison des codes
Quatre structures basées sur l'algorithme BF, pour/pendant/récursion
<!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 est également un algorithme de correspondance de préfixe classique. Le préfixe inclut également KMP. Nous pouvons voir que le plus gros inconvénient de cet algorithme est que le pointeur doit être reculé si la correspondance de caractères échoue, donc les performances sont très faibles. écrivez plus tard sur la mise à niveau des algorithmes KMP et BM pour BF
Téléchargement du code git :
https://github.com/JsAaron/data_structure