Reputation: 3588
I have a large string set something like - Objective-C is the primary programming language you use when writing software for OS X and iOS. It’s a superset of the C programming language and provides object-oriented capabilities and a dynamic runtime. Objective-C inherits the syntax, primitive types, and flow control statements of C and adds syntax for defining classes and methods. It also adds language-level support for object graph management and object literals while providing dynamic typing and binding, deferring many responsibilities until runtime.
I wants to divide above string in the length of at least 15 characters strings which will be ending by whitespaces & store in an array. For this I have applied following logic which is working fine , But it will be busy the compiler in case of long strings like 1000000 characters , Please help me if you can suggest better way to meet by requirements .Thanks.
NSMutableArray *randomSelection = [[NSMutableArray alloc] init];
NSString *shortDescription = shortDesc_;
NSString *str=@"";
NSArray *iarray=[shortDescription componentsSeparatedByString:@" "];
NSInteger i=0;
while (i<iarray.count)
{
NSString *prevStr=str;
str=[prevStr stringByAppendingString:[[iarray objectAtIndex:i] stringByAppendingString:@" "]];
if(str.length>15)
{
[randomSelection addObject:prevStr];
str=[[iarray objectAtIndex:i] stringByAppendingString:@" "];
}
i++;
}
if(str.length>0)
[randomSelection addObject:str];
Upvotes: 0
Views: 151
Reputation: 461
Try this
int numberOfLetters = 15;
if ([text length]>numberOfLetters) {
NSMutableArray* strings = [[NSMutableArray alloc] init];
__block int checkedStringLenght = 0;
while (checkedStringLenght<text.length-1) {
int rest = (int)text.length - checkedStringLenght;
__block NSRange neededRange;
[text enumerateSubstringsInRange:NSMakeRange(checkedStringLenght, MIN(rest,numberOfLetters)) options:NSStringEnumerationByWords | NSStringEnumerationReverse usingBlock:^(NSString *substring, NSRange subrange, NSRange enclosingRange, BOOL *stop) {
unsigned long fin =subrange.location - checkedStringLenght-1;
if (fin == 0){
NSString* lastString = [text substringWithRange:NSMakeRange(checkedStringLenght, rest)];
if ([[strings lastObject] length] + rest <= numberOfLetters) {
[strings replaceObjectAtIndex:strings.count-1 withObject:[strings[strings.count-1] stringByAppendingString:lastString]];
} else [strings addObject:lastString];
checkedStringLenght+=rest;
}
else {
neededRange =NSMakeRange(checkedStringLenght, fin);
NSString *ch = [text substringWithRange:neededRange];
checkedStringLenght+=ch.length;
[strings addObject:ch];
}
*stop = YES;
}];
}
NSLog(@"%@",strings);
}
My while
is executing only (int)(text.lenght/numberOfLetters)+1
times, your while
- for each word. enumerateSubstringInRage:options:
is executing 1 time for each while
, because is getting the last word only.
Upvotes: 0
Reputation: 53000
Let's consider your algorithm, which as you correctly state works.
You first break up your million characters into "words", so you have another million characters in memory at this point, and then you join the words into strings of 15 or more characters - and that will occupy another million or so characters of memory. Maybe you could remove the need for the intermediate million by breaking up the input directly at the right points? That should reduce your memory requirements by roughly 1/3 and save a fair bit of copying.
Next when building up your string of 15 or so characters you repeatedly call length
to calculate the length of the newly extended string. However you know how long it is - the previous length + length of added word + 1 for the space. Maybe keeping track of the length would save worthwhile time?
But then you wouldn't need to keep track of the length at all if you broke the string in the right place, but is that possible?
Consider the methods:
rangeOfCharacterFromSet:options:range
or rangeOfString:options:range
; andsubstringWithRange:
One of the first two can be used to easily find the range of characters which make up your next string of 15 or so, and the last enables you to extract it. No intermediate million or so characters in memory, no need to keep checking the length.
Will it be faster? Give it a go and find out!
HTH
Upvotes: 2