今天看到个面试题目, 觉得还有点意思。
原题目在这里(由于答复里面不支持Macdown,只好另开个文章来答复了)
最初的时候以为一个正则替换"<.*?>"应该就能解决问题,但是题目要求的<>之间的最短距离,并不是正则表达式中的最短匹配的概念,比如<a<b<c<!!!>在正则里面是符合"<.*?>"的,但是不符合题意,题意要求匹配<!!!>。又想了一下反向匹配如何?然后反向匹配又会遇到<!!!>a>b>c>的两难情况。
还望正则高手指点一下。有没有可能用正则匹配?
无奈只好自己写复杂的算法:
- (NSString *)myTrimString:(NSString *)from {
static NSString *startFlag = @"<";
static NSString *endFlag = @">";
NSMutableString *result = [from mutableCopy];
// find the start flag
NSRange startRange = [result rangeOfString:startFlag];
while (startRange.location != NSNotFound) {
CGFloat remainIndex = startRange.location + startRange.length;
NSRange remainRange = NSMakeRange(remainIndex, result.length-remainIndex);
// search from the remaining text
NSRange endRange = [result rangeOfString:endFlag options:0 range:remainRange];
if (endRange.location != NSNotFound) {
// try to locate the last one <, because we want to find the shortest content
CGFloat endIndex = endRange.location + endRange.length;
NSRange matchedRange = NSMakeRange(startRange.location, endIndex - startRange.location);
// use the NSBackwardsSearch option, so we find the first flag is the last flag we want.
NSRange nearestRange = [result rangeOfString:startFlag options:NSBackwardsSearch range:matchedRange];
matchedRange = NSMakeRange(nearestRange.location, endIndex - nearestRange.location);
[result deleteCharactersInRange:matchedRange];
// because we have delete the matched content in result,
// so the remain index must depent on this fact.
remainIndex = matchedRange.location;// + matchedRange.length - matchedRange.length;
startRange = [result rangeOfString:startFlag options:0 range:NSMakeRange(remainIndex, result.length - remainIndex)];
}
else {
// ok, have a rest:)
break;
}
}
return result;
}
顺便提升一下原题目的测试用例:
@"<a>3<4<5</b>5>4>3<//c><d>eee";
无奖欢迎抓BUG~~
BTW: 有空用Functional的思想再实现一下看看将会是怎么样的感觉。
网友评论