String permutation from Java to Javascript - javascript

I am new to Javascript and I was trying to reproduce a Java string permutation using Javascript but I cannot get the correct result.
Note: I followed this algorithm here (Hemant's answer): String permutation with recursion
Here is my code:
function getAllPermutations(input){
var permutations = [];
function loop(prefix, input){
var len = input.length;
if(len==0) {
permutations.push(prefix);
}
else{
for(i = 0; i < len; i++){
loop(prefix + input.charAt(i),input.substr(0,i) + input.substr(i+1,len));
}
}
}
loop("", input);
return permutations;
}
When I call getAllPermutations("good"), it's only returning ["good"]. What's going on with this code? Am I missing anything about the call back scope?

The problem is that the variable i in the for loop is defined globally. Therefore in each recursion the variable retains the value of the former iteration.
It can be fixed by writing var in front of the variable to make it a local variable like in the following code snippet.
for(var i = 0; i < len; i++){
// ...
}

Related

What happens if you put an iteration count of a for loop as a variable?

I want to make a program in javascript in which a person inputted the iteration count for a for loop(they could input x++, or y--), but I don't know if I am using the right method.
Here is my code:
var x = prompt("iteration count")
// x should equal something like, i++, or x--
for(var i = 0; i < 10; x){
document.write(i)
}
But when the code ran the program kept crashing.
Why is it crashing and how do I fix this?
Please Help
you need to parse the int value of x because it's a string and use it to increment i
var x = parseInt(prompt("iteration count"))
for (var i = 0; i < 10; i += x) {
document.write(i)
}
EDIT :
based on the question edit and the comments, you can use eval(), but :
Do not ever use eval!
eval() is a dangerous function, which executes the code it's passed with the privileges of the caller.
So before you use it, read the MDN page and check : eval isnt evil it's just misunderstood
where there's this comment from Spudley :
From a security perspective, eval() is far more dangerous in a server
environment, where code is expected to be fully trusted and hidden
from the end user.
In a browser, the user could eval any code they wanted at any time
simply by opening dev tools, so as a developer you can't get away with
having anything on your client code that could be insecure against
eval anyway.
to test the snippet below, type i++ in the prompt
var x = prompt("iteration count");
for (var i = 0; i < 10; eval(x)) {
console.log(i)
}
an alternative to eval() would be new Function or check the answers here : Programatically setting third statement of for loop
var input = 'i++';//Or whatever condition user passing in
var conditionProgramatically = () => new Function(input)() ;
for (var i = 0; i < 10; conditionProgramatically()) {
console.log(i)
}
For for-loop, third statement will be invoked/executed on every iteration, and hence we set a function call, and in that function, we execute whatever user passing in as you've mentioned i++
That is an endless loop because the variable i never incremented. Try this one.
var x = prompt("iteration count")
for(var i = 0; i < x, i++){
document.write(i)
}
You forgot to increment the index variable, it result to endless loop and maximum stack error, you can also use + for parseInt shorcut.
var x = +prompt("iteration count")
for(var i = 0; i < x;i++){
document.write(i)
}
You have to parse the input value and then make it as a condition to stop iterating after the given value.
var x = parseInt(prompt("iteration count"))
for (var i = 0; i < x; i++) {
document.write(i);
}

How to count vowels in a Javascript string with two functions?

I'm trying to write a Javascript function that counts the vowels in a string by calling another function inside that function, but when I test it in the console it returns 0.
Here is my first function that works fine and recognizes if a string is a vowel:
function isVowel(ch){
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
};
For the second function none of my ideas have worked. Here are a few examples of what I have tried so far:
This one returns me a 0:
function countVowels(str){
var count = 0;
for(var i; i <= str.length; ++i){
if(isVowel(i)){
++count;
}
}
return count;
};
I also tried the above, but removing the .length after str in the for() area.
Another example, but this one gives me an error:
function countVowels(str){
var count = 0
var pattern = /[aeiouAEIOU]/
for(var i = 1; i <= str.length(pattern); ++i){
if(isVowel(i)){
++count;
}
}
return count;
};
I've tried various other functions as well, but for the sake of keeping this post relatively short I won't continue to post them. I'm quite new to Javascript and I'm not sure what I'm doing wrong. Any help would be greatly appreciated!
Try using .match() with the g attribute on your String.
g: global
i: case insensitive
Regexp documentation
function countVowels(ch){
return ch.match(/[aeiouy]/gi).length;
}
var str = "My string";
alert(countVowels(str)); // 2
Although Robiseb answer is the way to go, I want to let you know why you code is not working (I'm referring your first attempt). Basically you made two mistakes in the loop:
As CBroe stated, you are passing i to your isVowel function. i is a integer representing the index of the loop, not the actual character inside the string. To get the character you can do str.substr(i, 1), what means "give me one character from the position i inside the string".
You are not giving a initial value to the i variable. When you create a variable, it is undefined, so you can not increment it.
alert(countVowels("hello"));
function countVowels(str) {
var count = 0;
for (var i = 0; i <= str.length; ++i) {
if (isVowel(str.substr(i, 1))) {
count++;
}
}
return count;
};
function isVowel(ch) {
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
};
UPDATE: You will see that other answers use other methods to select the character inside the string from the index. You actually have a bunch of different options. Just for reference:
str.slice(i,i+1);
str.substring(i,i+1);
str.substr(i,1));
str.charAt(i);
str[i];
i is the index, not the character. It should be:
if (isVowel(str[i])) {
count++;
}
Also, str.length(pattern) is wrong. length is a property, not a function, so it should just be str.length.
You forgot to assign the value 0 to i variable
And parameter for isVowel is the character, not the index of string
Here information about the JS language: https://stackoverflow.com/tags/javascript/info
function isVowel(ch){
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
}
function countVowels(str){
var count = 0;
// you forgot to assign the value to i variable
for(var i = 0; i < str.length; i++){
// isVowel(str[i]), not isVowel(i)
if(isVowel(str[i])){
count++;
}
}
return count;
}
console.log(countVowels('forgot'))
Obviously you should do it this way:
function isVowel(c){
var lc = c.toLowerCase();
if(lc === 'y'){
return (Math.floor(Math.random() * 2) == 0);
}
return ['a','e','i','o','u'].indexOf(lc) > -1;
}
function countVowels(s){
var i = 0;
s.split('').each(function(c){
if(isVowel(c)){
i++;
}
});
return i;
}
console.log(countVowels("the quick brown fox jumps over the lazy dog"));
Which, although less efficient and less useful than other answers, at least has the entertaining property of returning a different count 50% of the time, because sometimes Y.

How to pass an array with a key to the argument of a function? (Working with multi-dimensional arrays)

This may not be a good question, but it does makes sense(atleast to me, it does.)
Suppose I have a multi-dimensional array called temporaryFrequency. Now, I want to write a function which will take one argument --> frequencyArray[number]. This will be more clear from the code:
JS:
function getMaxTemporaryFrequency(frequencyArray[number]){
var maxOutofThese = frequencyArray[number][0];
for(var i = 0; i < frequencyArray[number].length; i++){
if(frequencyArray[number][i] > maxOutofThese)
maxOutofThese = frequencyArray[number][i];
}
return maxOutofThese;
}
This is the function which will return the maximum frequency from a sub-array of an array. Now, I will execute the following code to call the function:
//This is to get the max out of the temporary frequencies
for(var n = 0; n < temporaryFrequency.length; n++){
var maximumTempFrequency + (n + 1) = getMaxTemporaryFrequency(temporaryFrequency[n]);
}
Now, I have one more question attached to this. Can variable names be concatenated, like a did here? For example, for each loop count, I want to make variables : maximumTempFrequency1 , maximumTempFrequency2 , maximumTempFrequency3 and so on.
Now, this call of the function passes the nth element of the temporaryFrequency array to the function, which should return the greatest value from that nth sub-array. But, that is not working.
So, to summarise my question:
1) Can we pass an array with a key to function, like I did here? If
no, is there any way to do it?
2) Can we concatenate strings to make a variable name, like I did in
the 'for' loop? If no, is there any other method
*NOTE: For this question, viewers don't need to know the contents of the temporaryFrequency array.
The straight answer to your two questions are No.
The syntax function getMaxTemporaryFrequency(frequencyArray[number]) { ... } is not valid. The parser is expecting an identifier for the parameter name, and identifiers can't have brackets in them [ or ]. This results in the error:
Uncaught SyntaxError: Unexpected token [
Similarly, your variable name is also syntactically invalid. var maximumTempFrequency + (n + 1) = //anything results in
Uncaught SyntaxError: Unexpected token +
To answer your follow up questions of How to make it work, for the first question you can pass the dereferenced array member to the function when you call it (instead of when you declare it).
var frequencyArray = []; // fill it with your values
var number = 0; // or whatever number you want
function getMaxTemporaryFrequency(arr){
var maxOutofThese = arr[0];
for(var i = 0; i < arr.length; i++){
if(arr[i] > maxOutofThese)
maxOutofThese = arr[i];
}
return maxOutofThese;
}
function getMaxTemporaryFrequency(frequencyArray[number]);
For the latter one, you want to store the results to an array, like this:
//This is to get the max out of the temporary frequencies
var maximumTempFrequency = [];
for(var n = 0; n < temporaryFrequency.length; n++){
maximumTempFrequency[n+1] = getMaxTemporaryFrequency(temporaryFrequency[n]);
}
Note that your syntax getMaxTemporaryFrequency(temporaryFrequency[n]) is an example of what I put in the first code block above.

explanation on javascript variables inside a function

I am learning javascript and came across a topic which mentions that the variables declared inside a function is available anywhere inside the function and javascript puts the variable definition at the top like in the below example:
var functionScope=function(){
for (var i=0; i< 10; i++){//code inside this loop}
return i;
}
console.log(functionScope()); //prints 10
The javascript actually turns the above function to the below:
var functionScope=function(){
var i;
for ( i=0; i< 10; i++){//code inside the for loop}
return i;
}
console.log(functionScope()); //prints 10
Since javascript is interpreted language, it executes line by line. How will it know that it should pull the variable to the top of the function after it has tried accessing the variable. When it tries to access the variable it should tell as undefined right?
Also if I go by the theory that the variables will be placed at the top of the function and can be accessed anywhere then the below code should print 10, but why the below code prints undefined?
var functionScope=function(){
console.log('The value os i is '+i);
var i = 20;
}
console.log(functionScope());
Could someone explain where my understanding is wrong?
One more doubt: Typically in Java, if I had to print the value of i outside the for loop, i would get an error, but in javascript does the variable still accessible outside outside the for loop as in case of fist example where the variable is defined inline inside the for loop. Am i missing something here?
var functionScope=function(){
for (var i=0; i< 10; i++);
return i
}
console.log(functionScope()); //prints 10
This is only a bad indentation. Because of the ; at the end of for, it doesn't includes the return i statement into the loop.
There is the well indented one to help you understand what really happens:
var functionScope=function() {
for (var i=0; i< 10; i++)
/* do nothing */;
return i
}
With var, you tell the JS that the variable is not global, and it'll be aviable only inside the function.
With =, you can set the variable's value.
var i; for (i = 0; ... and for (var i = 0; ... is the same.
In the third example, you don't have i inside the function. In this case, the JS'll try to find it as a global variable, outside the function. If you've set window.i = 1, it'll print The value os i is 1, otherwise it'll generate an error, because i is not defined nowhere.
var i = 0;
var fn = function() {
i = 1; //window.i = 1;
};
console.log(i); //prints 1
var i = 0;
var fn = function() {
var i = 1; //fn.i = 1;
}
console.log(i); //prints 0
var fn = function() {
var i = 1; //fn.i = 1;
}
console.log(i); //ReferenceError: i is not defined
var i;
var fn = function() {
var i = 1; //fn.i = 1;
}
console.log(i) //prints undefined
As Sebastien C. has already told you, your example code dosn't do what you want it to do. for (var i=0; i< 10; i++); means for (var i=0; i< 10; i++) {/*do nothing*/}. If you remove the ;, you'll notece your function will return 0, because the return keyword stops the function, and it return the value, no other operations will be executed, your loop will run only once.
Also, you should use ++i.
Yes Javascript is interpreted and whenever is finds a var declared/undeclared, it declares it and then performs the operations or in technical terms it does var hoisting. So now the variable is declared, but is undefined.
So any operation done on it (other than assignment) will result in its value being undefined only. eg;
{
x++ ;
var x = 10 ;
console.log(x);
}
will print 10. So you can think of it as
{
var x = undefined; \\variable hoisted at beginning of block
x++ ;
x = 10 ;
console.log( x ); \\ x = 10
}

javascript return all combination of a number

I am trying to get all combination of a number. For example, input "123" should return ["123", "231", "213", "312", "321", "132"].
Here is my function:
function swapDigits(input) {
for (var i = 0; i++; i < input.length - 1) {
var output = [];
var inter = input.slice(i, i + 1);
var left = (input.slice(0, i) + input.slice(i + 1, input)).split("");
for (var j = 0; j++; j <= left.length) {
var result = left.splice(j, 0, inter).join("");
output.push(result);
}
}
console.log(output);
return output;
}
However this function returns undefined, could anyone tell me what's going wrong?
The errors with the for loop and scope have already been mentioned. Besides that, the splice method will change the string that it operates on. This means that the inner loop will never terminate because left keeps on growing, so j never reaches left.length.
If you are new to a language, I would suggest starting with an implementation that is close to the algorithm that you want to implement. Then, once you are comfortable with it, use more advanced language constructs.
See this fiddle for an example. This is the algorithm code:
function getPermutations(input)
{
if(input.length <= 1)
{
return [input];
}
var character = input[0];
var returnArray = [];
var subPermutes = getPermutations(input.slice(1));
debugOutput('Returned array: ' + subPermutes);
for(var subPermuteIndex = 0; subPermuteIndex < subPermutes.length; subPermuteIndex++ )
{
var subPermute = subPermutes[subPermuteIndex];
for(var charIndex = 0; charIndex <= subPermute.length; charIndex++)
{
var pre = subPermute.slice( 0, charIndex );
var post = subPermute.slice( charIndex );
returnArray.push(pre+character+post);
debugOutput(pre + '_' + character + '_' + post );
}
}
return returnArray;
}
Basically, this will walk to the end of the string and work its way back constructing all permutations of sub-strings. It is easiest to see this from the debug output for 1234. Note that 'Returned array' refers to the array that was created by the permutations of the sub-string. Also note that the current character is placed in every position in that array. The current character is shown between _ such as the 1 in 432_1_.
Returned array: 4
_3_4
4_3_
Returned array: 34,43
_2_34
3_2_4
34_2_
_2_43
4_2_3
43_2_
Returned array: 234,324,342,243,423,432
_1_234
2_1_34
23_1_4
234_1_
_1_324
3_1_24
32_1_4
324_1_
_1_342
3_1_42
34_1_2
342_1_
_1_243
2_1_43
24_1_3
243_1_
_1_423
4_1_23
42_1_3
423_1_
_1_432
4_1_32
43_1_2
432_1_
This algorithm doesn't enforce uniqueness. So, if you have a string 22 then you will get two results - 22,22. Also, this algorithm uses recursion which I think is quite intuitive in this case, however there are pure iterative implementations if you look for them.
There are several errors in that code.
You have the order of the parts of the for statement incorrect. The order is initialization, test, increment. So for (/* init */ ; /* test */ ; /* increment */)
You're creating a new array for each iteration of your outer loop.
I'm making this a CW because I haven't checked for further errors than the above.

Categories

Resources