Need help with this recursive problem (JavaScript)

  • Java
  • Thread starter Jamin2112
  • Start date
  • Tags
    Javascript
In summary: A = new Array(); if(w == 1) { return A; } else if(w > 1) { A = single_ops(w-1); } //Do your operation here return A;}In summary, the conversation was about a function single_ops(w) that returns a JavaScript array of all strings that can be made from 1 operation on the string w. The function uses a loop that runs "n" times, where "n" is proportional to the length of the word. The conversation also mentioned a recursive approach, but it was suggested to use a loop instead. The conversation also included a suggestion to change the variable "closeChars" to use the
  • #1
Jamin2112
986
12
Okay, so I have a function single_ops(w) that returns a JavaScript array of all strings that can be made from 1 operation on the string w:

Code:
		function single_ops(w)
		{
			/* Given a word w, return an array of all strings that are w with:
			
			   (1) 1 letter inserted, that letter being one which is distance
				   1 away on the keyboard
			   (2) 1 letter replaced, that letter being one which is distance
				   1 away on the keyboard
			   (3) 1 letter removed
			   (4) 2 adjacent letters swapped
			*/
			var A = new Array(); // Associative array to store words, so we can add them w/out addding repeats
			for (var i = 0, j = w.length; i < j; ++i)
			{
				var closeChars = kdmap[w[i]];
				var s1a = w.slice(0,i); // equals w[0], ..., w[i-1]    
				var s2a = w.slice(i,j); // equals w[i], ..., w[j-1]    
				var s1b = w.slice(0,i+1); // equals w[0], ..., w[i]
				var s2b = w.slice(i+1,j) // equals w[i+1], ..., w[j-1]
				for (var k = 0, n = closeChars.length; k < n; ++k)
				{
				    var cc = closeChars[k];
					// (1) ----------------------------------------------
					A[s1a + cc + s2a] = 1; // equals w[0],..., w[i-1], cc, w[i],..., w[j-1]
					A[s1b + cc + s2b] = 1; // equals w[0], ..., w[i], cc, w[i+1], ..., w[j-1]
					// (2) ----------------------------------------------
					A[s1a + cc + s2b] = 1; // equals w[0], ..., w[i-1], cc, w[i+1], ..., w[j-1]
				}
				// (3) --------------------------------------------------
				if (j > 1)
				    A[s1a + s2b] = 1; // equals w[0], ..., w[i-1], w[i+1], ..., w[j-1]
				// (4) --------------------------------------------------
				A[s1a + s2b.slice(0,1) + s2a.slice(0,1) + s2b.slice(1,s2b.length)] = 1;
			}
			return A;
		}

Yes, I know the procedure is messy and crappy. But it works for now. My problem is something different.

I want a procedure that uses that recursively calls that function so that I can have a set of all strings made from n operations on w. In other words, call the function once, returning an array A of all strings that are formed from 1 operation on w then, on each element of A, call the function again and merge the elements of the returned array to A, etc.

I'm working on it but having trouble with the part where I have a variable that is limiting the number of recursions. Any help?
 
Technology news on Phys.org
  • #2
You don't really need recursion for this, just a loop that run "n" times.
Of course, when n gets to be more than 2, you're going to be consuming significant processor and memory resources.

Also, you seem to be mixing characters in a string with characters in an array.

Suggest you change:
var closeChars = kdmap[w];
to
var closeChars = kdmap[w.charAt(i)];

I will post a solution in a moment.
 
  • #3
Here you go:
Code:
var distance = 2;
var neighbors = Array();
var allneighbors = Array();
allneighbors["was"] = 1;
neighbors["was"] = 1;//
for(i=0;i<distance;i++) {
  newneighbors = new Array();
  for (newword in neighbors) {
    var wordneighbors = single_ops(newword);
    for (word in wordneighbors) {
      if(allneighbors[word]!=1) {
        allneighbors[word] = 1;
        newneighbors[word] = 1;
      }
    }
  }
  neighbors = newneighbors;
}

for (word in allneighbors) {
  document.write("<br>"+word);
}
 
  • #4
.Scott said:
You don't really need recursion for this, just a loop that run "n" times.
Of course, when n gets to be more than 2, you're going to be consuming significant processor and memory resources.

I have constructed my algorithm so that n is proportional to the length of the word, so that longer words are expected to have more room for error. I have n=w.length/8+1, but I might even change it to n=w.length/10+1. It's expected that the user will be using gigantic words rarely.

Also, you seem to be mixing characters in a string with characters in an array.

Suggest you change:
var closeChars = kdmap[w];
to
var closeChars = kdmap[w.charAt(i)];


I thought those were equivalent?
 
  • #5
Jamin2112 said:
I have constructed my algorithm so that n is proportional to the length of the word, so that longer words are expected to have more room for error. I have n=w.length/8+1, but I might even change it to n=w.length/10+1. It's expected that the user will be using gigantic words rarely.
I thought those were equivalent?

Using the array method has some compatibility issues with older browsers. It is faster though.
 
  • #6
Jamin2112 said:
I have constructed my algorithm so that n is proportional to the length of the word, so that longer words are expected to have more room for error. I have n=w.length/8+1, but I might even change it to n=w.length/10+1. It's expected that the user will be using gigantic words rarely.
Of course it will be the largest words that will give you the biggest problems. A really long word will bring your computer to a halt as surely as pneumonultramicroscopicsilicovolcanokoniosis.
Jamin2112 said:
.Scott said:
Also, you seem to be mixing characters in a string with characters in an array.

Suggest you change:
var closeChars = kdmap[w];
to
var closeChars = kdmap[w.charAt(i)];


I thought those were equivalent?
It didn't work on my Firefox at work. As I recall, it's a version that's about 2 years old.
In any case, I hope your code is working smoothly.
 
  • #7
Is this what the OP was asking for?

Make a recursive program that receives n as a parameter. When the incoming parameter n > 1, make recursive calls passing n-1 down. When the incoming parameter n=1, just execute your existing program and return.
 
Last edited:
  • #8
.Scott said:
[STRIKE]It didn't work on my Firefox at work.[/STRIKE]
Correction, I tried it with Explorer 9 (2011) at work. That's were it didn't work.
 
  • #9
FactChecker said:
Is this what the OP was asking for?

Make a recursive program that receives n as a parameter. When the incoming parameter n > 1, make recursive calls passing n-1 down. When the incoming parameter n=1, just execute your existing program and return.
You would also need to consolidate the list of results.
Also the program as I implemented it, checks for words that have already been checked - so that you don't end up rechecking the same words over and over.
He asked for a recursive process, but I believe he was looking for a practical solution. The algorithm I presented was recursive - but it did not use recursive function calls.
 
  • #10
.Scott said:
He asked for a recursive process, but I believe he was looking for a practical solution. The algorithm I presented was recursive - but it did not use recursive function calls.
Ok. The last line of the OP asked a fundamental question about how to design a recursive solution and I thought it would not hurt to answer it. And of course you are right that there are other details to deal with.
 
  • #11
Using recursion in Javascript may not be very easy. Javascript allows its functions to be called from anywhere, in such a way that the function context (surrounding environment) can be passed into the procedure as a parameter. Many programmers use Javascript for years without becoming aware of this capability. So you can have procedures inside procedures, and when you call the inner procedure (from anywhere!) it has the context of the surrounding procedure.

In other words, Javascript allows "closures" (in a computer science sense of the word).

Given that the average programmer finds it somewhat difficult to understand how to implement recursion anyway, this is a double hazard. In recursion, you have to make sure every variable used as part of the recursion is a local variable (declared within the recurring function) so that each invocation of the function adds new copies of those variables to the call stack. And then, you have to check first (within the function) for the case that ends the recursion.

I've never tried doing recursion in Javascript, and I seldom do it at all because of the performance hit of growing the stack during recursion. Since javascript has closures, it does not manage the call stack in the same way that C or C++ does. Thus, I think it might be risky to attempt recursion in Javascript. More risky than usual.

That said, here's a link claiming to do recursion in Javascript. I have not tested it: http://www.htmlgoodies.com/primers/jsp/article.php/3622321
 

FAQ: Need help with this recursive problem (JavaScript)

What is a recursive function in JavaScript?

A recursive function is a function that calls itself until a certain condition is met. It is commonly used to solve problems that can be broken down into smaller subproblems.

How does recursion work in JavaScript?

When a recursive function is called, it creates a stack frame in memory. This stack frame keeps track of the function's variables and parameters. The function then calls itself, passing in new values for the parameters. This process continues until the base case is reached, at which point the function starts to return values and the stack frames are popped off the stack.

What is a base case in a recursive function?

A base case is the condition that stops the recursive calls and starts the process of returning values. It is important to have a base case in a recursive function to avoid an infinite loop.

How do I solve problems using recursion in JavaScript?

To solve a problem using recursion, you first need to identify the base case and the recursive case. Then, you can write a function that calls itself and passes in new values until the base case is reached. Finally, you can return values from each recursive call to solve the problem.

What are the advantages and disadvantages of using recursion in JavaScript?

The main advantage of using recursion is that it can simplify the code and make it more elegant. It is also useful for solving certain types of problems. However, recursion can also be less efficient than iterative solutions and can lead to stack overflow errors if not implemented correctly.

Similar threads

Replies
2
Views
1K
Replies
4
Views
977
Replies
9
Views
1K
Replies
7
Views
2K
Replies
97
Views
8K
Back
Top