0

In the else statement of this main for loop, I am trying to add each newly created stacks into my queue and need to keep going on over the same queue until it's empty or I find the end word.

    for (Stack<String> next:wordQ){
        if(next.peek().toString().equals(start)){
            for(String each:next){
                ladder.add(each);
                return ladder;
            }
        } 
        else {
            LinkedList<String> temp2 = new LinkedList<String>();
            temp2 = (LinkedList<String>) getWordsOneAway(next.peek().toString());
            for ( String nextWord:temp2){
                @SuppressWarnings("unchecked")
                Stack<String> nextTempStack = (Stack<String>) next.clone();
                nextTempStack.push(nextWord);
                wordQ.add(nextTempStack);
            }
            buildLadder(start, next.peek().toString());
        }
    }

Tried using Iterator. Same issue.

Iterator<Stack<String>> myQIter = wordQ.iterator();
    while ( myQIter.hasNext()){
        Stack<String> tempStack = myQIter.next();
        //System.out.println("This is peek: " +tempStack.peek());
        if(tempStack.peek().toString().equals(start)){
            for(String each:tempStack){
                ladder.add(each);
                return ladder;
            }
        } 
        else {
            LinkedList<String> temp2 = new LinkedList<String>();
            temp2 = (LinkedList<String>) getWordsOneAway(tempStack.peek().toString());
            for ( String nextWord:temp2){
                @SuppressWarnings("unchecked")
                Stack<String> nextTempStack = (Stack<String>) tempStack.clone();
                nextTempStack.push(nextWord);
                wordQ.add(nextTempStack);
            }
            buildLadder(start, tempStack.peek().toString());
        }
    }

wordQ.add(nextTempStack); This is the issue

Nimantha
  • 6,405
  • 6
  • 28
  • 69

2 Answers2

2

So you are iterating through a list and adding to it as you go.

Try adding to new a new list, and then you have finished iterating through, call addAll to add to your original collection

Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
  • If I do that, the recursion at the end wouldn't prove the point. – script_before_java Apr 28 '15 at 01:22
  • I can not see any recursion from the code that you have posted. – Scary Wombat Apr 28 '15 at 01:24
  • there have been cases (minor) when I had to read from a collection and update the same , and at all the places i did exactly what is mentioned in this answer . and that way no chances of exception . i doubt there is any other alternative – Srinath Ganesh Apr 28 '15 at 01:26
  • I am sorry for the confusion. This for loop is part of buildLadder(____ , ____) method which is at the end of my for loop code. – script_before_java Apr 28 '15 at 01:28
  • I am guessing there is problem with your design. Maybe you should be passing the new list as a parameter? – Scary Wombat Apr 28 '15 at 01:30
  • *(well i have never worked with synchronization/concurrency related projects)* .... BUT i do have a view that recursively calling the method and updating your list in such a method is not a proper practice . correct me if i am wrong – Srinath Ganesh Apr 28 '15 at 01:33
0

Here is complete class. Got it to work without recursion.The old school for int i loop took care if concurrent modification problem.

import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;

/**
 * Class that created a word-ladder between two words (if possible)
 * @author GJ
 * @version 4/27/2015
 */
public class LadderBuilder {

    private Collection<String> dictionary;
    private Collection<String> usedWords = new HashSet<String>();

    public LadderBuilder(Collection<String> dictionary) {
        this.dictionary = dictionary;
    }


    public Deque<String> buildLadder(String start, String end){

        LinkedList<String> temp = new LinkedList<String>();
        Queue<Stack<String>> wordQ = new LinkedList<Stack<String>>();
        Deque<String> ladder = new LinkedList<String>();
        if ( start.length() != end.length()){
            System.err.println("Selected words are not of the same length.");
            System.exit(1);
        }
        temp = (LinkedList<String>) getWordsOneAway(end);
        Iterator<String> myIter = temp.iterator();
        while(myIter.hasNext()){

            Stack<String> words = new Stack<>();
            words.push(end);
            words.push(myIter.next());
            wordQ.add(words);
        }

        for (int i = 0; i < wordQ.size(); i++){
            Stack<String> temp3 = wordQ.poll();
            i--;
            if(temp3.peek().equals(start)){
                for(String each:temp3){
                    ladder.add(each);
                }
                return ladder;
            } 
            else {
                LinkedList<String> temp2 = new LinkedList<String>();
                temp2 = (LinkedList<String>) getWordsOneAway(temp3.peek());
                for ( String nextWord:temp2){
                    @SuppressWarnings("unchecked")
                    Stack<String> nextTempStack = (Stack<String>) temp3.clone();
                    nextTempStack.push(nextWord);
                    wordQ.add(nextTempStack);
                }
            }
        }
        return null;

    }

    private List<String> getWordsOneAway(String word){
        usedWords.add(word);
        List<String> oneAwayList = new LinkedList<String>();
        for (int i = 0; i < word.length(); i++) {
            char[] currCharArr = word.toCharArray();
            for (char c = 'a'; c <= 'z'; c++) {
                currCharArr[i] = c;
                String newWord = new String(currCharArr);
                if (dictionary.contains(newWord) && !(usedWords.contains(newWord))) {
                    oneAwayList.add(newWord);
                    usedWords.add(newWord);
                }
            }
        }

        return oneAwayList;
    }

}