naive string matching algorithm gone wrong - javascript

I am trying to implement naive search and I do not get the expected result. Can anyone point out here, what could be the possible error.
function naive(string, str) {
for (let i = 0; i <= string.length - str.length; i++) {
if (string[i] == str[0]) {
let counter = 1
for (let j = 1; j <= str.length; j++) {
if (string[i + j] == str[j]) {
counter++;
console.log(counter)
} else
counter = 0;
}
if (counter == str.length) {
console.log(`${counter} pattern matched at ${i}`)
}
} else
console.log('nothing matched')
}
}

var match_found = false;
function naive(string, str){
for(let i =0; i <= string.length - str.length; i++){
if(string[i] == str[0]){
let counter= 1
for(let j = 1; j < str.length; j++){
if(string[i + j] == str[j]){
counter++;
}else{
break;
}
}
if(counter == str.length){
console.log('Pattern matched at ' + i);
match_found = true;// can break; here if you wish to, else it will give you all matches present
}
}
}
if(match_found === false){
console.log(str + ' not found in ' + string);
}
}
naive('abcdgggabcdggg','ggg');
You increment the counter when there is a match, but you need to break the loop where there is a mismatch.
Your inner for loop condition needs to have j < str.length instead of j <= str.length, because index starts from 0.
else console.log('nothing matched'). You can't just instantly decide that. If a string index doesn't match, you need to still keep looking for the rest of the indexes.
Best way to go about it is to maintain a boolean flag for it as shown in the above code.

You don't need to do all that iteration and comparison by yourself. Here's a simpler version of your function:
function naive(string, str) {
var counter = 0,
i = string.indexOf(str, 0); //find first occurance of str in string
while(i !== -1){
++counter; //we have a match, count one up
console.log(`counter %i, index %i`, counter, i);
i = string.indexOf(str, i+1); //find next occurance
}
return counter;
}
console.log("result", naive("lorem upsum", "m"));

Related

JavaScript Compression String

Defined a function that takes one argument (a string) and returns another string.
Input example: aabcc
Output example: a2bc2
function compressedString(message) {
if (message.length == 0) {
return;
}
var result = "";
var count = 0;
for (var n = 0; n < message.length; n++) {
count++;
if (message[n] != message[n+1]) {
result += message[n] + count;
count = 0;
}
}
return result;
}
console.log(compressedString('aabcc'));
Output I am getting: a1b1c1
Looked over the code but don't seem to find what's wrong.
Please change one line.
result += count > 1 ? message[n] + count : message[n];
If count is lower than 2, don't add count.
You can add a Conditional operator to only append the count if it is greater than 1.
result += message[n] + (count > 1 ? count : '');
Full code:
function compressedString(message) {
if (message.length == 0) {
return;
}
var result = '';
var count = 0;
for (var n = 0; n < message.length; n++) {
count++;
if (message[n] != message[n + 1]) {
result += message[n] + (count > 1 ? count : '');
count = 0;
}
}
return result;
}
console.log(compressedString('aabcc'));
Your function was actually returning: a2b1c2. If you want to return a2bc2 you just need an if to check if count is 1:
function compressedString(message) {
if (message.length == 0) {
return;
}
var result = "";
var count = 0;
for (var n = 0; n < message.length; n++) {
count++;
if (message[n] != message[n + 1]) {
if (count == 1)
result += message[n]
else {
result += message[n] + count;
}
count = 0;
}
}
return result;
}
Suppose you have arr1 = [a1,b2,c1];
and you want to convert it into [abbc]
Javascript accepts only numbers in for loop. So if you take the elements of this array individually, in the cast of characters it won't run except in the case of all the numbers it will run. But don't use +(element) operator. Since characters will throw a NaN.
So you can approach it so easily like this:
function check(string){
var new_string = "";
for(let i=0; i < string.length; i++){
let count = string[i];
for(var j=0; j< count; j++){
new_string = new_string + string[i];
}
}
console.log(new_string);
}
check("a2b3c2");
good luck

Changing the value of an index inside an array

I'm stuck with this problem where I need to eliminate a letter from each of the array values and change the first letter if it is in index 0. My current approach is this:
function capital(arr, char){
let str = "";
let result = "";
for (let i = 0; i < arr.length; i++){
str = arr[i] + (i < arr.length - 1 ? ",": "");;
for (let j = 0; j < str.length; j++){
if (str[j] === char){
result += "";
if (str[j] === char){
result += (j === 0? "A": "");
}
else {
result += str[j];
}
}
}
console.log(result);
}
capital(["doritos","sandking","bandana", "demand"], "d");
The program should eliminate each occurrence of letter d found in the strings and change the index 0 to letter A if the d is in index 0.
The current result is
Aoritos,sanking,banana,Aeman
but it should look like
Aritos,sanking,banana,Aman
The requirement does not allow any use of built in functions, and the actual program requires the letters to be case insensitive, but I can work on it by substituting codes and adding couple if elses, I just need help with the changing the index 0 condition. Any help would be appreciated, thank you!
You can check if your input char is at first index str.indexOf(char) then simply add prefix "A" to your string without first char i.e str.substring(1)
function capital(arr, char) {
let str = "";
let result = "";
for (let i = 0; i < arr.length; i++) {
str = arr[i];
if(str.indexOf(char) === 0) {
result = 'A' + str.substring(1);
}else {
result = str;
}
console.log(result);
}
}
capital(["doritos", "sandking", "bandana", "demand"], "d");
this logic may help you
function capital(arr, char) {
return arr.map(e => {
let isFirst = false;
if (e[0] == "d") isFirst = true;
e = e.replace(new RegExp(char, 'ig'), '');
if (isFirst)
e = e.replace(e.charAt(0), "A");
return e;
});
}
console.log(capital(["doritos", "sandking", "bandana", "demand"], 'd'))
You can iterate through each letter of your word and update the first letter if it is matched with passed letter and at 0 index, for other index if it doesn't match with passed letter add to your result.
const capitalize = ch => {
const letter = ch.charCodeAt(0);
if(letter >= 97 && letter <= 122) {
return String.fromCharCode(letter - 32);
}
return ch;
}
const capital = (words, ch) => {
let result = '';
for(let i = 0; i < words.length; i++) {
let newWord = '';
for(let j = 0; j < words[i].length; j++) {
if(capitalize(words[i][j]) === capitalize(ch) && j === 0) {
newWord = 'A';
}
if(capitalize(words[i][j]) !== capitalize(ch)) {
newWord += words[i][j];
}
}
result += newWord;
if(i < words.length - 1 ) {
result += ',';
}
}
return result;
}
const result = capital(["doritos","sandking","bandana", "demand", "sandDking"], "d");
console.log(result);

Replacing all of the repeated characters in javascript

function duplicateEncode(word){
var i;
var j;
for(i = 0; i < word.length; i++) {
for(j = i + 1; j < word.length; j++) {
if (word[i] == word[j]) {
word = word.replace(/word[i]/gi, ')');
}
else word = word.replace(/word[i]/gi, '(');
};
};
return word;
}
I need to get ( if character is not repeated in the word and this ) if it is and this code doesnt work it just gives me the word back that I type in.
You are not using regex properly. Here is one possible solution based off of your original code. As you know, Strings are immutable in Javascript so we need to rebuild the string every time using your approach.
function duplicateEncode(word){
for(i = 0; i < word.length; i++) {
if (word[i] == word[i+1]) {
word = word.substring(0,i) + ')' + word.substring(i+1);
}
else {
word = word.substring(0,i) + '(' + word.substring(i+1);
}
}
return word;
}
To avoid rebuilding the string we can store the characters in an array and then join them at the end for a performance boost for large strings.
function duplicateEncode(word){
const newWordArr = [];
for(i = 0; i < word.length; i++) {
if (word[i] == word[i+1]) {
newWordArr.push(')');
}
else {
newWordArr.push('(');
}
}
return newWordArr.join('');
}

Troubleshooting Algorithm

Im working on an algorithm to return the provided string with the first letter of each word capitalized. While leaving the rest of the word in lower case. Looking for some insight to why this code isn't working. Thanks.
function titleCase(str) {
let result = "";
let words = str.split(" ");
for(let i = 0; i <= words.length; i++){
let word = words[i];
for(let j = 0; j <= word.length; j++){
if(j === 0){
result += word[j].toUpperCase();
} else{
result += word[j].toLowerCase();
}
}
return result += " "
}
return result.slice(0, result.length - 1)
}
There are three errors in your program, that are stopping it from working:
You need to change i <= words.length to i < words.length (or i <= words.length - 1), since indexes start from 0 in javascript like most
programming languages.
You need to change j <= word.length to j < word.length (or j <= word.length - 1), same reason as above.
You need to not return prematurely, and need to change return result += " " to just result += " ".
Also although it does not stop your function from working you could simplify your return line by utilizing trimEnd.
function titleCase(str) {
let result = "";
let words = str.split(" ");
for (let i = 0; i < words.length; i++) {
let word = words[i];
for (let j = 0; j < word.length; j++) {
if (j === 0) {
result += word[j].toUpperCase();
} else {
result += word[j].toLowerCase();
}
}
result += " "
}
return result.trimEnd();
}
console.log(titleCase("The quick brown fox jumps over the lazy dog"));

checking multiple elements in javascript array

I have an array 'type' with multiple elements.how to check two elements contains in 'type' array?
i have tried the below code
var i, j;
var type = [];
for (i = 1; i <= count; i++)
{
var filetype_value = parseInt((document.submission['select_type_' + i].value));
type.push(filetype_value);
}
function search(arg)
{
for (j = 1; j <= count; j++)
{
if (type[j] === arg)
{
return true;
}
else
{
return false;
}
}
}
if(search(1) && search(2))
{
alert("Contains in array")
}
There is some problems with your approach.
1) You are just checking if type[1]===arg it will return true otherwise it will return false. So it will just check for type[1].
2) because file_type value is string so filetype_value' === arg is never going to be true.
3) In your loop j=1 will never check for first element of array.
Try this
function search(arg){
var matched = false;
for (j = 0; j <= type.length; j++){
if (type[j] == arg){
matched = true;
break;
}
}
return matched;
}
You have 2 problems
You are pushing the string "filetype_value" onto your array and not the actual value so in your search function you are actually testing: 'filetype_value' === arg
You are starting your loop using 1, array's start at an index of 0
change
type.push('filetype_value');
to
type.push(filetype_value);
change
for (j = 1; j <= count; j++)
to
for (j = 0; j <= count; j++)
Also instead of doing a loop you can use the array indexOf method to test if a value is in the array
function search(arg){
return type.indexOf(arg) !== -1;
}

Categories