【问题标题】:Anagram algorithm objective CAnagram 算法目标 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;
}

【问题讨论】:

标签: objective-c algorithm anagram


【解决方案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。太多人不知道这个类甚至存在以及它可以用于什么(然后使用NSDictionaryNSNumber...呃)
  • 你还需要小写,去掉非字母。像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;
        
        }
        

        【讨论】:

          猜你喜欢
          • 2012-03-08
          • 2015-07-18
          • 2015-06-08
          • 1970-01-01
          • 2016-09-05
          • 2013-10-09
          • 2011-07-25
          • 2011-09-27
          • 2013-11-05
          相关资源
          最近更新 更多