Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c NSString中子字符串的出现次数?_Objective C_Cocoa_Nsstring_Substring - Fatal编程技术网

Objective c 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解决方

如何获取NSString(例如,
@“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++
     }
}