Re: Reversing a String
Unfortunately, this is not correct; -[NSString characterAtIndex:] returns a unichar, which is not a char. In addition, it will give odd results for composed characters. Depending on what you want, you might be able to use rangeOfComposedCharacterAtIndex:. I'd also use NSMutableString instead of a stack buffer of chars, since this looks like a buffer overflow (unless I'm missing something): I think this is definitely the way to go. Something like this (untested, typed into Mail): - (NSString*) reversedString { unsigned len = [self length]; NSMutableString* reversed = [NSMutableString stringWithCapacity:len]; unsigned charIdx = len; while( charIdx 0 ) { NSRange charRng = [self rangeOfComposedCharacterSequenceAtIndex: (charIdx - 1)]; [reversed appendString:[self substringWithRange:charRng]]; charIdx = charRng.location; } return reversed; } Naturally this will be horribly inefficient, as it creates a new object for every composed character sequence, but the logic is likely what an end-user would expect a reversed string to look like. If you ever actually needed to optimize the string reversal you could drop down to using a reasonably sized unichar buffer and getCharacters:inRange: to do it in batches. I'm not sure how one would best optimize the composed character sequences calculations, but probably checking against +[NSCharacterSet nonBaseCharacterSet] would be good enough. ~Martin ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Reversing a String (Gabe Shahbazian)
I have been using the following for a while across a number of languages without problems. NSString *s = @Hello; unsigned int length = [s length]; unsigned int index = length - 1; NSMutableArray *ma = [NSMutableArray array]; while( index UINT_MAX ) { NSRange rng = NSMakeRange( index, 1 ); [ma addObject:[s substringWithRange:rng]]; --index; } NSString *reversed = [ma componentsJoinedByString:@]; NSLog(@reversed : %@,reversed); PGJH ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String (Gabe Shahbazian)
On Wed, Dec 31, 2008 at 4:28 AM, Peter Hudson peter.hud...@mac.com wrote: I have been using the following for a while across a number of languages without problems. NSString *s = @Hello; unsigned int length = [s length]; unsigned int index = length - 1; NSMutableArray *ma = [NSMutableArray array]; while( index UINT_MAX ) { NSRange rng = NSMakeRange( index, 1 ); [ma addObject:[s substringWithRange:rng]]; --index; } NSString *reversed = [ma componentsJoinedByString:@]; NSLog(@reversed : %@,reversed); I'm rather surprised, as this will fail on something as simple as an accented e using a separate combining character, let alone more complex constructs. Mike ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
Ironic... This question came up in a job interview I had a couple weeks ago. The following NSString category will work to reverse a string, and in my limited tests, it works with accents, mathematical symbols, and Korean characters: - (NSString *) stringByReversingSelf { NSMutableString * r = [NSMutableString stringWithString:self]; NSUInteger len = [r length]; NSUInteger mid = floor(len/2); for(int i = 0; i mid; i++) { NSRange fr = NSMakeRange(i,1); NSRange lr = NSMakeRange(len-i-1,1); NSString * f = [r substringWithRange:fr]; NSString * l = [r substringWithRange:lr]; [r replaceCharactersInRange:fr withString:l]; [r replaceCharactersInRange:lr withString:f]; } return r; } Here's the output of my extremely limited tests: (attached as a .png screenshot so that the encoding doesn't get messed up) Cheers, Dave On Dec 31, 2008, at 8:51 AM, Michael Ash wrote: On Wed, Dec 31, 2008 at 4:28 AM, Peter Hudson peter.hud...@mac.com wrote: I have been using the following for a while across a number of languages without problems. NSString *s = @Hello; unsigned int length = [s length]; unsigned int index = length - 1; NSMutableArray *ma = [NSMutableArray array]; while( index UINT_MAX ) { NSRange rng = NSMakeRange( index, 1 ); [ma addObject:[s substringWithRange:rng]]; --index; } NSString *reversed = [ma componentsJoinedByString:@]; NSLog(@reversed : %@,reversed); I'm rather surprised, as this will fail on something as simple as an accented e using a separate combining character, let alone more complex constructs. Mike ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
Looks like the attachment didn't come along. It's up here: http://davedelong.com/stuff/stringreverse.png Dave On Dec 31, 2008, at 9:29 AM, Dave DeLong wrote: Ironic... This question came up in a job interview I had a couple weeks ago. The following NSString category will work to reverse a string, and in my limited tests, it works with accents, mathematical symbols, and Korean characters: - (NSString *) stringByReversingSelf { NSMutableString * r = [NSMutableString stringWithString:self]; NSUInteger len = [r length]; NSUInteger mid = floor(len/2); for(int i = 0; i mid; i++) { NSRange fr = NSMakeRange(i,1); NSRange lr = NSMakeRange(len-i-1,1); NSString * f = [r substringWithRange:fr]; NSString * l = [r substringWithRange:lr]; [r replaceCharactersInRange:fr withString:l]; [r replaceCharactersInRange:lr withString:f]; } return r; } Here's the output of my extremely limited tests: (attached as a .png screenshot so that the encoding doesn't get messed up) Cheers, Dave ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
On Wed, Dec 31, 2008 at 11:29 AM, Dave DeLong davedel...@me.com wrote: Ironic... This question came up in a job interview I had a couple weeks ago. The following NSString category will work to reverse a string, and in my limited tests, it works with accents, mathematical symbols, and Korean characters: - (NSString *) stringByReversingSelf { NSMutableString * r = [NSMutableString stringWithString:self]; NSUInteger len = [r length]; NSUInteger mid = floor(len/2); for(int i = 0; i mid; i++) { NSRange fr = NSMakeRange(i,1); NSRange lr = NSMakeRange(len-i-1,1); NSString * f = [r substringWithRange:fr]; NSString * l = [r substringWithRange:lr]; [r replaceCharactersInRange:fr withString:l]; [r replaceCharactersInRange:lr withString:f]; } return r; } Here's the output of my extremely limited tests: (attached as a .png screenshot so that the encoding doesn't get messed up) Nope, doesn't work. It works on your test data because your test data doesn't contain any multi-character units. The fundamental error that everyone is making here is in assuming that a unichar is a single indivisible unit that can be tossed around at will. But it doesn't work that way. Sometimes you have multiple unichars next to each other in a grouping which must be preserved. Try your method on a string which contains abcde\u0301f where the \u0301 is actually unicode code point 0301 COMBINING ACUTE ACCENT. It starts out with abcdef with an acute accent on the e. After passing through your method, it ends up with the accent on the f! Or try it with a string that contains 1D11E MUSICAL SYMBOL G CLEF. This is a single code point which requires two unichars to represent, because unichar is only 16-bits and so NSString is implicitly UTF-16. After passing through your method, the two unichars which make up this single character get reversed which produces an invalid sequence, and the resulting string can't be printed. Here's code which works properly with those problems: - (NSString *)stringByReversingSelf { NSMutableString *me = [NSMutableString stringWithString:self]; NSMutableString *result = [NSMutableString string]; while([me length]) { NSRange range = [me rangeOfComposedCharacterSequenceAtIndex:0]; [result insertString:[me substringWithRange:range] atIndex:0]; [me deleteCharactersInRange:range]; } return result; } The key is the usage of -rangeOfComposedCharacterSequenceAtIndex:. Without calling this method or doing the equivalent to what it does, your code will suffer the problems I described above. I tested that code with the string @abcdéf턞g (that's an accented e using a combining diacritical before the f, and the aforementioned musical note at the end) and it worked as expected. I don't guarantee that my code will work on everything. Unicode is weird enough and covers enough weird languages that there are probably situations where this will still fail. But it covers most of the tricky bits, and at least will always produce valid unicode output. Mike ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
On Dec 31, 2008, at 10:52 AM, Michael Ash wrote: The key is the usage of -rangeOfComposedCharacterSequenceAtIndex:. Without calling this method or doing the equivalent to what it does, your code will suffer the problems I described above. I tested that code with the string @abcdéf턞g (that's an accented e using a combining diacritical before the f, and the aforementioned musical note at the end) and it worked as expected. I don't guarantee that my code will work on everything. Unicode is weird enough and covers enough weird languages that there are probably situations where this will still fail. But it covers most of the tricky bits, and at least will always produce valid unicode output. Reversing a string only really makes sense for certain languages anyhow. Perhaps even just English. The rendering of reversed strings may also get a bit weird for text involving positional variants. Anyhow, attempting to construct a universal solution will either be too difficult or perhaps not possible. The original poster should provide some extra clues as to what the output will be used for. I'm all for 100% Unicode support by applications, but there are some situations where working with plain 'ol ASCII still makes sense. In that specific case, reversing a string becomes trivial. ___ Ricky A. Sharp mailto:rsh...@instantinteractive.com Instant Interactive(tm) http://www.instantinteractive.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Reversing a String
What is the best way to take an NSString and reverse the characters so that hello becomes olleh? Thanks for any and all help, Gabe S ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
On 31/12/2008, at 4:08 PM, Gabe Shahbazian wrote: What is the best way to take an NSString and reverse the characters so that hello becomes olleh? Thanks for any and all help, Gabe S Hi Gabe. I don't think there's anything in Cocoa that does this for you. I needed to reverse strings and came up with this: - (NSString *)reverseString:(NSString *)aString { // Do the reversing with the help of an array of chars int i, j; const int stringLength = [aString length]; char reverseChars[stringLength]; for (i = stringLength - 1, j = 0; i = 0; i--, j++) { char c = [aString characterAtIndex:i]; reverseChars[j] = c; } reverseChars[j] = '\0';// create a C (UTF8) string by adding a null char NSString *backwardsString = [NSString stringWithUTF8String:reverseChars]; return backwardsString; } HTH, Ron ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
On 31 Dec 2008, at 4:35 pm, Graham Cox wrote: I don't think this is legal Hmm, seems C99 allows this. I didn't know that - my bad. --Graham ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
On Dec 31, 2008, at 4:23 PM, Ron Fleckner wrote: const int stringLength = [aString length]; char reverseChars[stringLength]; for (i = stringLength - 1, j = 0; i = 0; i--, j++) { char c = [aString characterAtIndex:i]; reverseChars[j] = c; } Unfortunately, this is not correct; -[NSString characterAtIndex:] returns a unichar, which is not a char. In addition, it will give odd results for composed characters. Depending on what you want, you might be able to use rangeOfComposedCharacterAtIndex:. I'd also use NSMutableString instead of a stack buffer of chars, since this looks like a buffer overflow (unless I'm missing something): reverseChars[j] = '\0';// create a C (UTF8) string by adding a null char -- Adam smime.p7s Description: S/MIME cryptographic signature ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
On 31/12/2008, at 4:42 PM, Graham Cox wrote: On 31 Dec 2008, at 4:35 pm, Graham Cox wrote: I don't think this is legal Hmm, seems C99 allows this. I didn't know that - my bad. --Graham Ha ha, yes. I resisted trying to explain that because I wouldn't be able to do it properly. I did it once sort of accidentally -- which worked -- then realized that it wasn't supposed to. I queried Uli Kusterer about this via his Masters of The Void site http://www.masters-of-the-void.com/what-you-need.htm and he said it was legal with the GCC compiler. I didn't know it was legal in C99. Ron ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
On Dec 31, 2008, at 4:42 PM, Graham Cox wrote: On 31 Dec 2008, at 4:35 pm, Graham Cox wrote: I don't think this is legal Hmm, seems C99 allows this. I didn't know that - my bad. Personally, I avoid variable length arrays out of fear that the allocation might fail. On 10.3 or 10.4 I ran into a situation where writing to memory from alloca was smashing the stack; unfortunately it didn't return NULL when it wasn't able to allocate sufficient memory. My impression was that the mechanism is similar for these, but I could be totally wrong... -- Adam smime.p7s Description: S/MIME cryptographic signature ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
In general, it would perhaps be best to create a c string from the NSString using the proper text encoding and then iterating through the C string in reverse, appending each character to an NSMutableString. Iterating through each character of an NSString is likely to be slow and the usage of characterAtIndex is certainly more than pointer arithmetic. -rob. On Dec 31, 2008, at 12:59 AM, Adam R. Maxwell wrote: On Dec 31, 2008, at 4:23 PM, Ron Fleckner wrote: const int stringLength = [aString length]; char reverseChars[stringLength]; for (i = stringLength - 1, j = 0; i = 0; i--, j++) { char c = [aString characterAtIndex:i]; reverseChars[j] = c; } Unfortunately, this is not correct; -[NSString characterAtIndex:] returns a unichar, which is not a char. In addition, it will give odd results for composed characters. Depending on what you want, you might be able to use rangeOfComposedCharacterAtIndex:. I'd also use NSMutableString instead of a stack buffer of chars, since this looks like a buffer overflow (unless I'm missing something): reverseChars[j] = '\0';// create a C (UTF8) string by adding a null char -- Adam ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/rob%40pinchmedia.com This email sent to r...@pinchmedia.com smime.p7s Description: S/MIME cryptographic signature ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
On Dec 30, 2008, at 10:23 PM, Ron Fleckner wrote: - (NSString *)reverseString:(NSString *)aString { // Do the reversing with the help of an array of chars int i, j; const int stringLength = [aString length]; char reverseChars[stringLength]; for (i = stringLength - 1, j = 0; i = 0; i--, j++) { char c = [aString characterAtIndex:i]; reverseChars[j] = c; } reverseChars[j] = '\0';// create a C (UTF8) string by adding a null char NSString *backwardsString = [NSString stringWithUTF8String:reverseChars]; return backwardsString; } There are a few problems with this method, e.g. it won't work with non- ASCII characters, it'll probably blow up if the string is ~10,000 characters or longer, the ints need to be NSUIntegers, and this ought to be a category method that works on the receiver. I'd use unichar, NSUInteger, malloc(), and - initWithCharactersNoCopy:length:freeWhenDone: at the least... Nick Zitzmann http://www.chronosnet.com/ ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
On Wed, Dec 31, 2008 at 12:08 AM, Gabe Shahbazian igothye3...@gmail.com wrote: What is the best way to take an NSString and reverse the characters so that hello becomes olleh? This doesn't make sense for all locales. Are you sure you want to do this? --Kyle Sluder ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Reversing a String
On 31/12/2008, at 5:26 PM, Nick Zitzmann wrote: On Dec 30, 2008, at 10:23 PM, Ron Fleckner wrote: - (NSString *)reverseString:(NSString *)aString { // Do the reversing with the help of an array of chars int i, j; const int stringLength = [aString length]; char reverseChars[stringLength]; for (i = stringLength - 1, j = 0; i = 0; i--, j++) { char c = [aString characterAtIndex:i]; reverseChars[j] = c; } reverseChars[j] = '\0';// create a C (UTF8) string by adding a null char NSString *backwardsString = [NSString stringWithUTF8String:reverseChars]; return backwardsString; } There are a few problems with this method, e.g. it won't work with non-ASCII characters, it'll probably blow up if the string is ~10,000 characters or longer, the ints need to be NSUIntegers, and this ought to be a category method that works on the receiver. I'd use unichar, NSUInteger, malloc(), and - initWithCharactersNoCopy:length:freeWhenDone: at the least... Nick Zitzmann http://www.chronosnet.com/ Yes of course, you're right. Perhaps I should have pointed that out to the OP but didn't think of it because I use it in a app which is a pale clone of Accessorizer, that is, the string it's reversing is a type and variable declaration. Reading it backwards gives me the variable name before any asterisks or types, so I can work out (in the code) quickly whether the variable is a pointer or a primitive type. Ron ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com