Re: Reversing a String

2008-12-31 Thread Martin Wierschin
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)

2008-12-31 Thread Peter Hudson
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)

2008-12-31 Thread Michael Ash
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

2008-12-31 Thread Dave DeLong
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

2008-12-31 Thread Dave DeLong

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

2008-12-31 Thread Michael Ash
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

2008-12-31 Thread Ricky Sharp


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

2008-12-30 Thread Gabe Shahbazian
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

2008-12-30 Thread Ron Fleckner


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

2008-12-30 Thread Graham Cox


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

2008-12-30 Thread Adam R. Maxwell


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

2008-12-30 Thread Ron Fleckner


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

2008-12-30 Thread Adam R. Maxwell

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

2008-12-30 Thread Robert Marini
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

2008-12-30 Thread Nick Zitzmann


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

2008-12-30 Thread Kyle Sluder
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

2008-12-30 Thread Ron Fleckner


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