Anagram 算法目标 C
Posted
技术标签:
【中文标题】Anagram 算法目标 C【英文标题】:Anagram algorithm objective C 【发布时间】:2012-12-04 01:11:08 【问题描述】:我编写了以下代码来检查 anagram 想知道这是完美的吗?有没有更好的方法在目标 C 中实现相同的功能
-(BOOL) findAnagram :(NSString *) string1 :(NSString *) string2
int len = string1.length;
if (len != string2.length)
return false;
for (int i=0; i < len; i++)
int h = 0;
int q = 0;
for (int k = 0; k < len ; k ++)
if ([string1 characterAtIndex:i] == [string1 characterAtIndex:k])
h++;
if ([string1 characterAtIndex:i] == [string2 characterAtIndex:k])
q++;
if (h!=q)
return false;
return TRUE;
【问题讨论】:
这应该在代码审查网站上。 这个问题属于codereview.stackexchange.com 【参考方案1】:一个比你的性能更好的版本,它是一个 O(n ^ 2) 算法,是一个 O(n) 算法:
BOOL anagrams(NSString *a, NSString *b)
if (a.length != b.length)
return NO;
NSCountedSet *aSet = [[NSCountedSet alloc] init];
NSCountedSet *bSet = [[NSCountedSet alloc] init];
for (int i = 0; i < a.length; i++)
[aSet addObject:@([a characterAtIndex:i])];
[bSet addObject:@([b characterAtIndex:i])];
return [aSet isEqual:bSet];
【讨论】:
+1 表示NSCountedSet
。太多人不知道这个类甚至存在以及它可以用于什么(然后使用NSDictionary
和NSNumber
...呃)
你还需要小写,去掉非字母。像a = [[[a componentsSeparatedByCharactersInSet:[[NSCharacterSet letterCharacterSet] invertedSet]] componentsJoinedByString:@""] lowercaseString];
这样的东西。用于测试的示例字谜:“Tom Marvolo Riddle”、“I am Lord Voldemort”。
@Jano true,但我认为该特定细节已由 OP 实现。【参考方案2】:
您想知道两个字符串是否包含完全相同的字符?最简单的方法可能是对它们进行排序并比较排序后的版本。
另一种方法是计算每个字母出现的次数(有多少 As,多少 B,等等),然后比较这些次数。
(注意:第二种方式只是第一种方式的变体,是一种对字符串进行排序的有效方式)
【讨论】:
他的算法正在执行您的第二个想法,尽管它会检查两次或三次等,如果某个字符出现超过 1 次。【参考方案3】:我觉得很好。但是代码风格有点奇怪。我会这样写:
- (BOOL)isStringAnagram:(NSString *)string1 ofString:(NSString *)string2
int len = string1.length;
if (len != string2.length)
return NO;
for (int i=0; i < len; i++)
int h = 0;
int q = 0;
for (int k = 0; k < len; k++)
if ([string1 characterAtIndex:i] == [string1 characterAtIndex:k])
h++;
if ([string1 characterAtIndex:i] == [string2 characterAtIndex:k])
q++;
if (h != q)
return NO;
return YES;
我遇到的主要问题是方法名称。虽然名称中可能有参数前面没有任何内容,但不建议这样做。即您使用 findAnagram::
作为名称,而我使用的是 isStringAnagram:ofString:
。
【讨论】:
【参考方案4】:这是对@zmbq 排序和比较建议的实现。
您应该考虑删除空格和不区分大小写的要求。
- (BOOL)isAnagram:(NSString *)leftString and:(NSString *)rightString
NSString *trimmedLeft = [[leftString stringByReplacingOccurrencesOfString:@" " withString:@""] lowercaseString];
NSString *trimmedRight = [[rightString stringByReplacingOccurrencesOfString:@" " withString:@""] lowercaseString];
return [[self stringToCharArraySorted:trimmedLeft] isEqual:[self stringToCharArraySorted:trimmedRight]];
- (NSArray *)stringToCharArraySorted:(NSString *)string
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i = 0 ; i < string.length ; i++)
[array addObject:@([string characterAtIndex:i])];
return [[array sortedArrayUsingSelector:@selector(compare:)] copy];
这样称呼
BOOL isAnagram = [self isAnagram:@"A BC" and:@"cba"];
【讨论】:
【参考方案5】:检查以下检查 Anagram 字符串的方法。
-(BOOL)checkAnagramString:(NSString*)string1 WithAnotherString:(NSString*)string2
NSCountedSet *countSet1=[[NSCountedSet alloc]init];
NSCountedSet *countSet2=[[NSCountedSet alloc]init];
if (string1.length!=string2.length)
NSLog(@"NOT ANAGRAM String");
return NO;
for (int i=0; i<string1.length; i++)
[countSet1 addObject:@([string1 characterAtIndex:i])];
[countSet2 addObject:@([string2 characterAtIndex:i])];
if ([countSet1 isEqual:countSet2])
NSLog(@"ANAGRAM String");
return YES;
else
NSLog(@"NOT ANAGRAM String");
return NO;
【讨论】:
【参考方案6】:磨坊算法的另一个运行:
- (BOOL) testForAnagramWithStrings:(NSString *)stringA andStringB: (NSString *)stringB
stringA = [stringA lowercaseString];
stringB = [stringB lowercaseString];
int counter = 0;
for (int i=0; i< stringA.length; i++)
for (int j=0; j<stringB.length;j++)
if ([stringA characterAtIndex:i]==[stringB characterAtIndex:j])
counter++;
if (counter!= stringA.length)
return false;
return true;
【讨论】:
以上是关于Anagram 算法目标 C的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode算法题-Valid Anagram(Java实现)
多目标遗传算法 ------ NSGA-II (部分源码解析) 交叉操作 crossover.c
多目标遗传算法 ------ NSGA-II (部分源码解析)状态报告 打印 report.c