这是使用回溯解决的经典案例,通常的情况是您面临许多选项,您必须从中选择一个。做出选择后,您将获得一组新选项;您获得的选项集取决于您做出的选择。一遍又一遍地重复此过程,直到您达到最终状态。这里有一个很好的回溯解释http://www.cis.upenn.edu/~matuszek/cit596-2012/NewPages/backtracking.html
/*
This part needs to be in the caller program, which will pass the original array and input. I have taken input as an array, you can use input as a string for your question, in the end for the algorithm it doesn't matter.
NSArray* a1 = @[
@[@"A", @"B", @"C", @"E"],
@[@"S", @"F", @"C", @"S"],
@[@"A", @"D", @"E", @"E"],
];
NSArray* input = @[ @"A", @"B", @"C", @"B" ];
BOOL result = [self checkPath:a1 andInput:input];
*/
-(BOOL) checkPath:(NSArray*)a1 andInput:(NSArray*)input
{
// Create a test array to keep track of what options you have already used.
NSMutableArray* testArray =
[[NSMutableArray alloc] init];
[testArray addObject:[[NSMutableArray alloc] init]];
[testArray addObject:[[NSMutableArray alloc] init]];
[testArray addObject:[[NSMutableArray alloc] init]];
// Initialize all the elements of the test array to zero, You should replace zero with 1 when you match the element at a certain index.
for(int i = 0; i < 3; i++) {
for (int j = 0; j< 4; j++) {
testArray[i][j] = @0;
}
}
for(int i = 0; i < 3; i++) {
for (int j = 0; j< 4; j++) {
NSLog(@"%@", a1[i][j]);
}
}
BOOL res = NO;
int i = 0, j = 0;
while (!res && i <3) {
while (!res && j <4) {
if( [input[0] isEqualToString:a1[i][j]])
{
testArray[i][j] = @1;
res = [self doesPathExist:input dictionaryArray:a1 startIndexX:i andStartIndexY:j compareIndex:1 andMarkerTable:testArray];
// Reset the test option incase the chosen option wasn't success
testArray[i][j] = [NSNumber numberWithBool:res];
}
j++;
}
i++;
}
return res;
}
/**
* Check if the path exist in array a1 starting at index x and y for elements of array input, starting at element c
*
* @param input input array for which you want to check path in a1
* @param a1 array in which we want to check the path
* @param x row number to start with
* @param y column number to start with
* @param c index of elemnet to check in input array
* @param markerTable table that decides which elements have already been used.
*
* @return yes if path exist for array input in a1 otherwise No
*/
-(BOOL)doesPathExist:(NSArray*)input dictionaryArray:(NSArray*)a1 startIndexX:(int) x andStartIndexY:(int) y compareIndex:(int)c andMarkerTable:(NSMutableArray*) markerTable
{
NSUInteger n = markerTable.count;
NSUInteger m = ((NSArray*)markerTable[0]).count;
NSUInteger N = input.count;
if (c == N)
{
NSLog(@"YES, Path Exists");
return YES;
}
else
{
BOOL result = NO;
while (c < N) {
int left = y -1;
int right = y + 1;
int top = x - 1;
int bottom = x + 1;
if (left>=0 && ![markerTable[x][left] isEqualToNumber: @1]) {
if( [a1[x][left] isEqualToString:input[c]]){
// set marker table value as 1 to mark the match
markerTable[x][left] = @1;
result = [self doesPathExist:input dictionaryArray:a1 startIndexX:x andStartIndexY:left compareIndex:c+1 andMarkerTable:markerTable];
// reset the marker table based on result, we do a reset of marker
// table at the index to make sure if this combination fails and there
// is another combination involving this element it should be able to use this element.
markerTable[x][left] = [NSNumber numberWithBool:result];
return result;
}
}
if (right<m && ![markerTable[x][right] isEqualToNumber:@1]) {
if([a1[x][right] isEqualToString:input[c]]) {
markerTable[x][right] = @1;
result = [self doesPathExist:input dictionaryArray:a1 startIndexX:x andStartIndexY:right compareIndex:c+1 andMarkerTable:markerTable];
markerTable[x][right] = [NSNumber numberWithBool:result];
return result;
}
}
if(top >=0 && ![markerTable[top][y] isEqualToNumber:@1]) {
if([a1[top][y] isEqualToString:input[c]]) {
markerTable[top][y] = @1;
result = [self doesPathExist:input dictionaryArray:a1 startIndexX:top andStartIndexY:y compareIndex:c+1 andMarkerTable:markerTable];
markerTable[top][y] = [NSNumber numberWithBool:result];
return result;
}
}
if(bottom < n && ![markerTable[bottom][y] isEqualToNumber:@1]) {
if([a1[bottom][y] isEqualToString:input[c]]) {
markerTable[bottom][y] = @1;
result = [self doesPathExist:input dictionaryArray:a1 startIndexX:bottom andStartIndexY:y compareIndex:c+1 andMarkerTable:markerTable];
markerTable[bottom][y] = [NSNumber numberWithBool:result];
return result;
}
}
c++;
}
NSLog(@"Returning false");
return NO;
}
}