0

I am trying to create an algorithm that essentially finds anagrams for a given word (Code below). After the user inputs their word, they press a button, and what it should be doing is looking at an array of words (populated from a txt file; I know that part works), and for each word taking the first letter and seeing if it is in the user's words, which I used a caseInsensitiveCompare to do. If all of the letters in the initial word are found in the user's typed word, it should add the word to an NSMutableArray. However, when I try to run it, testing by asking for the first word in the mutable array, I get the following error:

2014-08-07 13:56:52.231 HelloNoun[14796:60b] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'

This to me means that no words are being added to the mutable array. I don't understand this, since the user word itself should at least appear with the current code. I've looked through the documentation for everything I can think might be going wrong, and tried to Google an answer, but I'm still stumped as to why this isn't working.

I'm very green to coding, so any help with this issue or tips about things I should be doing differently (including about this post) are greatly appreciated.

Code:

- (IBAction)setOutput:(id)sender {
    NSString *lettersAvailableImmutable = self.userInput.text;
    NSMutableString *lettersAvailable;
    NSMutableArray *matches = [[NSMutableArray alloc] initWithCapacity:1];

    lettersAvailable = lettersAvailableImmutable];

    for (NSString *string in words)
    {
       int len = string.length;
        int runningTotal = 0;
        for (int i = 0; i < len; i++){
            NSString *currentChar = [string substringWithRange: NSMakeRange (i, 1)];
            int lettersAvailableLength = lettersAvailable.length;
            for (int j = 0; j < lettersAvailableLength; j++){
                NSString *currentInputChar = [lettersAvailable substringWithRange:NSMakeRange (j, 1)];
                if( [currentChar caseInsensitiveCompare:currentInputChar] == NSOrderedSame ) {
                    [lettersAvailable deleteCharactersInRange: NSMakeRange (j, 1)];
                    runningTotal++;
                    lettersAvailableLength--;
                }
                else {
                    continue;
                }
            }
        }
        if (runningTotal == len){
             [matches addObject:string];
        }
    }

    self.userOutput.text = [matches objectAtIndex:0];
}
9
  • 1
    Which line of code is giving the error. None of the code you posted makes any attempt to access an array element. Commented Aug 8, 2014 at 3:28
  • Between the last two closing brackets, I used this to test: self.userOutput.text = [matches objectAtIndex:0]; Commented Aug 8, 2014 at 3:32
  • 1
    OK, your code will crash any time there are no matches. Don't assume there are any matches. Commented Aug 8, 2014 at 3:38
  • 1
    You need to debug the code to find out why it doesn't do what you think it should do. Learning to use the debugger is a crucial skill. Commented Aug 8, 2014 at 3:58
  • 1
    @raki That would not cause any change in behavior at all. Commented Aug 8, 2014 at 5:40

2 Answers 2

3

If runningTotal is never == to len, then no objects will be added to matches.

Calling objectAtIndex: with an index of 0 on an empty array will yield that exception.

The initWithCapacity:1 does not create an array with one empty slot; it merely advises Foundation that the array should be optimized to hold up to 1 elements.

Or, in short, NSMutableArray is not a sparse array. There are no holes.


If no matches is expected, test for array.length > 0 before accessing an object.

If no matches is unexpected, then debug your code. Even NSLog() based debugging will work fine here.

Sign up to request clarification or add additional context in comments.

Comments

0

After several hours, I figured out the main problem (and learned more about debugging in the process) - I needed to copy the code creating lettersAvailable into the top for loop so that it would start anew each word. Now it works like a charm!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.