I'm calling a function using the setTimeout() function from a recursive function, however increasing the timeout time doesn't bring any change to the speed of the execution.
I was trying to implement Mergesort, the merger() function recursively calls itself and also calls another function Merge() using SetTimeout() but no matter how large I set the timeout interval to be, the execution takes place at the same speed.
I found several previous questions on setTimeout not working, (I came across a way to multiply for loop's variable with the time interval, How can I do something like that here?) but I'm a beginner in development and react and couldn't connect them to this, I'd like to know why exactly it is happening.
This is the problem area.
function merger(l,r){
if(l>=r){
return;//returns recursively
}
var m =l+ parseInt((r-l)/2);
merger(l,m);
merger(m+1,r);
setTimeout(merge,10,l,m,r)
}
More detailed code
import { useState } from "react";
function Visualiser () {
const [array,setarray] = useState([]);
const gendivs = () => {
var nums = [];
for (let i=0; i<250; i++ ){
let x = Math.floor(Math.random()*600 + 10);
nums[i] = x;
}
setarray(nums)
}
const merge = (l,m,r) => {
setTimeout(()=>{
setarray((prev) => {
const arr = [...prev]
var n1 = m - l + 1;
var n2 = r - m;
// Create temp arrays
var L = [];
var R = [];
for (let i = 0; i < n1; i++){
L[i] = arr[l + i];
}
for (let j = 0; j < n2; j++) {
R[j] = arr[m + 1 + j];
}
// Copy data to temp arrays L[] and R[]
// Merge the temp arrays back into arr[l..r]
// Initial index of first subarray
var i = 0;
// Initial index of second subarray
var j = 0;
// Initial index of merged subarray
var k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
return arr;
})
}, 10)
}
function merger(l,r){
if(l>=r){
return;//returns recursively
}
var m =l+ parseInt((r-l)/2);
merger(l,m);
merger(m+1,r);
setTimeout(merge,10,l,m,r)
}
function mergeSort () {
let l = 0;
let r = 249;
merger(l,r);
}
const selectsort = () => {
let t = [...array]
// One by one move boundary of unsorted subarray
for (let i = 0; i < 250; i++)
{
// Find the minimum element in unsorted array
let idx = i;
for (let j = i + 1; j < 250; j++) {
if (t[j] < t[idx])
idx = j;
}
var temp1 = t[i];
t[i] = t[idx];
t[idx] = temp1
// Swap the found minimum element with the first element
setTimeout(()=> {
setarray( (prev) => {
let arr = [...prev]
const temp = arr[i]
arr[i] = arr[idx]
arr[idx] = temp
return arr
})
},i*50)
}
}
const divs = array.map((ar, index) =>{
const h = ar.toString()+ "px"
return <div key={index} style = {{backgroundColor:"turquoise", margin: "1px", height: h, width: "3px"}}></div>
})
return (
<div>
<div className="btns">
<button onClick={gendivs}> Generate Array </button>
<button onClick={selectsort}> Selection Sort</button>
<button onClick={mergeSort}> Merge Sort</button>
</div>
<div className="d"> {divs} </div>
</div>
);
}
export default Visualiser;
Related
I want to delay this bubble sort algorithm. I am using reacts useState inside. after each swap I want the func to be delayed. how can you do this?
const sortDivs = () => {
var newArr = [...randomHeights]
for (let i = 0; i < newArr.length; i++) {
for (let j = 0; j < newArr.length - i; j++) {
if(newArr[j].height > newArr[j+1]?.height) {
let tmp = newArr[j];
newArr[j] = newArr[j + 1]
newArr[j + 1] = tmp;
setRandomHeights(newArr)
}
}
}
}
read about ' setTimeout ' it would be helpful.
setTimeout
Merge Function for two arrays, The function is not working properly and doesn't give the required answer. I want that the sorted arrays are merged up as it is the function saying, but it doesn't work.
var Merge = function(array,array1,array2)
{
var n_array = array.length;
var n_array1 = array1.length;
var i = j = k = 0;
while(i < n_array && j < n_array1)
{
if(array[i] <= array2[j])
{
array2[k] = array[i];
i = i + 1;
}
else
{
array2[k] = array1[j];
j = j + 1;
}
k = k + 1;
}
while(i < n_array)
{
array2[k] = array[i];
i = i + 1;
k = k + 1;
}
while(j < n_array1)
{
array2[k] = array1[j];
j = j + 1;
k = k + 1;
}
return array2;
};
array = [1,3,5,7];
array1 = [2,4,6,8];
array2 = [];
var result = Merge(array,array1,array2);
console.log("The array is sorted is " + result);
Why my code give an answer:
The array is sorted is 2,4,6,8,1,3,5,7
var Merge = function(array,array1,array2)
{
var n_array = array.length;
var n_array1 = array1.length;
var i = j = k = 0;
while(i < n_array && j < n_array1)
{
if(array[i] <= array1[j])
{
array2[k] = array[i];
i = i + 1;
}
else
{
array2[k] = array1[j];
j = j + 1;
}
k = k + 1;
}
while(i < n_array)
{
array2[k] = array[i];
i = i + 1;
k = k + 1;
}
while(j < n_array1)
{
array2[k] = array1[j];
j = j + 1;
k = k + 1;
}
return array2;
};
array = [1,3,5,7];
array1 = [2,4,6,8];
array2 = [];
var result = Merge(array,array1,array2);
console.log("The array is sorted is " + result);
It Works :)
This is the edited solution to the OP's problem.
While the fix for your code is mentioned above, that is a lot of lines for just doing a merge and sort. If you know you will be dealing with numbers you could use the following:
var arr = [1, 10, 22];
var arr1 = [20, 17, 3];
var arr2 = arr.concat(arr1);
sortAsc(arr2);
function sortAsc(arrayToSort){
return arrayToSort.sort(function(a, b){
return a - b;
});
}
ArrayList1 = [a,b,c,d]
ArrayList1 = [d,c,e,f,g]
I would like to have result as
ArrayListFinal = [c,d]
How can I accomplish this?
try this...........
for(int i =0;i<list1.size();i++){
for(int j=0;j<list2.size();j++){
if(list.get(j).equals(list2.get(i))){
listfinal.add(list.get(i));
}
}
}
for(int i=0;i<listfinal.size();i++){
System.out.println(list1.get(i));
}
Your problem is to find the intersection (denoted as ∩) of two array A and B .
Suppose the arrays are unsorted. The simplest way is to compare the elements one by one, like this:
function getIntersect(arr1, arr2) {
var temp = [];
for(var i = 0; i < arr1.length; i++){
for(var k = 0; k < arr2.length; k++){
if(arr1[i] == arr2[k]){
temp.push( arr1[i]);
break;
}
}
}
return temp;
}
But if the arr2 is much shorter than arr1, you may using a hash table to speed up:
function getIntersect(arr1, arr2) {
var r = [], o = {}, l = arr2.length, i, v;
for (i = 0; i < l; i++) {
o[arr2[i]] = true;
}
l = arr1.length;
for (i = 0; i < l; i++) {
v = arr1[i];
if (v in o) {
r.push(v);
}
}
return r;
}
I have an array:
var exArr:Array = [5,6,10,6,5,11,7,9,12,8,8,13,7,9,14];
I want to array:
var resultArr:Array = [5,6,7,8,9,10,11,12,13,14];
This may use full to you.
var a:Array = [5,6,10,6,5,11,7,9,12,8,8,13,7,9,14];
a.sort();
var i:int = 0;
while(i < a.length) {
while(i < a.length+1 && a[i] == a[i+1]) {
a.splice(i, 1);
}
i++;
}
for other, see here
Try this:
var exArr:Array = [5,6,10,6,5,11,7,9,12,8,8,13,7,9,14];
function group(subject:Array):Array
{
var base:Array = subject.slice().sort(Array.NUMERIC);
var prev:Number = base[0];
for(var i:int = 1; i < base.length; i++)
{
if(base[i] === prev)
{
base.splice(i, 1);
i--;
}
prev = base[i];
}
return base;
}
trace( group(exArr) );
I'm wondering which is faster in AS3:
array.forEach( function(v:Object, ...args):void
{ ... } );
Or
var l:int = array.length;
for ( var i:int = 0; i < l; i++ ) { ... }
for i :)
var array:Array = [];
for (var i:int=0; i < 100000; i++)
{
array[i] = i;
}
var time:uint = getTimer();
array.forEach( function(v:Object, ...args):void
{ v = 1; } );
trace(getTimer()-time); //trace 85
time = getTimer();
var l:int = array.length;
for ( i = 0; i < l; i++ ) { array[i] = 0; }
trace(getTimer()-time); //trace 3
The above answers do not take into account that you mostly will be performing operations on the array elements in the loop
This code
import flash.utils.getTimer;
var a:Array=[];
var time:int=0;
for(var i:int=0; i<10000; i++) {
a.push(new Date());
}
time=getTimer();
for(var j:int=0; j<a.length; j++) {
var dt:Date=a[j];
dt.valueOf();
}
trace("for: " , getTimer()-time);
time=getTimer();
for each(var xt:Date in a) {
xt.valueOf();
}
trace("for each: " , getTimer()-time);
time=getTimer();
a.forEach(nothing);
trace("a.forEach: " , getTimer()-time);
function nothing(d:Date, ...args):void {
d.valueOf();
}
Returns the following:
for: 3
for each: 2
a.forEach: 13
For 100000 values, the results are starker still
for: 27
for each: 17
a.forEach: 138
Overall winner: the for each loop
for each(var d:myClass in myCollection) {
//myCode
}
For VS Foreach on Array performance (in AS3/Flex)
hope this will help you in understanding the difference between for and for-each loop.
var time:uint;
var vec:Vector.<Number> = new Vector.<Number>;
for (var b:int=0; b < 1000000; b++)
{
vec[b] = 99;
}
///
time = getTimer();
for (var i:int = 0; i < vec.length; i++ )
{
vec[i] = 2;
}
trace('for i: '+(getTimer()-time)+'ms');
///
time = getTimer();
for (var j:int = vec.length - 1; j >= 0; --j)
{
vec[j] = 3;
}
trace('for i rev: '+(getTimer()-time)+'ms');
///
time = getTimer();
for ( var k:int in vec)
{
vec[k] = 4;
}
trace('for: '+(getTimer()-time)+'ms');
///
time = getTimer();
for each(var o:Number in vec)
{
o = 5;
}
trace('for each: '+(getTimer()-time)+'ms');
///
time = getTimer();
vec.forEach( function(v:int, ...args):void
{
v = 6;
}
);
trace('forEach: '+(getTimer()-time)+'ms');
// for i: 81ms
// for i rev: 79ms
// for: 28ms
// for each: 33ms
// forEach: 530ms