// JavaScript Document
var person = prompt("GIVE INPUT", "");
var count = 0;
var array = person.split(",");
var freq = [];
var words = [];
//freq.fill(0);
//words.fill("");
//window.alert(freq[0]);
var i = 0, j = 0;
while (array.length > 0) {
var temp = array[0];
while (j < array.length) {
if (temp == array[j]) {
count = count + 1;
array.splice(j, 1);
//console.log(array);
j = 0;
}
else {
j = j + 1;
}
}
freq[freq.length] = count;
count = 0;
words[words.length] = temp;
}
window.alert(freq + "\n" + words);
The problem is that whenever I run it an infinite loop occurs and no output is shown, I cannot find the error please help if possible. This code is for finding the frequency of the words in a input string with words separated by commas. thank u.
You just need to put var i=0,j=0; inside the while !
while(array.length>0)
{var i=0,j=0;
Working fidddle
You're resetting your loop variable j to 0 on each iteration. This condition if(temp==array[j]) never fails so j is always reset to 0, so while(j<array.length) is always true.
After coming out of the inner While loop, you need to reset j to zero. As the incremental value of j is not allowing it to go again inside the inner loop So array.length is not reducing And we are getting an infinite loop.
// JavaScript Document
var person = prompt("GIVE INPUT", "");
var count=0;
var array = person.split(",");
var freq = new Array();
var words = new Array();
//freq.fill(0);
//words.fill("");
//window.alert(freq[0]);
var i=0,j=0;
while(array.length>0)
{
var temp=array[0];
while(j<array.length)
{
if(temp==array[j])
{
count=count+1;
array.splice(j,1);
//console.log(array);
j=0;
}
else
{
j=j+1;
}
}
freq[freq.length]=count;
count=j=0;
words[words.length]=temp;
}
window.alert(freq+"\n"+words);
It's where for is more useful for consistency. You can replace inner while loop by this for loop:
for(j=a.length-1; j>=0; j--)
if(temp==a[j]) {
count=count+1;
a.splice(j,1);
}
Nevertheless, overall complexity of your counting method can be reduced with data structure like map.
Essential part of your script can be reduced to this:
var counter = new Map();
for (i in array)
counter.set(array[i], (counter.get(array[i])||0)+1);
var freq = Array.from(counter.values());
var words = Array.from(counter.keys());
Related
I am working on permutation str using recursive, but it can not get out of the for loop.
Can anyone help for this code?
Thank you in advance.
var permutations = [];
var words = [];
function getPerms(str) {
if(str.length == 0) {
permutations.push("");
return permutations;
}
var first = str.charAt(0);//get the first char
var reminder = str.slice(1);//remove the first char
words = getPerms(reminder);
for(var i = 0; i < words.length; i++) {
for(var j = 0; j <= words[i].length; j++) {
var s = insertCharAt(words[i], first, j);
permutations.push(s);
}
}
return permutations;
}
function insertCharAt(word, c, i) {
var start = word.slice(0, i);
var end = word.slice(i);
var result = start + c + end;
return result;
}
console.log(getPerms("abc"));
Your code is fine, except for one issue:
The variables permutations should not be a global variable. You can clearly see this is wrong, by looking at permutations.push(""). This is fine as a temporary result in the deepest level of recursion, but obviously this should not be present in the final result. Yet, because permutations is global, and you never remove anything from it, permutations will keep this "".
The problem gets worse because words gets the permutations reference from the recursive call, and so they point to the very same array! So not only are all previous results iterated, but with an extra character add to them they are pushed again into permutations, which is the same array as words giving you an endless loop: you add to the array you are iterating, and so never get to the end.
The solution is simple:
Make permutations a variable local to the getPerms function. And why not do the same for words when you are at it.
function getPerms(str, depth=0) {
var words = [];
var permutations = [];
if(str.length == 0) {
permutations.push("");
return permutations;
}
var first = str.charAt(0);//get the first char
var reminder = str.slice(1);//remove the first char
words = getPerms(reminder, depth+1);
for(var i = 0; i < words.length; i++) {
for(var j = 0; j <= words[i].length; j++) {
var s = insertCharAt(words[i], first, j);
permutations.push(s);
}
}
return permutations;
}
function insertCharAt(word, c, i) {
var start = word.slice(0, i);
var end = word.slice(i);
var result = start + c + end;
return result;
}
console.log(getPerms("abc"));
Be sure to check these solutions offered for this problem.
The problem is probably at the last call you return permutations and then assign it to words (what you did here is like words = permutation), but this is not an assignement by copy, but by reference (because words and permutations belongs to the same scope + they are array), so from the last call they are the same object (and when the code unstack previous call, they are now the same object). To illustrate, execute the following code. You will see, when you modify words you modify permutations:
var permutations = [];
var words = [];
function getPerms(str) {
if(str.length == 0) {
permutations.push("");
return permutations;
}
var first = str.charAt(0);//get the first char
var reminder = str.slice(1);//remove the first char
words = getPerms(reminder);
words.push("foo");
console.log( permutations);
return permutations;
}
function insertCharAt(word, c, i) {
var start = word.slice(0, i);
var end = word.slice(i);
var result = start + c + end;
return result;
}
console.log(getPerms("abc"));
In your code, you loop on words and modify permutation in the same time (so, based on the previous explanation, it is like modifying words and loop on words in the same time), it is this things which create the infinite loop.
I did not check if your algo works, I am just pointing code's problem.
So I think what you want is:
function getPerms(str) {
var permutations = [];
var words = [];
if(str.length == 0) {
permutations.push("");
return permutations;
}
var first = str.charAt(0);//get the first char
var reminder = str.slice(1);//remove the first char
words = getPerms(reminder);
for(var i = 0; i < words.length; i++) {
for(var j = 0; j <= words[i].length; j++) {
var s = insertCharAt(words[i], first, j);
permutations.push(s);
}
}
return permutations;
}
function insertCharAt(word, c, i) {
var start = word.slice(0, i);
var end = word.slice(i);
var result = start + c + end;
return result;
}
console.log(getPerms("abc"));
It is one of the challenges in Codewars, and I am supposed to write a function that will take a string and return an array, in which I can't have two consecutive identical elements. Also, the order should not change.
For example, if I pass a string "hhhhheeeelllloooooohhheeeyyy", then the function should return an array = ["h","e","l","o","h","e","y"].
This is my code.
var uniqueInOrder=function(iterable){
//your code here - remember iterable can be a string or an array
var unique = [];
for( var i = 0; i < iterable.length; i++) {
unique.push(iterable[i]);
}
for( var j = 0, k = 1; j < unique.length; j++, k = j + 1 ){
if(unique[j] === unique[k]){
unique.splice(k,1);
}
}
return unique;
}
so, if I pass a string, such as "hhhhheeeeeellllloooo",it doesn't work as I intend it to because the value of j keeps incrementing, hence I can't filter out all the identical elements.
I tried tweaking the logic, such that whenever the unique[j] === unique[k] the value of j would become zero, and if that's not the case, then things would continue as they are supposed to do.
This got me an infinite loop.
I need your help.
The second for loop is fail because unique.length is not constant during the run.
I think your problem can be solved like this:
var temp = iterable[0];
unique.push(iterable[0]);
for( var i = 1; i < iterable.length; i++) {
if(iterable[i] != temp) {
unique.push(iterable[i]);
temp = iterable[i];
}
}
Hope it helps!
You only need to compare the current index of iterable against the last character in unique:
function(iterable){
var unique = []
for(var i=0; i< iterable.length; i++){
if(unique.length < 1){
unique.push(iterable[i])
} else if(iterable[i] !== unique[unique.length - 1]) {
unique.push(iterable[i])
}
}
return unique
}
I think this will help you:
var word="hhhhheeeelllloooooohhheeeyyy"
function doit(iterable){
var unique = []
unique[0]=iterable[0]
for(var i=1; i< iterable.length; i++){
if(iterable[i] !== unique[unique.length - 1]) {
unique.push(iterable[i])
}
}
return unique
}
alert(doit(word))
for loop will not fail because unique.length is dynamic, i.e will change with addition of new elements to array.
Tested in Internet Explorer too.
Here is the link to jsfiddle: https://jsfiddle.net/kannanore/z5gbee55/
var str = "hhhhheeeelllloooooohhheeeyyy";
var strLen = str.length;
var newStr = "";
for(var i=0; i < strLen; i++ ){
var chr$ = str.charAt(i);
//if(i==0) {newStr = chr$ };
if(chr$ == str.charAt(i+1)){
strLen = str.length;`enter code here`
}else{
newStr = newStr + chr$ ;
}
}
//document.write(newStr);
console.log(newStr);
//Answer: helohey
I must be doing something stupid. The array newArea needs to add up data from all regions, i.e. be global. Regions are represented by variable p. But when I try to get newArea array to add to itself, e.g. newArea[p] += otherArray, it outputs NaNs. Even newArea[p] += 1 outputs NaNs.
Can anyone spot what I'm doing wrong? It's driving me mad and I'm working to a deadline.
mm=0
var maxVolume = 0;
var tempCAGR = 0;
var maxCAGR = 0;
var newArray = [];
var newRegions = [];
var newConsValues = [];
var newArea = [];
for (var p=0; p<arrayRef[mm].length; p++) {//9 regions
newArray[p] = [];
for (var q=0; q<arrayRef[mm][p].length; q++) {//4 scenarios
newArea[q] = [];
if (q==0) {
newRegions.push(arrayRef[mm][p][q][0]);
newConsValues.push(arrayRef[mm][p][q][1]);
}
for (var r=0; r<dates.length; r++) {//time
//console.log('p: '+p+', q: '+q+', r: '+r);
if (p==0) {
newArea[q][r] = 1;
} else {
newArea[q][r] += 1;
}
}
arrayRef[mm][p][q].shift();
tempCAGR = Math.pow(( arrayRef[mm][p][q][len] / arrayRef[mm][p][q][1] ),(1/len))-1;
//console.log(newRegions[p]+', num: '+arrayRef[mm][p][q][len-1]+', denom: '+arrayRef[mm][p][q][0]+', len: '+len+', cagr: '+tempCAGR);
newArray[p][q] = tempCAGR;
maxCAGR = Math.max(maxCAGR,tempCAGR);
}
}
console.log(newArea);
You are cleaning the array in newArea everytime you loop through it:
...loop q ...
newArea[q] = []; // <-- resets the array at q pos
... loop r ...
if (p==0) {
newArea[q][r] = 1;
} else {
newArea[q][r] += 1;
}
So when p === 0 it will fill an array at q pos of your newArea array. However, next iteration of p will clear them out, so there's nothing there to sum.
You probably want to keep the old array or create a new one if there isn't one.
newArea[q] = newArea[q] || [];
It looks like you do not have the variable initialised. With adding something to undefined, you get NaN.
You can change the art of incrementing with a default value:
if (p == 0) {
newArea[q][r] = 1;
} else {
newArea[q][r] = (newArea[q][r] || 0) + 1;
}
So I'm trying to find how many of each number from zero to ten is generated in a random array.
I created a random array list
i=0;
var ranList=[];
while (i<20){
i++;
ranList.push(Math.floor(10*Math.random()));
}
//count each number
document.write(ranList.sort().join("<br>"));
/*Then I made a function to count /elements from this array
*/
function ctnumber(array,elem){
var ct=0;
var j =0;
while(j<array.length)
{
j++;
if(array[j]==elem){
ct+=1;}
}
}
return ct;
}
alert(ctnumber(ranList,5));
The second function doesn't execute, any idea why?
Thank you!
First you should avoid using the name array for you variable:
http://www.w3schools.com/js/js_reserved.asp
Your brackets are also wrong. Change your function to this and it should work:
function ctnumber(arr,elem){
var ct=0;
var j =0;
while(j<arr.length)
{
j++;
if(arr[j]==elem){
ct+=1;}
}
return ct;
}
The problem with your code, as stated by Pardeep in his comment, is that you have an extra } after your ct+=1; in your second while loop.
The correct code would be: Fiddle
i = 0;
var ranList = [];
while (i < 20) {
i++;
ranList.push(Math.floor(10 * Math.random()));
}
//count each number
document.write(ranList.sort().join("<br>"));
function ctnumber(array, elem) {
var ct = 0;
var j = 0;
while (j < array.length) {
j++;
if (array[j] == elem) {
ct += 1; // NOTE NO } HERE NOW
}
}
return ct;
}
alert(ctnumber(ranList, 5));
I also suggest a bit of a code cleanup:
var i = 0;
var ranList = [];
while (i < 20) {
i++;
ranList.push(Math.floor(10 * Math.random());
}
function countNumbers(list, elem) {
var count = 0;
// For loops are generally more readable for looping through existing lists
for (var i = 0; i < list.length; i++) {
if (list[i] == elem) {
count++;
}
}
return count;
}
alert(countNumber(ranList, 5));
Please note that console.log() is a much better debugging tool, it can be accessed by F12 in Firefox and Chrome/IE.
I have a numeric 2D array (an array of arrays, or a matrix) and I need to do simple matrix operations like adding a value to each row, or multiplying every value by a single number. I have little experience with math operations in JavaScript, so this may be a bone-headed code snippet. It is also very slow, and I need to use it when the number of columns is 10,000 - 30,000. By very slow I mean roughly 500 ms to process a row of 2,000 values. Bummer.
var ran2Darray = function(row, col){
var res = [];
for (var i = 0 ; i < row; i++) {
res[i] = [];
for (var j = 0; j < col; j++) {
res[i][j] = Math.random();
}
}
return res;
}
var myArray = ran2Darray(5, 100);
var offset = 2;
for (i = 0; i < myArray.length; i++) {
aRow = myArray[i];
st = Date.now();
aRow.map(function addNumber(offset) {myArray[i] + offset*i; })
end = Date.now();
document.write(end - st);
document.write("</br>");
myArray[i] = aRow;
}
I want to avoid any added libraries or frameworks, unless of course, that is my only option. Can this code be made faster, or is there another direction I can go, like passing the calculation to another language? I'm just not familiar with how people deal with this sort of problem. forEach performs roughly the same, by the way.
You don't have to rewrite array items several times. .map() returns a new array, so just assign it to the current index:
var myArray = ran2Darray(5, 100000);
var offset = 2;
var performOperation = function(value, idx) {
return value += offset * idx;
}
for (i = 0; i < myArray.length; i++) {
console.time(i);
myArray[i] = myArray[i].map(performOperation)
console.timeEnd(i);
}
It takes like ~20ms to process.
Fiddle demo (open console)
Ok, Just a little modification and a bug fix in what you have presented here.
function addNumber(offset) {myArray[i] + offset*i; }) is not good.
myArray[i] is the first dimention of a 2D array why to add something to it?
function ran2Darray (row, col) {
var res = [];
for (var i = 0 ; i < row; i++) {
res[i] = [];
for (var j = 0; j < col; j++) {
res[i][j] = Math.random();
}
}
return res;
}
var oneMillion = 1000000;
var myArray = ran2Darray(10, oneMillion);
var offset = 2;
var startTime, endTime;
for (i = 0; i < myArray.length; i++) {
startTime = Date.now();
myArray[i] = myArray[i].map(function (offset) {
return (offset + i) * offset;
});
endTime = Date.now();
document.write(endTime - startTime);
document.write("</br>");
}
try it. It's really fast
https://jsfiddle.net/itaymer/8ttvzyx7/