• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSString, scramble
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSString, scramble


  • Subject: Re: NSString, scramble
  • From: Michel Haver <email@hidden>
  • Date: Mon, 02 Jul 2001 23:09:26 +0200

On 7/1/01 16:45, "Fritz Anderson" <email@hidden> wrote:

> At 2:38 PM +0200 7/1/2001, Michel M.J. Haver wrote:
>> I want to read a couple of string and then scramble the strings by mixing
>> the characters in the strings to new ad random positions.
>>
>> Problem Description by Example
>> I want to convert a string like for example "heart" to "retah"
>> or the next time you run the program the example string "heart" will be
>> converted in an other random scramble string like "tarhe".
>>
>> How I can implement such a random string scramble functionality with the
>> cocoa objects NSString, NSMutableString is something of a riddle to me which
>> I am working to find out.
>>
>> Does someone has some tips for solving this riddle?
>
> A solution appears at the end of this message. It is the complete
> source for a Foundation tool that makes an anagram of each argument
> passed to the tool.
>
>> I prefer to do it in Cocoa or is it should this kind of string manipulation
>> be done in C or C++?
>
> That's a separate question. The NSString solution works for any
> Unicode string, and handles dynamic-memory issues in a
> guaranteed-safe fashion. If called repeatedly, the overhead of
> dynamic allocation (I'm thinking particularly of the single-unichar
> substrings) would become a performance problem. In the unlikely
> event makeAnagram is called a huge number of times without releasing
> the current autorelease pool, there would be a memory problem (which,
> under Mac OS X, shows up first as a performance problem).
>
> The memory problem could be lessened by allocating an
> NSAutoreleasePool before the huge number of calls to makeAnagram, and
> periodically releasing and reallocating it.
>
> You could improve performance inside makeAnagram by calling [self
> getCharacters:] to get a copy of the string's characters in a C array
> of unichar, scrambling the array, and then passing the array to
> [NSString stringWithCharacters: length:] to produce the returned
> string. With this approach, my [swapCharacterAtIndex: withIndex:] is
> unnecessary, and [makeAnagram] can return NSString *.
>
> I didn't do this because (1) the "more efficient" way only just
> occurred to me; and (2) my example does have the advantage of being a
> close translation of your own.
>
> Absolutely ruthless optimization might drive you to give up Unicode
> support and work directly with ASCII C strings.
>
> -- F
>
> #import <Foundation/Foundation.h>
> #import <stdlib.h>
> #import <time.h>
>
> unsigned randRange(unsigned lowIncluded, unsigned highExcluded);
>
> // Return an unsigned integer in the range [low .. high)
> inline
> unsigned randRange(unsigned lowIncluded,
> unsigned highExcluded)
> {
> return lowIncluded + ((unsigned) random()) % (highExcluded - lowIncluded);
> }
>
> @interface NSMutableString (Anagrams)
> - (void) swapCharacterAtIndex: (unsigned) indexOne
> withIndex: (unsigned) indexTwo;
> @end
>
> @interface NSString (Anagrams)
> - (NSMutableString *) makeAnagram;
> @end
>
> @implementation NSMutableString (Anagrams)
>
> - (void) swapCharacterAtIndex: (unsigned) indexOne
> withIndex: (unsigned) indexTwo
> {
> unichar firstCharacter = [self characterAtIndex: indexOne],
> secondCharacter = [self characterAtIndex: indexTwo];
> NSString * firstString = [NSString stringWithCharacters: &firstCharacter
> length: 1];
> NSString * secondString = [NSString stringWithCharacters: &secondCharacter
> length: 1];
>
> [self replaceCharactersInRange: NSMakeRange(indexOne, 1)
> withString: secondString];
> [self replaceCharactersInRange: NSMakeRange(indexTwo, 1)
> withString: firstString];
> }
>
> @end
>
> @implementation NSString (Anagrams)
>
> - (NSMutableString *) makeAnagram
> {
> NSMutableString * retval = [self mutableCopy];
> unsigned i;
>
> for (i = 0; i < [self length]; i++) {
> [retval swapCharacterAtIndex: i withIndex: randRange(0, [self
> length])];
> }
>
> return [retval autorelease];
> }
>
> @end
>
> int main (int argc, const char * argv[])
> {
> NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
> NSArray * arguments = [[NSProcessInfo processInfo] arguments];
> int i;
>
> // Seed the random number generator
> srandom(time(NULL));
>
> for (i = 1; i < [arguments count]; i++) {
> NSString * fromString = [arguments objectAtIndex: i];
>
> NSString * anagram = [fromString makeAnagram];
>
> printf("%s\n", [anagram cString]);
> }
>
> [pool release];
> return 0;
> }


Fritz,

I am still bewildered by the quick answer on my question. I tried your
solution and it worked after I added

NSMutableArray * arguments = [[NSProcessInfo processInfo]
arguments];
[arguments addObject:@"Here's a string!"];

The NSMutableArray Gives no warning NSArray doesn't respond to "addObject"


The addition [arguments addObject:@"Here's a string!"];
results in a compiler waring NSArray Gives warning NSArray doesn't respond
to "addObject"
With NSArray * arguments = [[NSProcessInfo processInfo]
arguments];

Output of your program
'e ti!nHgrrse sa
Jul 02 22:42:20 anagram[1052] String out: 'e ti!nHgrrse sa.

anagram.app has exited with status 0.

Questions:
I want to implement this construction in my cocoa application.
How can I use @implementation NSString (Anagrams) without the NSMutableArray
construction?

Learning by example code makes the steep learning more manageable, so is
there a depot with cocoa example code other than the ADC examples?

Cheers,

Michel



#import <Foundation/Foundation.h>
//#import <stdlib.h>
//#import <time.h>

unsigned randRange(unsigned lowIncluded, unsigned highExcluded);

// Return an unsigned integer in the range [low .. high)
inline
unsigned randRange(unsigned lowIncluded,
unsigned highExcluded)
{
return lowIncluded + ((unsigned) random()) % (highExcluded -
lowIncluded);
}

@interface NSMutableString (Anagrams)
- (void) swapCharacterAtIndex: (unsigned) indexOne
withIndex: (unsigned) indexTwo;
@end

@interface NSString (Anagrams)
- (NSMutableString *) makeAnagram;
@end

@implementation NSMutableString (Anagrams)

- (void) swapCharacterAtIndex: (unsigned) indexOne
withIndex: (unsigned) indexTwo
{
unichar firstCharacter = [self characterAtIndex: indexOne],
secondCharacter = [self characterAtIndex: indexTwo];
NSString * firstString = [NSString stringWithCharacters:
&firstCharacter
length: 1];
NSString * secondString = [NSString stringWithCharacters:
&secondCharacter
length: 1];

[self replaceCharactersInRange: NSMakeRange(indexOne, 1)
withString: secondString];
[self replaceCharactersInRange: NSMakeRange(indexTwo, 1)
withString: firstString];
}

@end

@implementation NSString (Anagrams)

- (NSMutableString *) makeAnagram
{
NSMutableString * retval = [self mutableCopy];
unsigned i;

for (i = 0; i < [self length]; i++) {
[retval swapCharacterAtIndex: i withIndex: randRange(0, [self
length])];
}

return [retval autorelease];
}

@end

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableArray * arguments = [[NSProcessInfo processInfo]
arguments];

// NSArray * arguments = [[NSProcessInfo processInfo]
arguments];
int i;


// Seed the random number generator
srandom(time(NULL));

// NSLog(@"String out: %@.\n", arguments);

//add object to the array arguments
// NSArray * arguments = [[NSProcessInfo processInfo]
arguments];
// With NSArray Gives warning NSArray doesn't respond to "addObject"
// With NSMutableArray Gives no warning NSArray doesn't respond to
"addObject"

[arguments addObject:@"Here's a string!"];
// Print the contents of the array.
//NSLog(@"Array description: %@ \n", arguments);


for (i = 1; i < [arguments count]; i++) {
NSString * fromString = [arguments objectAtIndex: i];

NSString * anagram = [fromString makeAnagram];

printf("%s\n", [anagram cString]);
NSLog(@"String out: %@.\n", anagram);

}

[pool release];
return 0;
}


References: 
 >Re: NSString, scramble (From: Fritz Anderson <email@hidden>)

  • Prev by Date: Re: NSString, scramble
  • Next by Date: AFPMountURL in OS X?
  • Previous by thread: Re: NSString, scramble
  • Next by thread: Re: NSString, scramble
  • Index(es):
    • Date
    • Thread