搜尋

首頁  >  問答  >  主體

objective-c - 關於NSString字串反轉的問題

今天看到這個“Objective-C分割NSString”,有人用正則表達式進行解答,感覺很特別。所以就把以前遇到的字符串反轉的問你拿出來討論討論,可不可以用正則表達式來解決呢?

下麵是個最簡單的實現的如有什麼效率問題,邊界問題也希望多給意見。

/**** NSString+Reverse.h ****/
#import <Foundation/Foundation.h>
@interface NSString (Reverse)
- (NSString *)stringByReversed;
@end

/**** NSString+Reverse.m ****/
#import "NSString+Reverse.h"
@implementation NSString (Reverse)
- (NSString *)stringByReversed
{
  NSMutableString *s = [NSMutableString string];
  for (NSUInteger i=self.length; i>0; i--) {
    [s appendString:[self substringWithRange:NSMakeRange(i-1, 1)]];
  }
  return s;
}
@end
分割線

3月24日補充

根據@ParagonLight同學的回答我用如下代碼做了個測試:

  NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  [dateFormatter setDateFormat:@"ss.SSSS"];

  NSLog(@"S %@", [dateFormatter stringFromDate:[NSDate date]]);
  NSString *reversed = [string stringByReversed];
  NSLog(@"E %@", [dateFormatter stringFromDate:[NSDate date]]);

測試用的字符串長度為:8970

記錄了10次結果,我製作了一個圖表(算法1為我問題中的;算法2為@ParagonLight同學的)

隻看代碼的話算法2可以提高一半的效率,之所以花的時間比算法1高出許多,是因為每次循環都會生成一個新string對象,所耗費時間確實超乎我的預想了。

分割線

3月25日補充

由於算法1和算法3相差很小,為了讓結果更明顯,修改了測試用例,將測試字符串長度放大100倍,現在測試字符串長度為:897000

@ParagonLight同學的算法3的性能提升還是很明顯的

巴扎黑巴扎黑2845 天前701

全部回覆(1)我來回復

  • PHP中文网

    PHP中文网2017-04-21 11:19:12

    我這裡用了stringByReplacingCharactersInRange:方法。但這個方法其實也是重新new了一個string,所以感覺還不是最有效率的做法。其實可以將string轉換成char數組,然後設定兩個指針,分別指向數組的頭和尾,然後依序交換指向的值,直到i>j。
    我本身接觸iOS時間不長,對其特性還不是那麼了解,有什麼不對的地方也勞煩指出。

    - (NSString *)stringByReversed
    {
        NSUInteger i = 0;
        NSUInteger j = self.length - 1;
        NSString *temp;
        NSString *newString = self;
        NSLog(@"%@", self);
        while (i < j) {
            temp = [newString substringWithRange:NSMakeRange(i, 1)];
            newString = [newString stringByReplacingCharactersInRange:NSMakeRange(i, 1) withString:[self substringWithRange:NSMakeRange(j, 1)]];
            newString = [newString stringByReplacingCharactersInRange:NSMakeRange(j, 1) withString:temp];
            NSLog(@"%@",newString);
            i ++;
            j --;
        }
        NSLog(@"%@", newString);
        return newString;
    }
    分割線

    試試看這個呢

    -(NSString *)stringByReversed{
        NSUInteger i = 0;
        NSUInteger j = self.length - 1;
        unichar characters[self.length];
        while (i < j) {
            characters[j] = [self characterAtIndex:i];
            characters[i] = [self characterAtIndex:j];
            i ++;
            j --;
        }
        if(i == j)
            characters[i] = [self characterAtIndex:i];
        return [NSString stringWithCharacters:characters length:self.length];
    }
    更新:演算法4

    目測是unichar陣列越界了。乾脆直接malloc。 。 。不過我不得不說,這已經不是OC了。 。 。

    - (NSString *)stringByReversed{
      uint64_t  i = 0;
      uint64_t j = self.length - 1;
    //  unichar characters[self.length];
      unichar *characters = malloc(sizeof([self characterAtIndex:0]) * self.length);
      while (i < j) {
        characters[j] = [self characterAtIndex:i];
        characters[i] = [self characterAtIndex:j];
        i ++;
        j --;
      }
      if(i == j)
        characters[i] = [self characterAtIndex:i];
      return [NSString stringWithCharacters:characters length:self.length];
    }

    回覆
    0
  • 取消回覆