I have to do a binary search for a names directory in typescript, if the name is in the array the code works properly but if the name it's not in the array it became in an infinite loop.
Can somebody help me? Please!
This is the code:
var initialArray = ['Diego', 'David','Mauricio']
var sortedArray = initialArray.sort()
function search(find) {
var leftLimit = initialArray[0]
var leftLimitIndex = initialArray.indexOf(leftLimit)
var rightLimit = initialArray[initialArray.length - 1]
var rightLimitIndex = initialArray.indexOf(rightLimit)
var pivotIndex = 0
var index = -1
while (compare(leftLimit, rightLimit)) {
pivotIndex = Math.floor((leftLimitIndex + rightLimitIndex)/2)
console.log(pivotIndex)
if (initialArray[pivotIndex] == find) {
index = pivotIndex
break
}
else {
if (compare(initialArray[pivotIndex], find)) {
leftLimitIndex = pivotIndex + 1
}
else {
rightLimitIndex = pivotIndex - 1
}
}
console.log(initialArray[pivotIndex])
}
console.log("Result: "+initialArray[index])
return initialArray[index]
}
function compare(leftLimit, rightLimit) {
var r = (leftLimit < rightLimit ? -1 : 1)
if (r < 0) {
return true
}
else {
return false
}
}
Youare not taking in account the limits index which change and at the end you dont know if you have not more options to search or if the findTerm doesnt exits at all.
You only need to change the follow line
while (compare(leftLimit, rightLimit) && leftLimitIndex <= rightLimitIndex) {
Regards,
Related
Here is the code which i tried to solve, for the leetcode problem in javaScript https://leetcode.com/problems/palindrome-number/
Problem i am facing:
It is working for even number of digits in an intArr, but not for odd.
let myFunc = (num) => Number(num);
var intArr = Array.from(String(myInt), myFunc);
console.log(intArr.length);
const half = Math.ceil(intArr.length / 2);
const firstHalf = intArr.splice(0, half);
const secondHalf = intArr.splice(-half).reverse();
if (intArr.length % 2 != 0) {
firstHalf.pop();
}
console.log(firstHalf);
console.log(secondHalf);
arrayEquals(firstHalf, secondHalf);
function arrayEquals(firstHalf, secondHalf) {
if (
Array.isArray(firstHalf) &&
Array.isArray(secondHalf) &&
firstHalf.length === secondHalf.length &&
firstHalf.every((val, index) => val === secondHalf[index])
) {
console.log("true");
} else {
console.log("false");
}
}
}
isPalindrome(1221);
isPalindrome(12321);
Please let me know how can i solve this problem.
Please correct me if I was wrong in implementing this solution, Thank you.
You can check weather a number or string is a Palindrome or not by using following Function
const isPalindrome = (input) => {
const arr = (input.toString()).split('');
let isPalindromeInput = true, inputLengthMid = Math.floor(arr.length / 2);
for(let i=0, j=arr.length - 1; i <= inputLengthMid && j >= inputLengthMid; i++, j--) {
if(arr[i].toLowerCase() !== arr[j].toLowerCase()){
isPalindromeInput = false;
break;
}
}
return isPalindromeInput;
}
console.log('isPalindrome : ', isPalindrome('Neveroddoreven'));
console.log('isPalindrome : ', isPalindrome(12321));
console.log('isPalindrome : ', isPalindrome(1221));
console.log('isPalindrome : ', isPalindrome(11214211));
this maybe is not the biggest challenging problem but I've got curious about it.
I did a simple code just to get the Fibonacci value based on the user input without recursion and works just fine. Very simple code:
function fib(n) {
let fibArray = [0,1];
let count = 0;
while(fibArray.length <= n){
let previous = fibArray[count + 1];
let beforePrevious = fibArray[count];
fibArray.push(beforePrevious + previous);
count++;
}
return fibArray[n];
}
But the moment I tried to make it as a recursive function, the result is undefined, even if the value is not.
function fib(n, count = 0, fibArray = [0,1]){
if(fibArray.length - 1 === n){
return fibArray[n];
}
if (fibArray.length <= n ) {
let previous = fibArray[count + 1];
let beforePrevious = fibArray[count];
fibArray.push(beforePrevious + previous);
count++;
}
fib(n,count, fibArray);
}
Just add a return statement in the last line.
return fib(n,count, fibArray);
The code is ok, you just need to add a return:
function fib(n, count = 0, fibArray = [0,1]){
if(fibArray.length - 1 === n){
return fibArray[n];
}
if (fibArray.length <= n ) {
let previous = fibArray[count + 1];
let beforePrevious = fibArray[count];
fibArray.push(beforePrevious + previous);
count++;
}
return fib(n,count, fibArray);
}
I'm having trouble with one of my test cases and I can't figure out why. Any help would be appreciated. I tried implementing a min-heap with number types but something seems to be off. I tried to make the class as clear as possible. The expected order for a min-heap should be in ascending order when removing elements, for example: 1,2,3,4,5,6.
Min Heap Class:
class MinHeap {
constructor() {
this.heap = [];
}
getLeftChildIndex(parentIndex) { return 2 * parentIndex + 1; }
getRightChildIndex(parentIndex) { return 2 * parentIndex + 2; }
getParentIndex(childIndex) { return Math.floor((childIndex - 1) / 2); }
hasLeftChild(index) { return this.getLeftChildIndex(index) < this.heap.length; }
hasRightChild(index) { return this.getRightChildIndex(index) < this.heap.length; }
hasParent(index) { return this.getParentIndex(index) > 0 };
leftChild(index) { return this.heap[this.getLeftChildIndex(index)]; }
rightChild(index) { return this.heap[this.getRightChildIndex(index)]; }
parent(index) { return this.heap[this.getParentIndex(index)]; }
heapifyUp() {
var index = this.heap.length - 1;
while(this.hasParent(index) && this.parent(index) > this.heap[index]) {
this.swap(this.getParentIndex(index), index);
index = this.getParentIndex(index);
}
}
heapifyDown() {
var index = 0;
while(this.hasLeftChild(index)) {
var smallerChildIndex = this.getLeftChildIndex(index);
if(this.hasRightChild(index) && this.rightChild(index) < this.leftChild(index)) {
smallerChildIndex = this.getRightChildIndex(index);
}
if(this.heap[index] < this.heap[smallerChildIndex]) {
// No need to continue, we are in order
break;
}
this.swap(index, smallerChildIndex);
index = smallerChildIndex;
}
}
swap(index1, index2) {
var temp = this.heap[index1];
this.heap[index1] = this.heap[index2];
this.heap[index2] = temp;
}
peek() {
if(this.heap.length === 0) throw Error("Error: Heap underflow");
return this.heap[0];
}
getSize() {
return this.heap.length;
}
isEmpty() {
return this.heap.length === 0;
}
remove() {
if(this.heap.length === 0) throw Error("Error: Heap underflow");
var item = this.heap[0];
this.heap[0] = this.heap[this.heap.length - 1];
this.heap.pop();
this.heapifyDown();
return item;
}
add(item) {
this.heap.push(item);
this.heapifyUp();
}
}
Test Case Fail:
var heap = new MinHeap();
var list = [];
heap.add(1);
heap.add(1);
heap.add(2);
list.push(heap.remove());
heap.add(4);
list.push(heap.remove());
heap.add(3);
list.push(heap.remove());
heap.add(6);
list.push(heap.remove());
heap.add(3);
list.push(heap.remove());
heap.add(4);
list.push(heap.remove());
heap.add(5);
list.push(heap.remove());
list.push(heap.remove());
list.push(heap.remove());
console.log(list); // logs [1,1,2,3,4,3,4,5,6]
Something is wrong with my logic but can't seem to figure it out.
The problem is in the line
hasParent(index) { return this.getParentIndex(index) > 0 };
which should be
hasParent(index) { return this.getParentIndex(index) >= 0 };
or
hasParent(index) { return index > 0 };
With the broken implementation, adding 3 to the heap [4, 6] does not propagate it up properly, because index 2 is not considered to have a parent.
Bergi pointed our that, in this particular implementation, hasParent() could be simplified to an expression that's so minimal it's probably better to inline it.
For developers arriving at this question looking for a good way to program a min heap in JavaScript, I've worked on making an implementation that's as clear as possible:
class MinHeap {
constructor() {
this.data = [];
}
peak() {
return this.data[0];
}
push(value) {
this.data.push(value);
let i = this.data.length - 1;
while (i > 0) {
const parentIndex = Math.ceil((i / 2) - 1);
if (this.data[i] < this.data[parentIndex]) {
this.swap(i, parentIndex);
i = parentIndex;
} else {
break;
}
}
}
pop() {
// 1 or no remaining items is a special case
if (this.data.length < 2) {
return this.data.pop();
}
const min = this.data[0];
this.data[0] = this.data.pop();
let i = 0;
while (true) {
const [leftIndex, rightIndex] = [(i * 2) + 1, (i * 2) + 2];
const leftValue = this.data[leftIndex] ?? Infinity;
const rightValue = this.data[rightIndex] ?? Infinity;
// If both children are larger than the candidate, we're done.
if (leftValue > this.data[i] && rightValue > this.data[i]) {
break;
}
// Otherwise pick the index of the smallest value
const smallestIndex = leftValue < rightValue ? leftIndex : rightIndex;
this.swap(i, smallestIndex);
i = smallestIndex;
}
return min;
};
swap(i1, i2) {
const val1 = this.data[i1];
this.data[i1] = this.data[i2];
this.data[i2] = val1;
}
}
Usage and behavior:
const heap = new MinHeap();
heap.push(2);
heap.push(1);
heap.push(3);
heap.pop(); // 1
heap.pop(); // 2
heap.pop(); // 3
Suggestions for improvements is welcome! There is also a full explanation of the approach for people that aren't familiar with the array-backed-tree and "sink" and "float" heap algorithms.
I have ‘array magazine’ and ‘string ransomNote’. And want to access an element of the array based on an element from the string.
This is what I am trying: magazine.findIndex(ransomNote[i])
var canConstruct = function(ransomNote, magazine){
magazine = magazine.split('');
//console.log(magazine);
for(let i = 0; i < ransomNote.length; i++){
if (magazine.includes(ransomNote[i])){
element_to_erase = magazine.findIndex(ransomNote[i]);
magazine = magazine.splice(element_to_erase , 1);
//console.log(magazine);
continue;
} else {
return false;
}
}
return true;
};
console.log(canConstruct('aa', 'aab'));
findIndex takes a function as an argument, and you are passing it a string
you need to do
magazine.findIndex((magazineString) => magazineString === ransomNote[i])
Or just use indexOf as its pointed in the comments, and probably validate if that returns something other than -1 (indexOf) or undefined (findIndex) in either case.
Instead of converting the input string magazine to an array, you can use magazine.search directly -
const removeCharAt = (str = 0, pos = 0) =>
str.substr(0, pos) + str.substr(pos + 1)
const canConstruct = (ransomNote = "", magazine = "") => {
for (const char of ransomNote) {
const pos = magazine.search(char)
if (pos >= 0)
magazine = removeCharAt(magazine)
else
return false
}
return true
}
console.log(canConstruct('aa', 'aab'))
// true
console.log(canConstruct('az', 'aab'))
// false
console.log(canConstruct('stay inside', 'diet coke on sale this sunday'))
// true
There is another issue. While splice, u don't need to reassign. Splice modify the same array.
You can simplify using array.every.
var canConstruct = function (ransomNote, magazine) {
magazine = magazine.split("");
return ransomNote.split("").every((rChar) => {
const rIndex = magazine.indexOf(rChar);
if (rIndex !== -1) {
magazine.splice(rIndex, 1);
return true;
}
});
};
console.log(canConstruct("aa", "aab"));
console.log(canConstruct("az", "aab"));
I have an array of objects gAllMedicalFilesClaimantsArray with 2 properties (UserID & UserInfo)
For example:
gAllMedicalFilesClaimantsArray[0].UserID = "111";
gAllMedicalFilesClaimantsArray[0].UserInfo = "AAA-111";
gAllMedicalFilesClaimantsArray[1].UserID = "222";
gAllMedicalFilesClaimantsArray[1].UserInfo = "BDD-478333";
What is the fastest way to check whether a specific UserID exists in the array using Jquery or Javascript because gAllMedicalFilesClaimantsArray has got 8000 records?
Thanks
var match = '222';
var matches = $.grep(myArray, function(el, index) {
return (el.UserID === match);
});
You can fasten the search process by using Binary Search algorithm if the array is sorted (e.g with respect to UserId).
function binarySearch(array, userid) {
var low = 0, high = array.length - 1,
i, comparison;
while (low <= high) {
i = parseInt((low + high) / 2, 10);
if (array[i].UserId < userid) { low = i + 1; continue; };
if (array[i].UserId > userid) { high = i - 1; continue; };
return array[i];
}
return null;
};
You can find the user of which ID is 12 by using the function:
var result = binarySearch(gAllMedicalFilesClaimantsArray, 12);
Something like this, I believe:
function exists(uid) {
var k = gAllMedicalFilesClaimantsArray.length;
uid = uid.toString(); // ensure the arg is a str (this can be omitted)
while (k--) {
if (gAllMedicalFilesClaimantsArray[k].UserID === uid) {
return true;
}
}
return false;
}
Is the array sorted by the UserID? If so, it can be improved either further by using a binary search; that would change this from O(n) to O(log n). Your example suggests it is. I found a good implementation of a binary search in JavaScript on the web, here. Here is the code if the site ever dies:
function binarySearch(items, value){
var startIndex = 0,
stopIndex = items.length - 1,
middle = Math.floor((stopIndex + startIndex)/2);
while(items[middle] != value && startIndex < stopIndex){
//adjust search area
if (value < items[middle]){
stopIndex = middle - 1;
} else if (value > items[middle]){
startIndex = middle + 1;
}
//recalculate middle
middle = Math.floor((stopIndex + startIndex)/2);
}
//make sure it's the right value
return (items[middle] != value) ? -1 : middle;
}
ExistsInArray(value, array){
for(var item in array){
if(item.UserId == value){
return true;
}
}
return false;
}
You can either prototype Array object, like this:
Array.prototype.exists = function(value, prop){
var i = null;
for (i in this)
if (this[i][prop] && this[i][prop] == value)
return true;
return false;
}
gAllMedicalFilesClaimantsArray.exists('222', 'UserID');