Deleting consecutive empty strings in an array, but one - javascript

I want to write a function that replaces all the vowels (a,e,i,o,u) in a string and keeps one separator ('') between consonants. For example:
Input: 'kkkeoiekkk'
Output: ['kkk', '', 'kkk']
My try:
function split(para) {
let regex = /[a|e|i|o|u]/g;
let arr = para.replace(regex, '-').split('-');
for (let i = 0; i < str.length; i++) {
if (arr[i] === '' && arr[i - 1] === '') {}
}
return arr
}
Right now for the input split('hheeooook') I get back [ 'h', '', '', '', 'k' ] instead of ['h', '', 'k']. Thanks for everyone reading or pointing out what is wrong with my function.

Here is a slight variation on your attempt. It is mainly the regex which needed change.
function split (para) {
let regex = /[aeiou]+/g;
let arr = para.replace(regex, ' ').trim().split(' ');
return arr
}
console.log(split('kkhkeoiektr'));
console.log(split('akkeoihhkoo'));
console.log(split('kkeoihhkoo'));

Here is a solution without regex:
function split(para) {
let res = [];
let tmp = '';
for (let i = 0; i < para.length; i++) {
if ('aeiou'.includes(para[i])) {
if (tmp.length) {
res.push(tmp);
res.push('');
tmp = '';
}
} else {
tmp += para[i];
}
}
if (tmp.length) {
res.push(tmp);
} else {
if (res.length > 0)
res.pop();
}
return res;
}
console.log(split('kkkeoiekkk'));
console.log(split('kkkeoiekkka'));
console.log(split('kkkeoiekkkak'));

You can iterate to split the string.
var dict = {"a":1,"e":1,"i":1,"o":1,"u":1};
const src = 'kkkeoiekkk0qwert';
var pre = "";
var result = [];
for(var i = 0; i < src.length; i++){
var char = src.charAt(i);
console.log(char);
console.log(pre);
if(dict[char]){
if(pre){
result.push(pre);
pre = "";
}
}else{
pre += char;
}
}
if(pre){
result.push(pre);
}

An alternative using reg.exec:
function split (para) {
let res = [""], reg = /[^aeiou]+/g, match;
while(match = reg.exec(para)) res.push(match[0], "");
return res.slice(1, res.length - 1);
}
console.log(split('kkhkeoiektr'));
console.log(split('akkeoihhkoo'));
console.log(split('kkeoihhkoo'));
console.log(split('kkkk'));
console.log(split('aeiou'));

Related

JavaScript How to Create a Function that returns a string with number of times a characters shows up in a string

I am trying to figure out how to make a function that takes a string. Then it needs to return a string with each letter that appears in the function along with the number of times it appears in the string. For instance "eggs" should return e1g2s1.
function charRepString(word) {
var array = [];
var strCount = '';
var countArr = [];
// Need an Array with all the characters that appear in the String
for (var i = 0; i < word.length; i++) {
if (array.indexOf(word[i]) === false) {
array.push(word[i]);
}
}
// Need to iterate through the word and compare it with each char in the Array with characters and save the count of each char.
for (var j = 0; j < word.length; i++) {
for (var k = 0; k < array.length; k++){
var count = 0;
if (word[i] === array[k]){
count++;
}
countArr.push(count);
}
// Then I need to put the arrays into a string with each character before the number of times its repeated.
return strCount;
}
console.log(charRepString("taco")); //t1a1co1
console.log(charRepString("egg")); //e1g2
let str = prompt('type a string ') || 'taco'
function getcount(str) {
str = str.split('')
let obj = {}
for (i in str) {
let char = str[i]
let keys = Object.getOwnPropertyNames(obj)
if (keys.includes(char)) {
obj[char] += 1
} else {
obj[char] = 1
}
}
let result = ''
Object.getOwnPropertyNames(obj).forEach((prop) => {
result += prop + obj[prop]
})
return result
}
console.log(getcount(str))
If the order of the alphanumeric symbols matters
const str = "10zza";
const counted = [...[...str].reduce((m, s) => (
m.set(s, (m.get(s) || 0) + 1), m
), new Map())].flat().join("");
console.log(counted); // "1101z2a1"
Or also like (as suggested by Bravo):
const str = "10zza";
const counted = [...new Set([...str])].map((s) =>
`${s}${str.split(s).length-1}`
).join("");
console.log(counted); // "1101z2a1"
A more clear and verbose solution-
Let m be max number of symbols in charset
Time complexity- O(n log(m))
Space complexity- O(m)
function countFrequencies(str) {
const freqs = new Map()
for (const char of str) {
const prevFreq = freqs.get(char) || 0
freqs.set(char, prevFreq + 1)
}
return freqs
}
function getCountStr(str) {
const freqs = countFrequencies(str)
const isListed = new Set()
const resultArray = []
for (const char of str) {
if (isListed.has(char)) continue
resultArray.push(char)
resultArray.push(freqs.get(char))
isListed.add(char)
}
return resultArray.join("")
}
console.log(getCountStr("egg"))
console.log(getCountStr("taco"))
console.log(getCountStr("10za"))
Using Set constructor, first we will get the unique data.
function myfun(str){
let createSet = new Set(str);
let newArr = [...createSet].map(function(elem){
return `${elem}${str.split(elem).length-1}`
});
let newStr = newArr.join('');
console.log(newStr);
}
myfun('array');

Longest Common Prefix in Javascript

I am trying to solve the Leet Code challenge 14. Longest Common Prefix:
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string "".
Example 1:
Input: strs = ["flower","flow","flight"]
Output: "fl"
Example 2:
Input: strs = ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.
Constraints:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] consists of only lower-case English letters.
My solution:
let strs = ["flower", "flow", "flight"];
var longestCommonPrefix = function (strs) {
for (let i = 0; i < strs.length; i++) {
for (let j = 0; j < strs[i].length; j++) {
// console.log(strs[i+2][j]);
if (strs[i][j] == strs[i + 1][j] && strs[i + 1][j] ==strs[i + 2][j]) {
return (strs[i][j]);
} else {
return "0";
}
}
}
};
console.log(longestCommonPrefix(strs));
Output: f
How can I iterate over every character and check if it is same and then go for next and if it fails then the longest common prefix will be returned?
As the longest common prefix must occur in every string of the array you can jus iterate over the length and check if all words have the same char at that index until you find a difference
function prefix(words){
// check border cases size 1 array and empty first word)
if (!words[0] || words.length == 1) return words[0] || "";
let i = 0;
// while all words have the same character at position i, increment i
while(words[0][i] && words.every(w => w[i] === words[0][i]))
i++;
// prefix is the substring from the beginning to the last successfully checked i
return words[0].substr(0, i);
}
console.log(1, prefix([]));
console.log(2, prefix([""]));
console.log(3, prefix(["abc"]));
console.log(4, prefix(["abcdefgh", "abcde", "abe"]));
console.log(5, prefix(["abc", "abc", "abc"]));
console.log(6, prefix(["abc", "abcde", "xyz"]));
Some of the issues:
Your inner loop will encounter a return on its first iteration. This means your loops will never repeat, and the return value will always be one character.
It is wrong to address strs[i+1] and strs[i+2] in your loop, as those indexes will go out of bounds (>= strs.length)
Instead of performing character by character comparison, you could use substring (prefix) comparison (in one operation): this may seem a waste, but as such comparison happens "below" JavaScript code, it is very fast (and as string size limit is 200 characters, this is fine).
The algorithm could start by selecting an existing string as prefix and then shorten it every time there is a string in the input that doesn't have it as prefix. At the end you will be left with the common prefix.
It is good to start with the shortest string as the initial prefix candidate, as the common prefix can certainly not be longer than that.
var longestCommonPrefix = function(strs) {
let prefix = strs.reduce((acc, str) => str.length < acc.length ? str : acc);
for (let str of strs) {
while (str.slice(0, prefix.length) != prefix) {
prefix = prefix.slice(0, -1);
}
}
return prefix;
};
let res = longestCommonPrefix(["flower","flow","flight"]);
console.log(res);
An approach based on sorting by word length, and for the shortest word, for exiting early, an entirely Array.every-based prefix-validation and -aggregation ...
function longestCommonPrefix(arr) {
const charList = [];
const [shortestWord, ...wordList] =
// sort shallow copy by item `length` first.
[...arr].sort((a, b) => a.length - b.length);
shortestWord
.split('')
.every((char, idx) => {
const isValidChar = wordList.every(word =>
word.charAt(idx) === char
);
if (isValidChar) {
charList.push(char);
}
return isValidChar;
});
return charList.join('');
}
console.log(
longestCommonPrefix(["flower","flow","flight"])
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
not the best solution but this should work
function longestPrefix(strs){
if(strs.length <1){
return "";
}
const sharedPrefix=function(str1,str2){
let i=0;
for(;i<Math.min(str1.length,str2.length) /*todo optimize*/;++i){
if(str1[i] !== str2[i]){
break;
}
}
return str1.substr(0,i);
};
let curr = strs[0];
for(let i=1;i<strs.length;++i){
curr=sharedPrefix(curr,strs[i]);
if(curr.length < 1){
// no shared prefix
return "";
}
}
return curr;
}
this:
strs[i][j] == strs[i + 1][j] ==strs[i + 2][j]
makes no sense in JS... or at least, makes no sense in what you are doing... to do this you should use a && operator, like this:
strs[i][j] == strs[i + 1][j] && strs[i + 1][j] ==strs[i + 2][j]
Otherwise JS will evaluate the first condition, and then will evaluate the result of that operation (either true or false) with the third value
In addition to this, consider that you are looping with i over the array, and so i will also be str.length - 1 but in the condition you are referencing strs[i + 2][j] that will be in that case strs[str.length + 1][j] that in your case, makes no sense.
About the solution:
You should consider that the prefix is common to all the values in the array, so you can take in consideration one value, and just check if all the other are equals... the most obvious is the first one, and you will end up with something like this:
let strs = ["flower", "flow", "flight", "dix"];
function longestCommonPrefix (strs) {
// loop over the characters of the first element
for (let j = 0; j < strs[0].length; j++) {
// ignore the first elements since is obvious that is equal to itself
for (let i = 1; i < strs.length; i++) {
/* in case you have like
[
'banana',
'bana'
]
the longest prefix is the second element
*/
if(j >= strs[i].length){
return strs[i]
}
// different i-th element
if(strs[0][j] != strs[i][j]){
return strs[0].substr(0, j)
}
}
}
// all good, then the first element is common to all the other elements
return strs[0]
};
console.log(longestCommonPrefix(strs));
you can do it like this, it works fast enough ~ 110ms
function longestCommonPrefix(strs){
if (strs.length === 0) {
return ''
}
const first = strs[0];
let response = '';
let prefix = '';
for (let i = 0; i < first.length; i++) {
prefix += first[i];
let find = strs.filter(s => s.startsWith(prefix));
if (find.length === strs.length) {
response = prefix;
}
}
return response;
};
let strs = ["flower", "flow", "flight"];
var longestCommonPrefix = function (strs) {
for (let i = 0; i < strs.length; i++) {
for (let j = 0; j < strs[i].length; j++) {
console.log(strs[i+2][j]);
if (strs[i][j] == strs[i + 1][j] && strs[i][j] ==strs[i + 2][j]) {
return (strs[i][j]);
} else {
return "0";
}
}
}
};
console.log(longestCommonPrefix(strs));
This **return ** f
Increase the index while the letter is the same at that index for all words in the list. Then slice on it.
function prefix(words) {
if (words.length === 0) { return '' }
let index = 0;
while (allSameAtIndex(words, index)) {
index++;
}
return words[0].slice(0, index);
}
function allSameAtIndex(words, index) {
let last;
for (const word of words) {
if (last !== undefined && word[index] !== last[index]) {
return false;
}
last = word;
}
return true;
}
I assume you are here for Leetcode problem solution.
var longestCommonPrefix = function(strs) {
let arr = strs.concat().sort();
const a1 = arr[0];
const a2 = arr[arr.length -1];
const length = a1.length;
let i=0;
while(i<length && a1.charAt(i) == a2.charAt(i)) i++;
return a1.substring(0,i);
};
function prefixLen(s1, s2) {
let i = 0;
while (i <= s1.length && s1[i] === s2[i]) i++;
return i;
}
function commonPrefix(arr) {
let k = prefixLen(arr[0], arr[1]);
for (let i = 2; i < arr.length; i++) {
k = Math.min(k, prefixLen(arr[0], arr[i]));
}
return arr[0].slice(0, k);
}
console.log(commonPrefix(['pirate', 'pizza', 'pilates'])) // -> "pi"
var longestCommonPrefix = function(strs) {
let prefix = "";
for(let i = 0; i < strs[0].length; i++) {
for(let j = 1; j < strs.length; j++) {
if(strs[j][i] !== strs[0][i]) return prefix;
}
prefix = prefix + strs[0][i];
}
return prefix;
};
console.log(longestCommonPrefix);
It is as simple as one loop and compare each element of the strings
const longestPrefix = (strs) => {
[word1, word2, word3] = strs;
let prefix = [];
if(strs === null || strs.length <= 2 || strs.length > 3) return 'please
insert 3 elements'
for (let i=0; i < word1.length; i++){
if(word1[i] === word2[i] && word1[i] === word3[i]){
prefix.push(word1[i])
}
}
return prefix.join('')
}
I read in another answer: 'Increase the index while the letter is the same at that index for all words in the list. Then slice on it.'
that's how I came up with this:
const findPrefix = (strs) => {
let i = 0;
while (strs.every((item) => strs[0][i] === item[i])) {
i++;
}
return strs[0].slice(0, i);
};
console.log(findPrefix(["flo", "flow", "flomingo"]));
const findPrefix = (strs) => {
let broke = false;
return strs[0].split("").reduce(
(acc, curr, index) =>
broke || !strs.every((word) => word[index] === curr)
? (broke = true && acc)
: (acc += curr),
""
);
};
console.log(findPrefix(["flower", "flow", "flamingo"]));
Here is my solution, Today I had an interview and the dev asked me the same question, I think I failed because I got stuck hahaha kinda nervous when someone is watching me 😂, anyway I decided to figure it out after the interview is done and this is my answer (without google it I swear) and for those who don't feel comfortable with the common "for loop"
const arr = ["absence", "absolute", "absolutely", "absorb"]
function getPrefix(arr) {
if (arr.length === 0 || arr.some(s => !s)) return null //if it's an empty array or one of its values is null or '', return null
const first = arr[0].split("") // turns the first position of the array, into an array
const res = arr.map(w => {
// mapping the original array
const compare = w.split("") // every item of the array will be converted in another array of its characters
return first.map((l, idx) => (compare[idx] === l ? l : "")).join("") // loop through the "first" array and compare each character
})
const prefix = first.join("").startsWith(res[res.length - 1]) // compare if the first letter starts with the last item of the returned array
? res[res.length - 1] // if true, return the final response which is the prefix
: null // else, return null, which means there is no common prefix
console.log("prefix: ", prefix)
return prefix
}
getPrefix(arr)
let arr = ["flower", "flow", "flight"]
function checkPrefix(array) {
let index = []
for (let i = 0; i <= array[0].length; i++) {
if (check(array[0][i], i, array)) {
index.push(i)
} else {
break;
}
}
console.log(array[0].substring(index[0], index[index.length - 1] + 1));
}
const check = (str, index, stringArr) => {
debugger
let status = true
stringArr.map(ele => {
debugger
if (ele[index] != str) {
status = false
}
})
return status
}
checkPrefix(arr)
/**
* #param {string[]} strs
* #return {string}
*/
var longestCommonPrefix = function(strs) {
let compare = strs[0];
let str = "";
for (let i = 1; i < strs.length; i++) {
let j = 0;
while(compare[j] != undefined && strs[i][j] != undefined) {
if(strs[i][j] == compare[j]) {
str += strs[i][j];
}
else break;
j++;
}
compare = str;
str = "";
}
return compare;
};
Longest common prefix in Javascript (All test case accepted. Asked by many company interviews.)
var longestCommonPrefix = function (strs) {
let string = '';
if (strs.length > 1) {
for (let i = 0; i < strs[0].length; i++) {
let str = strs[0].charAt(i);
for (let s = 0; s < strs.length - 1; s++) {
if (!(strs[s + 1].charAt(i) && strs[s].charAt(i) && strs[s + 1].charAt(i) == strs[s].charAt(i))) {
str = '';
}
}
if (!str) {
break;
}
string += str;
}
return string;
} else {
return strs[0];
}
};
longestCommonPrefix(["flower","flow","flight"]);
Code to find longest prefix
var longestCommonPrefix = function(strs) {
let match = false;
let len = strs[0].length ;
let ans = "";
let prev_ans ="";
if(strs.length ==1){
return strs[0];
}
for (let i = 1; i < strs.length; i++){
if( strs[i-1].length > strs[i].length){
len = strs[i].length;
}
}
for (let i = 1; i < strs.length; i++){
for (let j = 0; j < len; j++){
if(strs[i-1].charAt(j) == strs[i].charAt(j)){
ans += strs[i-1].charAt(j);
match = true;
}
else{
break;
}
}
if(prev_ans != "" && prev_ans !=ans){
if(prev_ans.length > ans.length){
return ans;
}else{
return prev_ans;
}
}
prev_ans = ans;
ans = "";
if (match == false){
return "";
}
}
return prev_ans;
};
console.log(longestCommonPrefix(["flow","fly","flu"]));
My solution:
function longestCommonPrefix(...words) {
words.sort(); // shortest string will be first and the longest last
return (
words[0].split('') // converts shortest word to an array of chars
.map((char, idx) => words[words.length - 1][idx] === char ? char : '\0') // replaces non-matching chars with NULL char
.join('') // converts back to a string
.split('\0') // splits the string by NULL characters
.at(0) // returns the first part
);
}
Usage example:
longestCommonPrefix('abca', 'abda', 'abea'); // 'ab'
let testcases = [
["flower", "flow"], //should return "flow"
["flower", "flow", "flight"], //should return "fl"
["flower", "flow", "fight"], //should return "f"
["flower", "flow", "floor"], //should return "flo"
["flower"], //should return "flower"
]
var longestCommonPrefix = function(strs) {
for(var i=0; i<strs.length; i++){
for(var j=0; j<strs[i].length; j++){
if(strs[i][j] + strs[i][j+1] === strs[i+1][j]+strs[i+1][j+1]){
return strs[i][j]+strs[i][j+1];
}
else {
return "";
}
}
}
};
for (let strs of testcases)
console.log(longestCommonPrefix(strs));

Test word against array for anagrams - Javascript

So far.. I have this:
function anagrams(word, words) {
for(let i = 0; i <= words.length; i++){
const aCharMap = buildCharMap(word);
const bCharMap = buildCharMap(words[i]);
if(Object.keys(aCharMap).length !== Object.keys(bCharMap).length) {
words.pop(words[i])
}
for (let char in aCharMap) {
if (aCharMap[char] !== bCharMap[char]) {
words.pop(words[i]);
}
}
console.log(word);
console.log(words);
}
}
function buildCharMap(str) {
const charMap = {};
for (let char of str.replace(/[^\w]/g, '').toLowerCase()) {
charMap[char] = charMap[char] + 1 || 1;
}
return charMap;
}
The question at hand is obvious if you read through the code but here it is
Write a function that will find all the anagrams of a word from a list. You will be given two inputs a word and an array with words. You should return an array of all the anagrams or an empty array if there are none. For example:
anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']) => ['aabb', 'bbaa']
anagrams('racer', ['crazer', 'carer', 'racar', 'caers', 'racer']) => ['carer', 'racer']
anagrams('laser', ['lazing', 'lazy', 'lacer']) => []
Is pop used the way you use it?
Alternatively you can do like this:
function anagrams(word, words) {
let result = [];
const aCharMap = buildCharMap(word);
// you also had a off-by-one error in loop
for (let i = 0; i < words.length; i++) {
const bCharMap = buildCharMap(words[i]);
let isAnagram = (a, b) => {
if (Object.keys(a).length !== Object.keys(b).length) return false;
for (let char in a) {
if (aCharMap[char] !== b[char]) {
return false
}
}
return true;
}
if (isAnagram(aCharMap, bCharMap)) result.push(words[i])
}
function buildCharMap(str) {
const charMap = {};
for (let char of str.replace(/[^\w]/g, '').toLowerCase()) {
charMap[char] = charMap[char] + 1 || 1;
}
return charMap;
}
return result
}
console.log(anagrams("test", ["estt", "ttee", "tset"]))

Returning a string with only vowels capitalized

I'd like to return the variable newString with only vowels capitalized. Not sure how to proceed. Tried using an if/else block but my logic wasn't correct.
function LetterChanges(str) {
var newArray = [];
for (var i = 0; i < str.length; i++) {
var strCode = str.charCodeAt(i) + 1;
var strLetter = String.fromCharCode(strCode);
newArray.push(strLetter);
var newString = newArray.join("");
}
return newString;
}
LetterChanges("hello");
This is different from your approach, but you can do this:
function LetterChanges(str) {
return str.toLowerCase().replace(/[aeiou]/g, function(l) {
return l.toUpperCase();
});
}
console.log(LetterChanges("The Quick Brown Fox Jumped Over The Lazy Dog"));
Here's an approach that's closer to your attempt and uses somewhat simpler concepts:
function LetterChanges(str) {
var newArray = [];
for (var i = 0; i < str.length; i++) {
var ch = str.charAt(i);
if ('aeiouAEIOU'.indexOf(ch) !== -1) {
newArray.push(ch.toUpperCase());
} else {
newArray.push(ch.toLowerCase());
}
}
return newArray.join("");
}
Split, map, join.
var vowels = 'aeiou';
var text = 'my random text with inevitable vowels';
var res = text.split('').map(function(c){
return (vowels.indexOf(c) > -1) ? c.toUpperCase() : c;
});
See the fiddle: http://jsfiddle.net/zo6j89wv/1/
Strings are Collections of word-characters, so you can directly access each part of the string:
var foo = 'bar';
console.log(foo[0]); // outputs 'b'
Hence you can extend this to uppercase the output:
console.log(foo[0].toUpperCase() // outputs 'B'
To do this without regex, you can set the string to lower case, then iterate once over, calling toUpperCase() on each vowel.
function letterChanges(string){
var vowels = 'aeiou';
var lowerString = string.toLowerCase();
var result = '';
for( var i=0; i<lowerString.length; i++){
if( vowels.indexOf( lowerString[i] ) >= 0 ){ //if lowerString[i] is a vowel
result += lowerString[i].toUpperCase();
} else {
result += lowerString[i]
}
}
return result;
}
const vowelSound = string => {
let res = string.split("").filter(item => item === 'a' || item === 'i' || item === 'e' || item === 'o' || item === 'u')
return res.join("")
}

Is there any pre-built method for finding all permutations of a given string in JavaScript?

I'm a newbie to the JavaScript world. As the title mentions, I want to know whether there is any pre-built method in JavaScript to find all possible permutations of a given string.
For example, given the input:
the
Desired output:
the
teh
eht
eth
het
hte
//string permutation
function permutation(start, string) {
//base case
if ( string.length == 1 ) {
return [ start + string ];
} else {
var returnResult = [];
for (var i=0; i < string.length; i++) {
var result = permutation (string[i], string.substr(0, i) + string.substr(i+1));
for (var j=0; j<result.length; j++) {
returnResult.push(start + result[j]);
}
}
return returnResult;
}
}
permutation('','123') will return
["123", "132", "213", "231", "312", "321"]
function permutations(str){
if (str.length === 1) {
return str;
}
var permut = [];
for (var i=0; i<str.length; i++){
var s = str[0];
var _new = permutations(str.slice(1, str.length));
for(var j=0; j<_new.length; j++) {
permut.push(s + _new[j]);
}
str = str.substr(1, str.length -1) + s;
}
return permut;
}
permutations('the');
//output returns:[ 'the', 'teh', 'het', 'hte', 'eth', 'eht' ]
No pre-built, but writing such function is possible.. here is one relatively simple way using two functions:
function FindAllPermutations(str, index, buffer) {
if (typeof str == "string")
str = str.split("");
if (typeof index == "undefined")
index = 0;
if (typeof buffer == "undefined")
buffer = [];
if (index >= str.length)
return buffer;
for (var i = index; i < str.length; i++)
buffer.push(ToggleLetters(str, index, i));
return FindAllPermutations(str, index + 1, buffer);
}
function ToggleLetters(str, index1, index2) {
if (index1 != index2) {
var temp = str[index1];
str[index1] = str[index2];
str[index2] = temp;
}
return str.join("");
}
Usage:
var arrAllPermutations = FindAllPermutations("the");
Live test case: http://jsfiddle.net/yahavbr/X79vz/1/
This is just basic implementation, it won't remove duplicates and has no optimization. However for small strings you won't have any problem, add time measure like in the above test case and see what's your reasonable limit.
This is similar but finds all anagrams/permutations from an array of words. I had this question in an interview. Given an array of words ['cat', 'dog', 'tac', 'god', 'act'], return an array with all the anagrams grouped together. Makes sure the anagrams are unique.
var arr = ['cat', 'dog', 'tac', 'god', 'act'];
var allAnagrams = function(arr) {
var anagrams = {};
arr.forEach(function(str) {
var recurse = function(ana, str) {
if (str === '')
anagrams[ana] = 1;
for (var i = 0; i < str.length; i++)
recurse(ana + str[i], str.slice(0, i) + str.slice(i + 1));
};
recurse('', str);
});
return Object.keys(anagrams);
}
console.log(allAnagrams(arr));
//["cat", "cta", "act", "atc", "tca", "tac", "dog", "dgo", "odg", "ogd", "gdo", "god"]
Assuming a large string to search, you could use a regular expression
to examine a set of possibles that first matches the letters and the total number of letters,
and return the matches that use the same letter set as the pattern.
//(case-insensitive)
function lettersets(str, pat){
var A= [], M, tem,
rx= RegExp('\\b(['+pat+']{'+pat.length+'})\\b', 'gi'),
pattern= pat.toLowerCase().split('').sort().join('');
while((M= rx.exec(str))!= null){
tem= M[1].toLowerCase().split('').sort();
if(tem.join('')=== pattern) A.push(M[1]);
};
return A;
}
lettersets(s, 'the').sort();
function swap(a, b, str) {
if (a == b)
str = str;
else {
str = str.split("");
var temp = str[a];
str[a] = str[b];
str[b] = temp;
str = str.join("");
}
}
function anagram(a1, b1, ar) {
if (a1 == b1)
document.write(ar + "<br/>");
else
for (i = a1; i < b1; i++) {
swap(a1, b1, ar);
anagram((a1) ++, b1, ar);
swap(a1, b1, ar);
}
}
Well there isnt any built in function in js(i dont believe it to be in any coding language)......and anyways this is the fully functioning program, it omits any repetitions and also displays the number of permutations.....
var n=0;
var counter=0;
var storarr=new Array();
function swap(a,b,str) { //swaps the terms str[a] and str[b] and returns the final str
str = str.split("");
var temp = str[a];
str[a] = str[b];
str[b] = temp;
return str.join("");
}
function anagram(_a,_b,ar) { //actual function which produces the anagrams
if(_a == _b) {
storarr[n]=ar;
n++;
counter++;
}
else {
for(var i= _a;i<= _b;i++) {
ar=swap(_a,i,ar);
anagram(_a+1,_b,ar);
ar=swap(_a,i,ar);
}
}
}
function factorial(a) { //return a!
var x=1;
for(var i=1;i<=a;i++)
x=x*i;
return x;
}
var strl=prompt("Enter String:","");
var l=strl.length;
anagram(0,l-1,strl);
storarr.sort(); //sorts the storarr alphabetically
var storlen=storarr.length;
var cai=0;
var counterarr = new Array();
strl.split("");
for(var i=0;i<l;i=i+c) { //determines the number of times a term is repeating
var c=1;
for(var j=i+1;j<l;j++) {
if(strl[i]==strl[j])
c++;
}
counterarr[cai]=c;
cai++;
}
var yellow=1;
for(var i=0;i<counterarr.length;i++) { //multiplies the terms of the counter array
yellow=yellow*factorial(counterarr[i]);
}
counter=counter/yellow;
document.write("Count : " + counter + "<br />");
for(var i=0;i<storlen;i=i+yellow) { //prints the non-flagged terms in storarr
document.write(storarr[i] + "<br />");
}
strl.join("");
<pre>
<script>
var count = 0;
var duplicate = false;
function FindAllPermutations(str, index) {
for (var i = index; i < str.length; i++) {
var newstr;
if (index == i) newstr = str;
else newstr = SwapLetters(str, index, i);
if (!duplicate) {
count++;
document.write(newstr + "\n");
if (i == index) duplicate = true;
} else if (i != index) duplicate = false;
FindAllPermutations(newstr, index + 1);
}
}
function SwapLetters(str, index1, index2) {
if (index1 == index2) return str;
str = str.split("");
var temp = str[index1];
str[index1] = str[index2];
str[index2] = temp;
return str.join("");
}
FindAllPermutations("ABCD", 0); // will output all 24 permutations with no duplicates
document.write("Count: " + count);
</script>

Categories