Detect same occurrence in string - javascript

Let us assume I got two strings. In my case the strings are "stringA" and "stringB":
Example 1:
let stringA = "1ABC DEFGHI";
let stringB = "XYZABC DEFGHI";
Even if the two strings are not exactly the same, they still contain a large amount of letter sequences, which are identical in both. In the case above it is the string "ABC DEFGHI" that occurs in both of them.
Example 2: And heres another example:
let stringA = "0142 41193566"
let stringB = "+49 142 41193566"
In this case the result should be 142 41193566 because this string occurs in both of them.
I would describe the operation as a kind of mask operation, but I have not progressed so far in implementing it. Unfortunately, this code snippet is everything I can offer so far.
let stringA = "0142 41193566"
let stringB = "+49 142 41193566"
let stringC = "....ThISisATest"
let stringD = "+Th.ISisATest33"
let detectBiggestOccurrence = function(stringA, stringB) {
let result = []
for (let c in stringA) {
if (stringB.includes(stringA[c])) {
let index = stringB.indexOf(stringA[c])
result+=stringB[index]
}
}; return result
}
let resultWorking = detectBiggestOccurrence(stringA, stringB)
console.log("working:", resultWorking)
let resultNotWorking = detectBiggestOccurrence(stringC, stringD)
console.log("not working:", resultNotWorking)
Issue: The code above is working for the first call (detectBiggestOccurrence(stringA, stringB)) but it does not work for the second one (detectBiggestOccurrence(stringC, stringD)).

The approach that I've used to solve your problem :
Create an empty mask
Populate that empty mask by one letter in first string and check if the mask is present in the second string.
Compare mask length with last response length. If mask is bigger, mask becomes the response
function detectBiggestOccurrence(stringA, stringB){
var mask ="";
var response ="";
stringA.split('').forEach( el => {
mask +=el;
if(stringB.includes(mask)){
if(mask.length > response.length){ response = mask; }
}
else {
mask =el;
}
})
return response;
}
let stringA = "1ABC DEFGHI";
let stringB = "XYZABC DEFGHI";
console.log(detectBiggestOccurrence(stringA, stringB));
let stringC = "0142 41193566";
let stringD = "+49 142 41193566";
console.log(detectBiggestOccurrence(stringC, stringD));
let stringE = "....ThISisATest"
let stringF = "+Th.ISisATest33"
console.log(detectBiggestOccurrence(stringE, stringF));

Here is a modified version of Pierre Capo's answer. It will return a correct result, even if a "problematic" string should be tested (see my comment under Pierre's answer).
function maxmatch(a,b){
var i=0,res='',pat=a[i];
while (i<a.length) {
if (b.includes(pat)) {
if (pat.length>res.length) res=pat;
pat+=a[++i];
}
else {
if (pat.length>1) pat=pat.slice(1);
else pat=a[++i];
}
}
return res;
}
let testStrings=[["1ABC DEFGHI","XYZABC DEFGHI"],
["1ABC DEFGHI","XYZBC DEFGHI ABC"],
["0142 41193566","+49 142 41193566"],
["....ThISisATest","+Th.ISisATest33"]];
testStrings.forEach(t=>console.log(maxmatch(...t)))
When applied to the test strings (please notice: I added a modified version of the first test string) they will all return the correct answer:
ABC DEFGHI
BC DEFGHI
142 41193566
ISisATest

Related

Generate random 6 characters based on input

Generate random 6 characters based on input. Like I want to turn 1028797107357892628 into j4w8p. Or 102879708974181177 into lg36k but I want it to be consistant. Like whenever I feed 1028797107357892628 in, it should always spit out j4w8p. Is this possible? (Without a database if possible.) I know how to generate random 6 characters but I dont know how to connect it with an input tbh. I would appreciate any help, thanks.
let rid = (Math.random() + 1).toString(36).substring(7);
You can create a custom hashing function a simple function to your code would be
const seed = "1028797089741811773";
function customHash(str, outLen){
//The 4 in the next regex needs to be the length of the seed divided by the desired hash lenght
const regx = new RegExp(`.{1,${Math.floor(str.length / outLen)}}`, 'g')
const splitted = str.match(regx);
let out = "";
for(const c of splitted){
let ASCII = c % 126;
if( ASCII < 33) ASCII = 33
out += String.fromCharCode(ASCII)
}
return out.slice(0, outLen)
}
const output = customHash(seed, 6)
console.log(output)
It is called hashing, hashing is not random. In your example to get rid:
let rid = (Math.random() + 1).toString(36).substring(7);
Because it is random, it's impossible to be able to produce "consistant result" as you expect.
You need algorithm to produce a "random" consistant result.
Thanks everyone, solved my issue.
Code:
let seed = Number(1028797089741811773)
let rid = seed.toString(36).substring(0,6)
console.log(rid)
Or:
let seed = Number(1028797089741811773)
let rid = seed.toString(36).substring(6)
console.log(rid)

String.fromCharCode() not working as intended

So, I'm trying to make a simple encryption and decryption application where the user inputs are upped by some amount of characters. For Eg: user inputs "abcd" then it converts to "bcde".
Code used for encryption:
const encryptedInput = (input) => {
try {
// convert to array
let splitInput = sanitize(input).split("");
//down the characters by derived
let mapped = splitInput.map((element) =>
element == " "
? element
: String.fromCharCode(element.charCodeAt(0) + process.env.NUMBEROFCHARS)
);
let encryptedInput = mapped.join(""); // result
return encryptedInput; //return
} catch (err) {}
};
The above code works perfectly fine. Its when I try to decrypt it back to original form, It gives me weird symbols and not the original message.
Code used for decryption:
const decryptedInput = (input) => {
try {
// convert to array
let splitInput = sanitize(input).split("");
//down the characters by derived
let mapped = splitInput.map((element) =>
element == " "
? element
: String.fromCharCode(element.charCodeAt(0) - process.env.NUMBEROFCHARS)
);
let decryptedInput = mapped.join(""); // result
return decryptedInput; //return
} catch (err) {}
};
Output / Result:
During encryption:
Input: abcd
Output: bcde
During decryption:
Input: bcde
Output: ϕϟϩϳ
But I want the output as abcd not ϕϟϩϳ.
So I restarted my pc and the code works now.

Uncompress a String, repeat chars `n` times

I have the following problem statement:
Write a function, uncompress, that takes in a string as an argument.
The input string will be formatted into multiple groups according to
the following pattern:
number + char
for example, '2c' or '3a'.
The function should return an uncompressed version of the string where
each 'char' of a group is repeated 'number' times consecutively. You
may assume that the input string is well-formed according to the
previously mentioned pattern.
test_00: uncompress("2c3a1t"); // -> 'ccaaat'
Here is my code which is using a stack. The problem is that it's only returning 'cc' and I can't figure out why. I've console logged what goes into the IF ELSE and I'm hitting both so I don't understand why nothing gets pushed to the stack.
Would really appreciate the help if someone can spot what I'm missing.
const uncompress = (s) => {
const nums = '23456789';
const stack = [];
for (let char of s) {
if (nums.includes(char)) {
stack.push(Number(char));
} else {
const num = stack.pop();
stack.push(char.repeat(num));
};
};
return stack.join('');
};
console.log(uncompress("2c3a1t")); // -> 'ccaaat'
Here's how I would do it:
Split the string up into pairs of numbers and chars:
str.match(/\d+[a-zA-Z]/g)
And reduce that array to a string, while taking each value from the array, getting the char from it (cv.match(/[a-zA-Z]/)[0]) and repeating it according to the number (.repeat(parseInt(cv)))
const uncompress = str => str.match(/\d+[a-zA-Z]/g).reduce((acc, cv) =>
acc + cv.match(/[a-zA-Z]/)[0].repeat(parseInt(cv)), "")
console.log(uncompress("2c3a1t"))
console.log(uncompress("27b1d8g"))
And just like that I was able to write the code which passed the test case:
const nums = '123456789';
const stack = [];
for (let char of s) {
if (nums.includes(char)) {
stack.push(Number(char));
} else {
let num = '';
while (nums.includes(stack[stack.length - 1])) {
num += stack.pop();
}
stack.push(char.repeat(num));
};
};
return stack.join('');
};

How to get a substring in JS

I have a search input and I need to bold a mathcing part of the string in result.
For example:
input: mac
Search results:
mac book pro 16
iMac 27"
Important macOS tips
I tried do something like that:
let results = document.querySelectorAll('.search-result-child');
results.forEach(result => {
let resultText = result.children[0].innerText;
let startText = resultText.toLowerCase().indexOf(searchInput.value.toLowerCase());
let matchingWord = resultText.toLowerCase().substring(startText);
let newWord = `${resultText.substring(0, startText)}<b>${matchingWord}</b>${partAfterMatchingWordHere}`;
result.children[0].innerHTML = newWord;
})
But in that case I don't know how to get the end index
So in word "mac book pro" - the first index need to be 0 and the last need to be 2.
If you have a solution for it or a best way to do that please help me
I was able to do it thanks to https://stackoverflow.com/users/12270289/klaycon
Code:
let results = document.querySelectorAll('.search-result-child');
results.forEach(result => {
let resultText = result.children[0].innerText;
let newWord = resultText.toLowerCase().replace(searchInput.value.toLowerCase(), `<b>${searchInput.value}</b>`);
result.children[0].innerHTML = newWord;
})
You can add (String.length-1) to the start index to get the ending index

Integer and string Javascript

i do a simple exercise "Write a JavaScript program to compute the sum of the two given integers. If the two values are same, then returns triple their sum".
InnerHTML is ok but it seems that my variables are string and not numbers (if i use parseFloat however it doesn't work).
Example : p161 = 10; p162 = 5; => ris = 105 and not 15
let p16 = document.getElementById("p16");
document.getElementById("button16").addEventListener("click", es);
function es(){
let p161 = document.getElementById("input161").value;
let p162 = document.getElementById("input162").value;
let ris = 0;
if (p161 == p162){
ris = (p161 + p162)*3;
return p16.innerHTML = ris;
} else {
ris = p161 + p162;
return p16.innerHTML = ris;
}
}
You are concatenating strings so what you see makes sense. Since you are looking for the sum of integers I dont see why you need to parseFloat. If you want numbers you should just do
let p161 = +document.getElementById("input161").value;
let p162 = +document.getElementById("input162").value;
Plus sign in this case is the unary operator that will convert value to Number type according to ECMA spec

Categories

Resources