Objective c NSString中子字符串的出现次数?
如何获取NSString(例如,Objective c NSString中子字符串的出现次数?,objective-c,cocoa,nsstring,substring,Objective C,Cocoa,Nsstring,Substring,如何获取NSString(例如,@“cake”)在较大的NSString(例如,@“Cheesecake、apple cake和cherry pie”)中出现的次数 我需要在很多字符串上这样做,所以无论我使用什么方法,都需要相对快速 谢谢 没有内置方法。我建议返回一个c字符串,并使用一个通用的c字符串类型的算法进行子字符串计数。。。如果你真的需要这是快 如果你想保持目标C,这可能会有所帮助。它描述了NSString的基本子字符串搜索。如果你使用范围,调整和计数,那么你将有一个“纯”的目标C解决方
@“cake”
)在较大的NSString(例如,@“Cheesecake、apple cake和cherry pie”
)中出现的次数
我需要在很多字符串上这样做,所以无论我使用什么方法,都需要相对快速
谢谢 没有内置方法。我建议返回一个c字符串,并使用一个通用的c字符串类型的算法进行子字符串计数。。。如果你真的需要这是快
如果你想保持目标C,这可能会有所帮助。它描述了NSString的基本子字符串搜索。如果你使用范围,调整和计数,那么你将有一个“纯”的目标C解决方案。。。尽管很慢。有几种方法可以做到这一点。您可以迭代调用
rangeOfString:options:range:
,也可以执行以下操作:
NSArray * portions = [aString componentsSeparatedByString:@"cake"];
NSUInteger cakeCount = [portions count] - 1;
编辑我再次思考这个问题,我编写了一个线性时间算法来进行搜索(与草堆字符串的长度成线性关系):
+(NSUTEGER)字符串发生次数:(NSString*)指针指示:(NSString*)干草堆{
const char*rawPinele=[Pinele UTF8String];
NSU整数针长=strlen(粗针);
const char*rawshaystack=[haystack UTF8String];
NSU整数haystackLength=strlen(rawHaystack);
整数针数=0;
指数=0;
对于(整数索引=0;索引=针长度){
NeedCount++;//我们找到了针
指数=0;
}
}
}
回针数;
}
这没有经过测试,但应该是一个良好的开端
NSUInteger count = 0, length = [str length];
NSRange range = NSMakeRange(0, length);
while(range.location != NSNotFound)
{
range = [str rangeOfString: @"cake" options:0 range:range];
if(range.location != NSNotFound)
{
range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
count++;
}
}
下面是一个版本,它是对
NSString
的扩展(与Matthew Flaschen的回答相同):
@接口NSString(我的子搜索)
-(无符号)countOccurnceSof:(NSString*)子字符串;
@结束
@实现NSString(我的子字符串搜索)
-(无符号)countOccurnceSof:(NSString*)子字符串{
无符号计数=0;
无符号myLength=[自身长度];
NSRange uncheckedRange=NSMakeRange(0,myLength);
对于(;;){
NSRange foundAtRange=[自范围字符串:子字符串]
选项:0
范围:不勾选“];
if(foundAtRange.location==NSNotFound)返回计数;
无符号newLocation=NSMaxRange(FoundaRange);
uncheckedRange=NSMakeRange(newLocation,myLength newLocation);
计数++;
}
}
@结束
{
NSString*haystack=@“芝士蛋糕、苹果蛋糕和樱桃派”;
NSString*针=@“蛋糕”;
无符号计数=[haystack CountOccurrencesof:Pine针];
NSLog(@“找到%u个时间%@”,计数,计数==1?@“”:@“s”);
}
如果您想计算单词,而不仅仅是子字符串,那么请使用。用于(int i=0;iMatthew Flaschen的答案对我来说是一个很好的开始。以下是我最终以方法的形式使用的内容。我对循环采取了一种稍微不同的方法。这已经用传递给stringToCount和text的空字符串进行了测试,stringToCount作为文本中的第一个和/或最后一个字符出现
我定期使用此方法计算传递文本中的段落数(即stringToCount=@“\r”)
希望这对某人有用
- (int)countString:(NSString *)stringToCount inText:(NSString *)text{
int foundCount=0;
NSRange range = NSMakeRange(0, text.length);
range = [text rangeOfString:stringToCount options:NSCaseInsensitiveSearch range:range locale:nil];
while (range.location != NSNotFound) {
foundCount++;
range = NSMakeRange(range.location+range.length, text.length-(range.location+range.length));
range = [text rangeOfString:stringToCount options:NSCaseInsensitiveSearch range:range locale:nil];
}
return foundCount;
}
假设方法位于名为myHelperClass的类中,则调用示例
int foundCount = [myHelperClass countString:@"n" inText:@"Now is the time for all good men to come to the aid of their country"];
正在寻找一种比我的更好的方法,但下面是另一个例子:
NSString *find = @"cake";
NSString *text = @"Cheesecake, apple cake, and cherry pie";
NSInteger strCount = [text length] - [[text stringByReplacingOccurrencesOfString:find withString:@""] length];
strCount /= [find length];
我想知道哪一个更有效
为了更好地使用,我制作了一个NSString
类别:
// NSString+CountString.m
@interface NSString (CountString)
- (NSInteger)countOccurencesOfString:(NSString*)searchString;
@end
@implementation NSString (CountString)
- (NSInteger)countOccurencesOfString:(NSString*)searchString {
NSInteger strCount = [self length] - [[self stringByReplacingOccurrencesOfString:searchString withString:@""] length];
return strCount / [searchString length];
}
@end
简单地说:
[text countOccurencesOfString:find];
可选:
您可以通过定义选项将其修改为不区分大小写的搜索方式:
下面的正则表达式应该在没有循环交互的情况下完成此工作
已编辑
NSString *string = @"Lots of cakes, with a piece of cake.";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"cake" options:NSRegularExpressionCaseInsensitive error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, [string length])];
NSLog(@"Found %i",numberOfMatches);
仅在iOS 4.x和更高版本上可用。以下是NSString上的另一个分类版本:
-(NSUInteger) countOccurrencesOfSubstring:(NSString *) substring {
if ([self length] == 0 || [substring length] == 0)
return 0;
NSInteger result = -1;
NSRange range = NSMakeRange(0, 0);
do {
++result;
range = NSMakeRange(range.location + range.length,
self.length - (range.location + range.length));
range = [self rangeOfString:substring options:0 range:range];
} while (range.location != NSNotFound);
return result;
}
一种打字速度更快但效率可能更低的解决方案
- (int)numberOfOccurencesOfSubstring:(NSString *)substring inString:(NSString*)string
{
NSArray *components = [string componentsSeparatedByString:substring];
return components.count-1; // Two substring will create 3 separated strings in the array.
}
-(iAction)搜索:(id)发件人{
int maincount=0;
对于(int i=0;iSwift)而言,解决方案为:
var numberOfSubstringAppearance = 0
let length = count(text)
var range: Range? = Range(start: text.startIndex, end: advance(text.startIndex, length))
while range != nil {
range = text.rangeOfString(substring, options: NSStringCompareOptions.allZeros, range: range, locale: nil)
if let rangeUnwrapped = range {
let remainingLength = length - distance(text.startIndex, rangeUnwrapped.endIndex)
range = Range(start: rangeUnwrapped.endIndex, end: advance(rangeUnwrapped.endIndex, remainingLength))
numberOfSubstringAppearance++
}
}
调用例如NSString.UTF8String不会导致分配新字符串吗?似乎使用NSString的方法(如rangeOfString)会更快。是的。如果您决定复制它以供以后使用,则会执行两次。与深入研究NSString方法和分配相比,创建一次c字符串并查找k个子字符串的影响最小在每次点击后都要提取一个子字符串。不一定。如果你从一个不可变的字符串开始,子字符串就不需要分配。正如Chris所演示的,也根本不需要提取子字符串。另外请注意,如果字符串是UTF-16,将字符串转换为UTF8可能会非常昂贵。组件由字符串分离解决方案会导致大量不必要的内存分配。@Matthew true,但这是一个两行解决方案。NumberOfOfOccurrenceSofString:inString:
当搜索字符串以与指针相同的字符开始时失败,但在仍处于成功匹配的内部时不再匹配。这是因为NeedIndex总是被重新设置设置为0,但实际上需要更复杂的逻辑。举一个简单的例子:[self numberOfOccurrencesOfString:@“aab”inString:@“aaab”]
返回值为0,而它显然应该是1。有关高效子字符串匹配算法中涉及的所有复杂问题,请参阅和算法。范围=[str rangeOfString:@“蛋糕”选项:0范围:范围);此LOC必须为repla
-(NSUInteger) countOccurrencesOfSubstring:(NSString *) substring {
if ([self length] == 0 || [substring length] == 0)
return 0;
NSInteger result = -1;
NSRange range = NSMakeRange(0, 0);
do {
++result;
range = NSMakeRange(range.location + range.length,
self.length - (range.location + range.length));
range = [self rangeOfString:substring options:0 range:range];
} while (range.location != NSNotFound);
return result;
}
- (int)numberOfOccurencesOfSubstring:(NSString *)substring inString:(NSString*)string
{
NSArray *components = [string componentsSeparatedByString:substring];
return components.count-1; // Two substring will create 3 separated strings in the array.
}
-(IBAction)search:(id)sender{
int maincount = 0;
for (int i=0; i<[self.txtfmainStr.text length]; i++) {
char c =[self.substr.text characterAtIndex:0];
char cMain =[self.txtfmainStr.text characterAtIndex:i];
if (c == cMain) {
int k=i;
int count=0;
for (int j = 0; j<[self.substr.text length]; j++) {
if (k ==[self.txtfmainStr.text length]) {
break;
}
if ([self.txtfmainStr.text characterAtIndex:k]==[self.substr.text characterAtIndex:j]) {
count++;
}
if (count==[self.substr.text length]) {
maincount++;
}
k++;
}
}
NSLog(@"%d",maincount);
}
}
var numberOfSubstringAppearance = 0
let length = count(text)
var range: Range? = Range(start: text.startIndex, end: advance(text.startIndex, length))
while range != nil {
range = text.rangeOfString(substring, options: NSStringCompareOptions.allZeros, range: range, locale: nil)
if let rangeUnwrapped = range {
let remainingLength = length - distance(text.startIndex, rangeUnwrapped.endIndex)
range = Range(start: rangeUnwrapped.endIndex, end: advance(rangeUnwrapped.endIndex, remainingLength))
numberOfSubstringAppearance++
}
}