Sim*_*iwi 51 cocoa objective-c nsstring
我一直在谷歌搜索如何做到这一点,但我将如何扭转NSString?例如:嗨会变成:呃
我正在寻找最简单的方法来做到这一点.
谢谢!
@Vince我做了这个方法:
- (IBAction)doneKeyboard {
// first retrieve the text of textField1
NSString *myString = field1.text;
NSMutableString *reversedString = [NSMutableString string];
NSUInteger charIndex = 0;
while(myString && charIndex < [myString length]) {
NSRange subStrRange = NSMakeRange(charIndex, 1);
[reversedString appendString:[myString substringWithRange:subStrRange]];
charIndex++;
}
// reversedString is reversed, or empty if myString was nil
field2.text = reversedString;
}
Run Code Online (Sandbox Code Playgroud)
我把那个方法连接到textfield1的didendonexit.当我单击完成按钮时,它不会反转文本,UILabel只显示我输入的UITextField文本.怎么了?
Jan*_*ano 103
阻止版本.
NSString *myString = @"abcdefghijklmnopqrstuvwxyz";
NSMutableString *reversedString = [NSMutableString stringWithCapacity:[myString length]];
[myString enumerateSubstringsInRange:NSMakeRange(0,[myString length])
options:(NSStringEnumerationReverse | NSStringEnumerationByComposedCharacterSequences)
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[reversedString appendString:substring];
}];
// reversedString is now zyxwvutsrqponmlkjihgfedcba
Run Code Online (Sandbox Code Playgroud)
小智 51
写一个简单的循环来做到这一点:
// myString is "hi"
NSMutableString *reversedString = [NSMutableString string];
NSInteger charIndex = [myString length];
while (charIndex > 0) {
charIndex--;
NSRange subStrRange = NSMakeRange(charIndex, 1);
[reversedString appendString:[myString substringWithRange:subStrRange]];
}
NSLog(@"%@", reversedString); // outputs "ih"
Run Code Online (Sandbox Code Playgroud)
在你的情况下:
// first retrieve the text of textField1
NSString *myString = textField1.text;
NSMutableString *reversedString = [NSMutableString string];
NSInteger charIndex = [myString length];
while (myString && charIndex > 0) {
charIndex--;
NSRange subStrRange = NSMakeRange(charIndex, 1);
[reversedString appendString:[myString substringWithRange:subStrRange]];
}
// reversedString is reversed, or empty if myString was nil
textField2.text = reversedString;
Run Code Online (Sandbox Code Playgroud)
小智 11
jano的回答是正确的.不幸的是,它会产生许多不必要的临时对象.这是一个更快(更复杂)的实现,基本上做同样的事情,但使用memcpy和unichar缓冲区将内存分配保持在最低限度.
- (NSString *)reversedString
{
NSUInteger length = [self length];
if (length < 2) {
return self;
}
unichar *characters = calloc(length, sizeof(unichar));
unichar *reversedCharacters = calloc(length, sizeof(unichar));
if (!characters || !reversedCharacters) {
free(characters);
free(reversedCharacters);
return nil;
}
[self getCharacters:characters range:NSMakeRange(0, length)];
NSUInteger i = length - 1;
NSUInteger copiedCharacterCount = 0;
// Starting from the end of self, copy each composed character sequence into reversedCharacters
while (copiedCharacterCount < length) {
NSRange characterRange = [self rangeOfComposedCharacterSequenceAtIndex:i];
memcpy(reversedCharacters + copiedCharacterCount, characters + characterRange.location, characterRange.length * sizeof(unichar));
i = characterRange.location - 1;
copiedCharacterCount += characterRange.length;
}
free(characters);
NSString *reversedString = [[NSString alloc] initWithCharactersNoCopy:reversedCharacters length:length freeWhenDone:YES];
if (!reversedString) {
free(reversedCharacters);
}
return reversedString;
}
Run Code Online (Sandbox Code Playgroud)
我在100,000个随机多字节Unicode字符串上测试了这个,长度在1到128之间.这个版本比jano快4-5倍.
Enumerate substrings: 2.890528
MemCopy: 0.671090
Enumerate substrings: 2.840411
MemCopy: 0.662882
Run Code Online (Sandbox Code Playgroud)
测试代码位于https://gist.github.com/prachigauriar/9739805.
更新:我通过简单地转换为UTF-32缓冲区并反转它再次尝试了这一点.
- (NSString *)qlc_reversedStringWithUTF32Buffer
{
NSUInteger length = [self length];
if (length < 2) {
return self;
}
NSStringEncoding encoding = NSHostByteOrder() == NS_BigEndian ? NSUTF32BigEndianStringEncoding : NSUTF32LittleEndianStringEncoding;
NSUInteger utf32ByteCount = [self lengthOfBytesUsingEncoding:encoding];
uint32_t *characters = malloc(utf32ByteCount);
if (!characters) {
return nil;
}
[self getBytes:characters maxLength:utf32ByteCount usedLength:NULL encoding:encoding options:0 range:NSMakeRange(0, length) remainingRange:NULL];
NSUInteger utf32Length = utf32ByteCount / sizeof(uint32_t);
NSUInteger halfwayPoint = utf32Length / 2;
for (NSUInteger i = 0; i < halfwayPoint; ++i) {
uint32_t character = characters[utf32Length - i - 1];
characters[utf32Length - i - 1] = characters[i];
characters[i] = character;
}
return [[NSString alloc] initWithBytesNoCopy:characters length:utf32ByteCount encoding:encoding freeWhenDone:YES];
}
Run Code Online (Sandbox Code Playgroud)
这比memcpy版本快3-4倍.上述要点已使用最新版本的代码进行了更新.
Enumerate substrings: 2.168705
MemCopy: 0.488320
UTF-32: 0.150822
Enumerate substrings: 2.169655
MemCopy: 0.481786
UTF-32: 0.147534
Enumerate substrings: 2.248812
MemCopy: 0.505995
UTF-32: 0.154531
Run Code Online (Sandbox Code Playgroud)
我想我会抛出另一个版本以防万一有人感兴趣..个人而言,我喜欢使用NSMutableString的更清洁的方法,但如果性能是最高优先级,那么这个更快:
- (NSString *)reverseString:(NSString *)input {
NSUInteger len = [input length];
unichar *buffer = malloc(len * sizeof(unichar));
if (buffer == nil) return nil; // error!
[input getCharacters:buffer];
// reverse string; only need to loop through first half
for (NSUInteger stPos=0, endPos=len-1; stPos < len/2; stPos++, endPos--) {
unichar temp = buffer[stPos];
buffer[stPos] = buffer[endPos];
buffer[endPos] = temp;
}
return [[NSString alloc] initWithCharactersNoCopy:buffer length:len freeWhenDone:YES];
}
Run Code Online (Sandbox Code Playgroud)
我还写了一个快速测试,以便将它与更传统的NSMutableString方法(我在下面也包括在内)进行比较:
// test reversing a really large string
NSMutableString *string = [NSMutableString new];
for (int i = 0; i < 10000000; i++) {
int digit = i % 10;
[string appendFormat:@"%d", digit];
}
NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970];
NSString *reverse = [self reverseString:string];
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSince1970] - startTime;
NSLog(@"reversed in %f secs", elapsedTime);
Run Code Online (Sandbox Code Playgroud)
结果是:
使用NSMutableString方法(下) - "在3.720631秒内反转"
使用unichar*缓冲方法(上图) - "在0.032604秒内反转"
仅供参考,这是用于此比较的NSMutableString方法:
- (NSString *)reverseString:(NSString *)input {
NSUInteger len = [input length];
NSMutableString *result = [[NSMutableString alloc] initWithCapacity:len];
for (int i = len - 1; i >= 0; i--) {
[result appendFormat:@"%c", [input characterAtIndex:i]];
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
42566 次 |
| 最近记录: |