I have two strings of equal number of slashes and the same letter in each position. There is always one letter and a square bracket indicating an index. There will always be a corresponding letter in both strings.
var first = "/a/b[1]/c/d[3]/e[1]/f"
var second = "/a/b[1]/c/d[4]/e/f"
I expect output should be
result = "/a/b[1]/c/d/e/f"
This is what I came up with but maybe there's a better way of doing it as it returns /a/b/c/d/e/f which is not what i wanted. http://jsfiddle.net/3PM9H/
var first = "/a/b[1]/c/d[3]/e[1]/f".split("/");
var second = "/a/b[1]/c/d[4]/e/f".split("/");
for (var i=0; i < first.length; i++){
firstMatch = first[i].match(/\[([0-9]+)\]/g);
secondMatch = second[i].match(/\[([0-9]+)\]/g);
if (firstMatch != secondMatch){
first[i] = first[i].replace(/\[([0-9]+)\]/g,'') //get rid of the square bracket.
}
}
first.join("/");
I just solved this here. It's a node project but the main file is dependency-less hence portable.
Use the dynamic programming algorithm to compute the Levenshtein distance, and use that transform to generate the regex. Subsitutes become wildcards, inserts or deletes become optional characters.
var Levenshtein = require('levenshtein-transformation)';
var lev = new Levenshtein(str1, str2);
console.log(lev.regex());
Related
I was asked this question in a recent interview. I need to find the longest substring without repeating characters.
Given "abcabcbb", the answer is "abc", which the length is 3.
Given "bbbbb", the answer is "b", with the length of 1.
Given "pwwkew", the answer is "wke", with the length of 3
This is what I came up with, I think it works correctly, but the interviewer was not impressed and said that my solution may not work for all cases.
var str = "pwwkew";
var longSubstring = function(str) {
var obj = {}; //map object
var count = 0;
var c = []; //count array to keep the count so far
for (var i = 0; i < str.length; ++i) {
//check if the letter is already in the map
if (str[i] in obj && obj[str[i]] !== i) {
c.push(count); //we encountered repeat character, so save the count
obj = {};
obj[str[i]] = i;
count = 1;
continue;
} else {
obj[str[i]] = i;
++count;
}
}
return Math.max.apply(null, c);
}
console.log(longSubstring(str)); //prints 3
Can anyone tell me what's the problem with my solution? I think it is one of the best :) and also solves in O(n) time.
I guess the problem with your code is, it gets haywire when there is no repeating letters in the whole sentence to start with. As mentioned in one of the comments "abc" won't produce a correct result. My approach would be slightly different than yours as follows;
var str = "pwwkew",
data = Array.prototype.reduce.call(str, (p,c) => (p.test.includes(c) ? p.test = [c]
: p.test.length >= p.last.length ? p.test = p.last = p.test.concat(c)
: p.test.push(c)
, p), {last:[], test:[]}),
result = data.last.length;
console.log(data);
console.log(result);
In this reduce code we initially start with an object like {last:[], test:[]} and go over the characters one by one. If the received character is in our objects's test array we immediately reset the test array to include only the letter we tested (the p.test = [c] line). However If the received character is not in our test array then we do either one of the two thing as follows. If our test array's length is equal or longer than the last array's length then we add the current character to test array and make last array = test array. (p.test.length >= p.last.length ? p.test = p.last = p.test.concat(c) line). But if our test array's length is shorter than the last array's length we just add the current character to test array and continue likewise all the way to the end of the string one by one over single characters.
I'm writing a JavaScript function that has to take in a string argument & determine the word or words with the maximum number or repeated (or most frequent) non sequential characters and return that word or words.
The way that I went about solving this problem was to first find the maximum number of times a character was repeated per word and record that number to use later in a function to test against every word in the string (or the array of strings as I later split it); if the word met the conditions, it's pushed into an array that I return.
My maxCount function seemed to work fine on its own but when I try to make it work together with my other function to get the words with max repeated chars returned, it's not working in JS Fiddle - it keeps telling me that "string.split is not a function" - I'll admit that the way I'm using it (string.split(string[i]).length) to analyze words in the string letter by letter is a bit unconventional - I hope there's some way to salvage some of my logic to make this work in the functions that can work together to get the results that I want.
Also, I don't know if I'm using Math.max correctly/in a "legal" way, I hope so. I've tried switching my variable name to "string" thinking that would make a difference but it did not even though my arguments are of the string variety and it's a string that's being represented.
Here's a link to my Fiddle:
https://jsfiddle.net/Tamara6666/rdwxqoh6/
Here's my code:
var maxCount = function (word) {
/// var maxRepeats = 0;
var numArray = [];
var string = word;
for (var i = 0, len = string.length; i < len; i++) {
//split the word('string') into letters at the index of i
numArray.push((string.split(string[i]).length) -1);
}
var max = Math.max(...numArray);
return max;
}
///console.log(maxCount("xxxxxxxxxxxxx"));
var LetterCount = function(string){
var repeatedChars = 0;
var wordArray=[];
var stringArray = string.split(" ");
for (var i = 0; i < stringArray.length; i++){
var eachWord = stringArray[i];
var maxRepeats = maxCount(stringArray);
if (repeatedChars < maxRepeats) {
repeatedChars = maxRepeats;
wordArray = [eachWord];
}else if (repeatedChars == maxRepeats) {
wordArray.push(eachWord);
}
}
return wordArray;
};
console.log(LetterCount("I attribute my success to cats"));
//should return ["attribute", "success"]
*** I've tried to map this first function onto the array formed when I split my string at the spaces but it is just returned me an empty array (I also might not have been using map correctly in this example); I also have tried using valueOf to extract the primitive value out of the array from the first function which also didn't work. I'm not really sure what to do at this point or what angle to take- I feel if I understood more what was going wrong I could more easily go about fixing it. Any help would be much appreciated. Thanks!
You are passing an array to maxCount at line 20, while it expects a string:
var maxRepeats = maxCount(stringArray);
You should use:
var maxRepeats = maxCount(eachWord);
If you are getting split is not a function error then first make sure that your string isn't null by printing it on console. If it isn't null then confirm that its a string not an array or some other thing.
I have the below code which works. But would using RegExp be a more efficient code?
(Return true if the string in the first element of the array contains the letters of the string in the second element of the array.)
function mutation(arr) {
var first = arr[0].split("");
var second = arr[1].split("");
var answer = false;
for (var e = 0; e < second.length; e++) {
answer = false;
for (var i = 0; i < first.length; i++) {
if (first[i] === second[e]) {
answer = true;
}
}
}
return answer;
}
mutation(['hello', 'hey']);
Using regex to do this check as the code you've shown above:
var a = 'hello how are you';
var b ='hey you there';
var result = new RegExp(b.split(/ +/)[0].split('').join('|')).test( a.split(/ +/)[0] );
//=> true
First split(/ +/)[0] is used to get first word from both strings
Then split('') is used to get each letter from first word of 2nd input
join('|') is used to join them by | to get regex as h|e|y
new RegExp is used for construct a regex object
test is used to execute the regex
In ES6 it can be written as follows:
function mutation(lettersSource, checkedString) {
var referenceLetters = new Set(lettersSource); // get letters from string
var usedLetters = new Set(checkedString);
// create union of letters in both strings
var lettersUnion = new Set([...usedLetters, ...referenceLetters]);
return lettersUnion.size === referenceLetters.size;
}
This solution is O(m+n+k) where m and n is number of letters in strings, and k is number of used letters.
Your solution is O(m*n), quite inefficient.
In ES5 Object can be used as well as dictionary to collect only letters, but it will be slower for many possible letters (Unicode strings).
If you don't have to care about memory usage, you can create dense array using .charCodeAt to index elements in array for O(1) access to checking if elements exists (O(m+n+k)).
Required solution for a problem:
Id is fixed ‘qualityassurance’ I want to generate ids like: 1- q.ualityassurance
For second run id should be like: 2- qu.alityassurance
For third run it should be like: 3- qua.lityassurance
and so on till id’s length. But i dont understand how to recall function for next run with incremented value.
Code is:
Selenium.prototype.doNothing = function(){
// The do in front of Nothing in the function is what tells the system this is a global function
}
Selenium.prototype.doRandomEmail = function(locator, num)
{
var id = “qualityassurancetask”;
var stringLength = id.length;
var randomstring = ”;
var insstring = ‘.’;
var num = 1;
//var rnum = Math.floor(Math.random() * stringLength);
var remainingstring = id.substring(num,id.length);
randomstring += id.substring(0,num).concat(insstring, remainingstring);
randomstring += “#gmail.com”
num= num+1;
selenium.doType(locator,randomstring,num);
}
Try something like this:
next_address = last_address.replace(/\.(.)/, "$1.");
The idea is to look for ".?" where ? is any character (note that the literal . in the regex is used to match any character, hence my use of .? to explain). This is changed to "?.", i.e. the dot is "pushed" rightward in the string. If the new and old addresses are identical, then you've run out of combinations.
Note if your address strings contain the #gmail.com part, you need to avoid moving the dot past the #, which you can do like this:
next_address = last_address.replace(/\.(\w)/, "$1.");
That is, only allow swapping the dot with "word" characters.
I have a textarea where the user can write up to 1000 characters. I need to get the jQuery('#textarea').val() and create an array where each item is a line of the textarea's value. That means:
This is a nice line inside the textarea.
This is another line.
(let's asume this line is empty - it should be ignored).
Someone left more than 2 new lines above.
Should be converted to a JavaScript array:
var texts = [];
text[0] = 'This is a nice line inside the textarea.';
text[1] = 'This is another line.';
text[2] = 'Someone left more than 2 new lines above.';
That way they can be easily imploded for to querystring (this is the qs format required by the provider):
example.com/process.php?q=["This is a nice line inside the textarea.","This is another line.","Someone left more than 2 new lines above."]
I tried both the phpjs explode() and string.split("\n") approaches but they doesn't take care of the extra new lines (aka line breakes). Any ideas?
String.prototype.split() is sweet.
var lines = $('#mytextarea').val().split(/\n/);
var texts = [];
for (var i=0; i < lines.length; i++) {
// only push this line if it contains a non whitespace character.
if (/\S/.test(lines[i])) {
texts.push($.trim(lines[i]));
}
}
Note that String.prototype.split is not supported on all platforms, so jQuery provides $.split() instead. It simply trims whitespace around the ends of a string.
$.trim(" asd \n") // "asd"
Check it out here: http://jsfiddle.net/p9krF/1/
Use split function:
var arrayOfLines = $("#input").val().split("\n");
var split = $('#textarea').val().split('\n');
var lines = [];
for (var i = 0; i < split.length; i++)
if (split[i]) lines.push(split[i]);
return lines;
Try this
var lines = [];
$.each($('textarea').val().split(/\n/), function(i, line){
if(line && line.length){
lines.push(line);
}
});