How to make KMP Algorithm visualizer using HTML,CSS & JavaScript ?
Last Updated :
22 Jul, 2024
The KMP matching algorithm uses degenerating property (pattern having the same sub-patterns appearing more than once in the pattern) of the pattern and improves the worst-case complexity to O(n). The basic idea behind KMP’s algorithm is: whenever we detect a mismatch (after some matches), we already know some of the characters in the text of the next window. We take advantage of this information to avoid matching the characters that we know will anyway match.
Example:
Matching Overview
txt = "AAAAABAAABA"
pat = "AAAA"
We compare first window of txt with pat
txt = "AAAAABAAABA"
pat = "AAAA" [Initial position]
We find a match. This is same as Naive String Matching.
In the next step, we compare next window of txt with pat.
txt = "AAAAABAAABA"
pat = "AAAA" [Pattern shifted one position]
This is where KMP does optimization over Naive. In this second window, we only compare the fourth A of the pattern
with the fourth character of the current window of text to decide whether the current window matches or not. Since we know
the first three characters will anyway match, we skipped matching the first three characters.
In this article, we will see How to make a KMP Algorithm visualizer using HTML, CSS & JavaScript.
Approach: We will use the KMP Algorithm but we will be taking input of text and pattern and then we will be computing an LPS array then we will compare text and pattern and we will highlight the ways in which we are conducting the algorithm which visualize it to the user
Below is the step-by-step implementation:
Step 1: We need to now understand the HTML part of how we made the containers in HTML in order to divide we made a container that holds all of our elements like a displayer which holds elements that are to be displayed on the screen and then we have our text which holds our text followed by pattern and pattern text a message div then we have input tags for pattern and text, in the end, we have start button which at the end begins the algorithm visualization.
index.html
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<link href=
"https://fonts.googleapis.com/css2?family=Open+Sans:wght@300&display=swap"
rel="stylesheet" />
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
<title>Document</title>
</head>
<body>
<h1>
<span class="1">K</span>ruth <span class="2">
M
</span>orris
<span class="3">P</span>rat
<span>Algorithm</span>
</h1>
<div id="container">
<div id="displayer">
<div id="text"></div>
<div id="pattern"></div>
<div id="pattern_text"></div>
<div id="message"></div>
</div>
<input id="input" type="text"
placeholder="Enter the Text">
<input id="input1" type="text"
placeholder="Enter the Pattern">
<div id="start">Begin</div>
</div>
</body>
</html>
Step 2: We will have black background so we gave the text color as white to every element so that it shows and then for the span we have to make it glow so we give a text-shadow we set our HTML background color and font family now for the body we make sure everything remains center and set flex-direction as a center and for container also we give it some position same goes for the container we give it a letter spacing so that it looks neat we make a tile and make sure every element displayed is with tile for symmetric we set on hover and change color to cyan and then we style every element for its positions
style.css
CSS
* {
color: white;
font-family: "Open sans", sans-serif;
}
html {
background-color: black;
}
body {
display: flex;
flex-direction: column;
align-items: center;
height: 100vmin;
}
h1 span {
font-size: 6vmin;
font-weight: normal;
text-shadow: 0 0 20px cyan,
0 0 40px cyan,
0 0 80px cyan;
}
#container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 80%;
width: 80%;
}
#displayer {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 90%;
}
#text,
#pattern,
#message {
width: 100%;
height: 7vmin;
margin: 3vmin;
font-size: 5vmin;
display: flex;
align-items: center;
justify-content: center;
}
#message {
color: cyan;
font-size: 2vmin;
}
#pattern_text,
#array_text {
width: 100%;
height: 5vmin;
margin: 3vmin;
font-size: 5vmin;
display: flex;
align-items: center;
justify-content: center;
color: g;
}
#pattern_text#array_text {
width: 100%;
height: 5vmin;
margin: 3vmin;
font-size: 5vmin;
display: flex;
align-items: center;
justify-content: center;
color: g;
}
.tile {
width: 6vmin;
height: 6vmin;
margin: 10px;
text-align: center;
height: fit-content;
border: 1px solid black;
}
#start {
align-self: center;
background-color: black;
font-size: 3vmin;
box-sizing: border-box;
padding: 1vmin;
color: white;
cursor: pointer;
border: none;
margin-top: 2vmin;
transition: 0.5s ease-in-out;
font-weight: bold;
letter-spacing: 4px;
}
#start:hover {
transform: scale(1.5);
text-shadow: 0 0 10px cyan,
0 0 20px cyan,
0 0 40px cyan;
}
#input,
#input1 {
width: 40%;
height: 7%;
border: none;
border-radius: 7px;
background-color: #333;
color: white;
margin: 1vmin;
font-size: 2vmin;
transition: 0.5s ease-in-out;
}
#input::placeholder,
#input1::placeholder {
font-size: 3vmin;
text-align: center;
color: white;
}
h1 {
margin-top: 0;
text-align: center;
padding: 1vmin;
margin-bottom: 1vmin;
width: 100%;
font-size: 5vmin;
font-weight: normal;
letter-spacing: 2px;
border-bottom: 1px solid white;
}
Step3: like in this example we first computed the below LPS array and then when the 1st element repeats we shift the element counter to the next element and then when the p again repeats we make the index of lps array where the element repeats as 1 then when so then we iterate over the text and we compare and look for the first element we first found it on 3rd index of the text so we compare it with the next element of pattern and 4th index of text it is equal we now compare the next element of text to next element of pattern it is not equal now we send the counter on the pattern to the element to index of element which is not equal i.e 2nd index of pattern and 2nd index of lps array is 1 so we send it to 1st index then we compare next index of text i.e 5 and 1st index of pattern it is not equal we send the counter of pattern on index 1 of lps array i.e 0 now we again compare 6th index of text to 0th index of the pattern not equal now we again compare and then we found the pattern on 7th index.
script.js
JavaScript
function id(id) {
return document.getElementById(id);
}
var count = 0;
var pattern, text, Psize, Tsize;
var idcountrater = 0;
var conti = 0;
const LpsComputation = async (pattern, Psize, lps, resolve) => {
let len = 0;
let i = 1;
let j = 0;
id("message").innerText = " ";
lps[0] = 0;
for (let i = 0; i < Psize; i++) {
var tile = document.createElement('span')
tile.classList.add("tile");
tile.innerText = "0"
tile.id = idcount;
id("pattern_text").appendChild(tile);
idcount++;
}
id(idcount - Psize + idcountrater).
style.borderColor = "orange";
id(idcount - Psize + idcountrater).innerText = "0";
id(idcount - Psize + idcountrater).
style.color = "orange";
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 3000)
)
id(idcount - Psize + idcountrater).
style.borderColor = "black";
id(idcount - Psize + idcountrater).
style.color = "white"
// id(`${idcount}`)
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 2000)
)
idcountrater++;
while (i < Psize) {
if (pattern[i] == pattern[len]) {
id((idcount - Psize) + len).
style.borderColor = "cyan";
id((idcount - Psize) + len).
style.color = "cyan";
id((idcount - Psize) + i).
style.borderColor = "cyan";
id((idcount - Psize) + i).
style.color = "cyan";
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 2000)
)
id((idcount - Psize) + len + 1).
style.borderColor = "black";
id((idcount - Psize) + len + 1).
style.color = "white";
id((idcount - Psize) + len).
style.borderColor = "black";
id((idcount - Psize) + len).
style.color = "white";
len++;
lps[i] = len;
id((idcount - Psize) + i).
style.borderColor = "cyan";
id((idcount - Psize) + i).
innerText = len;
id((idcount - Psize) + i).
style.color = "cyan";
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 2000)
)
id((idcount - Psize) + i).
style.borderColor = "black";
id((idcount - Psize) + i).
style.color = "white";
i++;
} else {
if (len != 0) {
id((idcount - Psize) + len).
style.borderColor = "red";
id((idcount - Psize) + len).
style.color = "red";
id("message").innerText =
`since the next element is not equal
we need to compare from where
character is repeating in pattern`
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 4000)
)
id((idcount - Psize) + len).style.borderColor
= "black";
id((idcount - Psize) + len).style.color
= "white";
len = lps[len - 1];
id("message").innerText = `we sent
it to ${len} index`;
id((idcount - Psize) + len).style.borderColor
= "green";
id((idcount - Psize) + len).style.color
= "green";
await new Promise((resolve) =>
setTimeout(() => {
id("message").innerText = ``;
resolve();
}, 3000)
)
id((idcount - Psize) + len).style.borderColor
= "black";
id((idcount - Psize) + len).style.color
= "white";
} else {
lps[i] = 0;
id((idcount - Psize) + i).style.borderColor
= "orange";
id((idcount - Psize) + i).style.color
= "orange";
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 3000)
)
id((idcount - Psize) + i).style.borderColor
= "black";
id((idcount - Psize) + i).style.color
= "white";
i++;
}
}
} conti = 1;
resolve();
}
const kmp = async (pattern, text, Psize, Tsize) => {
var lps = [];
id("message").innerText = `Computing the LPS array first`;
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 4000)
)
await new Promise((resolve) => {
LpsComputation(pattern, Psize, lps, resolve);
})
id("message").innerText =
`Now after Computation beginning with
the comparison process`;
await new Promise((resolve) =>
setTimeout(() => {
id("message").innerText = " ";
resolve();
}, 3000)
)
console.log("inside kmp");
var i = 0;
var j = 0;
console.log(`pattern is ${pattern} text is ${text} Tsize
is ${Tsize} Psize ${Psize}`);
while (i < Tsize) {
console.log("inside for loop");
if (pattern[j] == text[i]) {
console.log("if");
id(idcount - (Tsize + Psize) - Psize + i).
style.borderColor = "orange";
id(idcount - (Tsize + Psize) - Psize + i).
style.color = "orange";
id((idcount - Psize) - Psize + j)
.style.borderColor = "orange";
id((idcount - Psize) - Psize + j).style.color
= "orange";
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 3000)
)
id(idcount - (Tsize + Psize) - Psize + i)
.style.borderColor = "cyan";
id(idcount - (Tsize + Psize) - Psize + i)
.style.color = "cyan";
id((idcount - Psize) - Psize + j)
.style.borderColor = "cyan";
id((idcount - Psize) - Psize + j).style.color
= "cyan";
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 3000)
)
id(idcount - (Tsize + Psize) - Psize + i)
.style.borderColor = "black";
id(idcount - (Tsize + Psize) - Psize + i)
.style.color = "white";
id((idcount - Psize) - Psize + j)
.style.borderColor = "black";
id((idcount - Psize) - Psize + j)
.style.color = "white";
console.log(`i is ${i} j is ${j}`);
i++; j++;
}
if (j == Psize) {
console.log(`inside i is ${i} j is${j}`);
let x = 0;
while (x < j) {
id(i - Psize).style.borderColor = "greenyellow";
id(i - Psize).style.color = "greenyellow";
id(i).style.borderColor = "greenyellow";
id(i).style.color = "greenyellow";
i++;
x++;
}
id("message").innerText =
"Pattern Found inside of the Text"
return;
} else if (i < Tsize && pattern[j] != text[i]) {
console.log("inside else if");
if (j != 0) {
console.log("INSIDE PROBLEM");
id(idcount - (Tsize + Psize) - Psize + i)
.style.borderColor
= "orange";
id(idcount - (Tsize + Psize) - Psize + i)
.style.color
= "orange";
id((idcount - Psize) - Psize + j)
.style.borderColor
= "orange";
id((idcount - Psize) - Psize + j)
.style.color
= "orange";
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 3000)
)
id(idcount - (Tsize + Psize) - Psize + i)
.style.borderColor
= "black";
id(idcount - (Tsize + Psize) - Psize + i)
.style.color
= "white";
id((idcount - Psize) - Psize + j)
.style.borderColor
= "black";
id((idcount - Psize) - Psize + j)
.style.color
= "white";
j = lps[j - 1];
console.log('logging in');
} else {
id(idcount - (Tsize + Psize) - Psize + i)
.style.borderColor
= "orange";
id(idcount - (Tsize + Psize) - Psize + i)
.style.color
= "orange";
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 3000)
)
id(idcount - (Tsize + Psize) - Psize + i)
.style.borderColor
= "black";
id(idcount - (Tsize + Psize) - Psize + i)
.style.color
= "white";
i = i + 1;
}
}
}
}
let idcount = 0;
window.onload = async () => {
id("displayer").style.display = "none";
id("start").addEventListener('click', () => {
id("displayer").style.display = "flex";
pattern = id("input1").value;
Psize = pattern.length
text = id("input").value;
Tsize = text.length;
id("input1").style.display = "none"
id("input").style.display = "none"
id("start").style.display = "none"
for (let i = 0; i < Tsize; i++) {
let tile = document.createElement('span');
tile.id = idcount;
tile.classList.add("tile");
tile.innerText = text[i];
id("text").appendChild(tile);
idcount++;
}
let idcount1 = 0;
for (let i = 0; i < Psize; i++) {
let tile = document.createElement('span');
tile.id = idcount;
tile.classList.add("tile");
tile.innerText = pattern[i];
id("pattern").appendChild(tile);
idcount++;
}
kmp(pattern, text, Psize, Tsize);
})
}
Output:
Similar Reads
How to make Kadanes Algorithm visualizer using HTML CSS & Javascript ?
In this article, we will see how to make a Kadanes Algorithm visualizer using HTML, CSS & Javascript. Approach:Â Kadanes algorithm is used to calculate the largest sum in a contiguous subarray. We are basically gonna use the algorithm as same and we are gonna use JavaScript and CSS to show the v
5 min read
How to make Moore's Voting Algorithm Visualizer using HTML CSS & JavaScript ?
This article will show how to make Moore's Voting Algorithm visualizer using HTML, CSS & JavaScript. This algorithm is used for an element that repeats more than n/2 times n is the size of the array for this element that has to repeat continuously so that is the key approach for this algorithmAp
8 min read
Create a Stack Visualizer using HTML CSS and Javascript
In this article, we will see how to create a stack visualizer using HTML, CSS & Javascript, along with understanding its implementation through the illustration.Stack is a well-known linear data structure that may follow the order LIFO(Last In First Out) or FILO(First In Last Out). There are man
9 min read
How to make own Linktree using HTML, CSS and JavaScript ?
Linktree is a tool that permits you to share multiple hyperlinks of various social media into one site. It gained popularity on Instagram, as Instagram does not allow you to share web links anywhere other than Stories and the 'bio' section of your profile page, which has a strict character limit. In
5 min read
How to make Live Coding Editor using HTML CSS and JavaScript ?
In this article, we will implement a live coding editor using HTML, CSS, and JavaScript. This project will allow you to write and execute HTML, CSS, and JavaScript code in real-time, making it an excellent tool for learning and testing your code snippets.Final OutputPrerequisiteHTMLCSSJavaScriptAppr
3 min read
How to Create a Portfolio Website using HTML CSS and JavaScript ?
A portfolio website is a website that represents you online on the web pages. It contains different sections like Introduction to Yourself, About You, Your Services, Your Contact Details, and Your Portfolio. We are going to build all of the sections with an interactive and attractive web design that
15+ min read
Sliding Window Visualizer using HTML CSS and JavaScript
Window sliding technique is used extensively in array problems and used a lot in subarray-related problems like subarray sum etc. In this article, we will understand how Sliding Window Visualizer works along with knowing the basic implementation of the visualizer.Window sliding technique is an effic
8 min read
Comb Sort Visualizer using JavaScript
Comb Sort is mainly an improvement over Bubble Sort. Comb Sort improves on Bubble Sort by using a gap of the size of more than 1. In order to know more about it. Please refer to Comb Sort. An algorithm like Comb Sort can be easily understood by visualizing instead of long codes. In this article, Com
5 min read
Gnome Sort Visualizer using JavaScript
In this article, we are going to learn Gnome sort Visualizer using javascript, Gnome Sort also called Stupid sort, is based on the concept of a Garden Gnome sorting his flower pots. In order to know more about it. Please refer to Gnome Sort.An algorithm like Gnome Sort can be easily understood by vi
4 min read
Design a Stock Market Dashboard using HTML CSS & JavaScript
We will walk through the step-by-step process of designing a Stock Market Dashboard template using HTML, CSS, and JavaScript. This application will provide users with a dashboard interface where they can view a watchlist of stocks, search for specific stocks, and see detailed information about each
11 min read