I'm trying to do a little program to reverse a string and I'm using this approch:
var reverse = (str) => {
let returned = [...str];
for(let i = 0; i < returned.length; i++)
{
let symetrical = returned.length - i - 1;
let temp = returned[i];
returned[i] = returned[symetrical];
returned[symetrical] = temp;
}
return returned.join("");
}
but when i test the function like reverse('123') I got the same input as result?
why the returned variable didn't change?
You can simplify the function by creating two arrays, the array of the letters of the param str, and the results array which takes the length - 1 - i algorithm you had:
let reverse = (str) => {
const arr1 = [...str];
const arr2 = []
for(let i = 0; i < arr1.length; i++)
{
arr2[i] = arr1[arr1.length - 1 - i];
}
return arr2.join("");
}
console.log(reverse("abcde"));
Related
My apologies if this is a duplicate, I couldn't find an answer after searching for a while on Stackoverflow.
I am trying to use a nested loop to find any duplicate characters in a string.
So far, all I can manage to do is to find one duplicate the string.
For example, when I try the string "aabbcde", the function returns ['a', 'a'], whereas I was expecting ['a', 'a', 'b', 'b'].
I obviously have an error in my code, can anybody help point me towards what it could be?
const myStr = "aabbcde";
function duplicateCount(text){
const duplicates = [];
for (let i = 0; i < text.length; i++) {
for (let j = 0; j < text[i].length; j++) {
if (text[i] === text[j]) {
duplicates.push(text[i]);
}
}
}
return duplicates;
}
duplicateCount(myStr);
It should be something like this.
issues in this loop for (let j = 0; j < text[i].length; j++)
const myStr = "aabbcde";
function duplicateCount(text){
const duplicates = [];
for (let i = 0; i < text.length; i++) {
for (let j = i+1; j < text.length; j++) {
if (text[i] === text[j]) {
duplicates.push(text[i]);
}
}
}
return duplicates;
}
console.log(duplicateCount(myStr));
Using nested loop will make it very hard to do it,we can use a Object to store the appear count,and then filter the count
const myStr1 = "aabbcde";
const myStr2 = "ffeddbaa";
const duplicateCount = str => {
let map = {}
for(c of str){
map[c] = (map[c]??0) + 1
}
let result = []
for(m in map){
if(map[m] <= 1){
continue
}
result.push(...Array(map[m]).fill(m))
}
return result
}
console.log(duplicateCount(myStr1))
console.log(duplicateCount(myStr2))
You can simply achieve the result you're looking for by creating an object map of the string (meaning each key of the object will be each unique character of the string and their associated values will be the number of times each character is repeated in the string).
After you create an object map of the string, you can loop through the object and check if each value is greater than one or not. If they're you would push that item into a result array by the number of times the character is repeated. Please find my code here:
const myStr = 'aabbcde';
const duplicateCount = (str) => {
const result = [];
const obj = {};
str.split('').map((char) => {
obj[char] = obj[char] + 1 || 1;
});
for (key in obj) {
if (obj[key] > 1) {
for (let i = 0; i < obj[key]; i++) {
result.push(key);
}
}
}
return result;
};
console.log(duplicateCount(myStr));
/**
* Let us create a function that receives a string "abcbdbd",
* and returns an array like:
["a", "a.b", "a.b.c", "a.b.c.b", "a.b.c.b.d", "a.b.c.b.d.b", ...]
*/
function splitString(str) {
const arr = [];
for (var i = 0; i < str.length; i++) {
arr.push(str[i]);
for (var z = 0; z < arr.length; z++) {
const joinArr = `${arr[0]}.${arr[z]}`;
console.log(joinArr);
}
}
return [];
}
console.log(splitString("abcdebfkjj"));
how to add . after every string? I have tried for loop. So should I use map and .join?
An example using map
const str = "abcbdef";
const array = str.split("");
const output = array.map((_, idx, arr) => arr.slice(0, idx + 1).join("."));
console.log(output);
Create an array from the string (Array.from()), reduce it to an array, so that each element is the current last element (acc[acc.length-1]) in the array plus itself. For the first element just add it to the array.
function splitString(str) {
return Array.from(str).reduce((acc,cv) => {
if (acc[0]) acc.push(acc[acc.length-1]+"."+cv)
else acc[0] = cv // if the array is empty, add just the first char
return acc
},[])
}
console.log(splitString("abcdebfkjj"));
You could create an array of all characters and add the last returned value.
function splitString(str) {
return Array.from(
str,
(l => v => l += (l && '.') + v)('')
);
}
console.log(splitString("abcdebfkjj"));
function splitString(str) {
let arr = [];
let temp = "";
for (let i = 0; i < str.length; i++) {
temp += (temp !== "" ? "." : "") + str[i];
arr.push(temp);
}
return arr;
}
console.log(splitString("abcbdbd"));
Given two strings s1 and s2 consisting of lowercase English alphabets, the task is to count all the pairs of indices (i, j) from the given strings such that s1[i] = s2[j] and all the indices are distinct i.e. if s1[i] pairs with some s2[j] then these two characters will not be paired with any other character.
Input: s1 = 'abcd', s2 = 'aad'
Output: 2
Input: s1 = 'geeksforgeeks', s2 = 'platformforgeeks'
Output: 8
I tried to like this:
function getSameCount(str, str2) {
var o = {},
o2 = {};
for (var i = 0; i < str.length - 1; i++) {
if (str[i] in o) {
o[str[i]] = parseInt(o[str[i]] + 1)
} else {
o[str[i]] = 0
}
}
console.log(o);
for (var i = 0; i < str2.length - 1; i++) {
if (str[i] in o2) {
o2[str[i]] = parseInt(o2[str[i]] + 1)
} else {
o2[str[i]] = 0
}
}
console.log(o2);
}
getSameCount('abcd', 'aad')
Use for..in loop and includes method
var s1 = "abcd";
var s2 = "aad";
function match(s1, s2) {
var count = 0;
for(let i in s1) {
s2.includes(s1[i]) ? count++ : false;
}
return count;
}
console.log(match(s1,s2));
We can convert the second input string to an array, then the next step is to iterate over the first input string and find a match in the second input string's character array.
If a match is found, increment the counter and remove that character from the second input string's character array so that it is not considered in the next match:
//Solution:
function getSameCount(str1, str2) {
let count = 0;
const obj = str2.split("");
for(str of str1){
let idx = obj.findIndex(s => s === str);
if(idx >= 0){
count++;
obj.splice(idx, 1);
}
}
return count;
}
//Test:
console.log(getSameCount("abcd", "aad"));
console.log(getSameCount("geeksforgeeks", "platformforgeeks"));
console.log(getSameCount("aad", "abcd"));
console.log(getSameCount("platformforgeeks", "geeksforgeeks"));
You can create a custom method on the array and find the number of characters which are common in all the words. Below steps are list of procedure to find the common characters in all the string
Create a prototype method on Array , findCommonWord in this case.
This method accepts an array of string, so input will be like
[ "abcd", "aad","geeksforgeeksda","platdformforgeeks"].findCommonWord()
First step is to modify the input, to remove duplicate characters from a string using Set then sort it by ascending order of the length of string. This is because number of loop will be least if we have to find common character , that also have to present in string with least length.
Then create a new array with out the first string and split the first string. split will create a new array and iterate over it and check if this character is present in rest of the string.
var s1 = "abcd",
s2 = "aad",
s3 = "geeksforgeeksda",
s4 = "platdformforgeeks";
Array.prototype.findCommonWord = function() {
let tempArray = this.map(function(item) {
return [...new Set(item.split(''))].join('');
}).sort(function(a, b) {
return a.length - b.length
})
let count = 0;
let firstElm = tempArray[0].split('');
let restElem = tempArray.splice(1);
let countObject = {}
for (let i = 0; i < firstElm.length; i++) {
let z = findIfIncludes(restElem, firstElm[i]);
if (z.length === restElem.length) {
countObject[firstElm[i]] = 1;
} else {
countObject[firstElm[i]] = 0
}
}
function findIfIncludes(arr, char) {
return arr.filter(item => item.includes(char))
}
console.log(countObject)
let totalCount = 0;
for (let keys in countObject) {
if (countObject[keys] > 0) {
totalCount += 1;
}
}
return totalCount;
};
console.log([s1, s2, s3, s4].findCommonWord());
function numberOfSameChars(s1, s2) {
let obj = {};
let counter = 0;
for (let i=0; i<s1.length; i++){
if(s1[i] in obj) {
obj[s1[i]]++;
} else {
obj[s1[i]] = 1;
}
}
for (let i=0; i<s2.length; i++) {
if(s2[i] in obj && obj[s2[i]] > 0) {
obj[s2[i]]--;
counter++;
}
}
return counter;
}
Try this code:
function countMatch(s1,s2){
var count = 0;
while(s1.length && s2.length){
if(s2.includes(s1.charAt(0))){
count++;
s2 = s2.replace(s1.charAt(0),"");
s1 = s1.slice(1);
}
else {
s1 = s1.slice(1);
}
}
return count;
}
console.log(countMatch("abcd","aad"));
//2
I used objects to do this, and I was kind of curious about there being another way, as I wanted to take an algorithmic approach as well, but whatever works works.
Anyways, here's the code:
function commonCharacterCount(s1, s2) {
let string1Counter = {};
let string2Counter = {};
let commonCount = 0;
for(let i = 0; i < s1.length; i++){
if(!string1Counter.hasOwnProperty(s1[i])){
string1Counter[s1[i]] = 0;
}
string1Counter[s1[i]]++;
}
for(let i = 0; i < s2.length; i++){
if(!string2Counter.hasOwnProperty(s2[i])){
string2Counter[s2[i]] = 0;
}
string2Counter[s2[i]]++;
}
for(let key in string1Counter){
if(string2Counter.hasOwnProperty(key)){
if(string1Counter[key] < string2Counter[key]){
commonCount += string1Counter[key];
}
else{
commonCount += string2Counter[key];
}
}
}
return commonCount;
}
The logic is basically to just save all of the characters of each string and their count,check for similarities, and compare the count of common characters. Whichever has the fewer amount of common characters will be the amount shared by both.
O(3N) time complexity, O(2N) space complexity (because of the stored objects).
I guess I can also do "delete object" but seems redundant on just an algorithm IDE because it's not like it's running on a server for any extended period of time.
function commonSameCount(s1, s2) {
var s1Array = s1.split("");
var s2Array = s2.split("");
var count = 0;
let index = 0;
s1Array.filter(s1 => {
index = s2Array.findIndex(s2 => s2 == s1);
if(index >= 0){
count++;
s2Array.splice(index, 1);
}
});
return count;
}
A simple solution using Regex:
index.js
function getSameCount(s1,s2) {
for (let i in s2) {
s1 = s1.replace(s2[i], "1")
}
const result = s1.replace(/[^1]/g, '').length
return result
}
I'm working on the Quicksort2 problem on HackerRank. I can't figure out how it wants me to output the solution.
I've tried to console.log the sorted arrays as they're created, an array of the sorted arrays and an array of the arrays converted to strings. Returning from the processData function seems to do nothing.
function checkSort(arr) {
for (let i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) return false;
}
return true;
}
function processData(input) {
let sortedArrays = [];
quickSort(input);
function quickSort(input) {
if (input.length <= 1) return input;
let pivot = [input[0]];
let left = [], right = [];
for (let i = 1; i < input.length; i++) {
input[i] < pivot ? left.push(input[i]) : right.push(input[i]);
}
let newArr = quickSort(left).concat(pivot, quickSort(right));
if (checkSort(newArr)) sortedArrays.push(newArr);
return newArr;
}
console.log(sortedArrays);
}
I'm expecting it to match HackerRank's desired output.
There're a couple of issues with your implementation:
Below is a quote from the task description:
In this challenge, print your array every time your partitioning method finishes, i.e. whenever two subarrays, along with the pivot, are merged together.
However, you're trying to print the final sorted array sortedArrays rather than a subarray for each step as the problem states. So, print the subarray newArr before returning it. Don't forget to format the output using join.
Another quote:
There will be two lines of input:
the size of the array
the n numbers of the array
Your processData expects a parsed input aka an array that it can work with. If it receives the raw input (2 lines of data) then they should be parsed accordingly. for instance, they could be parsed as below:
...
function processData(input) {
var lines = input.split('\n')
var len = lines[0]
var arr = lines[1].split(' ');
...
And so your fixed code could look as follows:
function processData(input) {
var lines = input.split('\n')
var len = lines[0]
var arr = lines[1].split(' ');
quickSort(arr);
function quickSort(input) {
if (input.length <= 1) return input;
let pivot = [input[0]];
let left = [], right = [];
for (let i = 1; i < input.length; i++) {
input[i] < pivot ? left.push(input[i]) : right.push(input[i]);
}
let newArr = quickSort(left).concat(pivot, quickSort(right));
// print the subarray once the partitioning for this step has finished
console.log(newArr.join(' '))
return newArr;
}
}
I am trying to sort an array of strings based on a character inside each of those strings. So far, I have this
function doMath(s) {
let arr = s.split(' ');
let letterArr = [];
let sortedArr = [];
let n = 0;
for (var i = 0; i < arr.length; i++) {
n = arr[i].indexOf(arr[i].match(/[a-z]/i));
letterArr.push(arr[i][n]);
}
letterArr.sort();
console.log(letterArr);
for (i = 0; i < arr.length; i++) {
for (var j = 0; j <= arr[i].length; j++) {
if (arr[i].indexOf(letterArr[j]) > -1) {
sortedArr.unshift(arr[i]);
}
}
}
console.log(sortedArr);
}
doMath("24z6 1x23 y369 89a 900b");
The problem is shown when I log this array. If I use sortedArr.push(arr[i]);,
then the output is:
["24z6", "1x23", "y369", "89a", "900b"]
However, when I use sortedArr.unshift(arr[i]);, I get the output:
["900b", "89a", "y369", "1x23", "24z6"]
I am not sure why the b comes before the a.
I just want it to be a-z for the sorting. I tried push() and it is correct but backwards (z-a). When I try unshift(), it's correct except the b and a are switched.
function doMath(s) {
return s.split(' ').sort(function (a,b) {
return a.match(/[a-z]/i)[0].localeCompare(b.match(/[a-z]/i)[0])})
}
console.log(doMath("24z6 1x23 y369 89a 900b"));