iOS敏感词过滤,DFA算法的OC实现

   最近给项目加个屏蔽敏感词的功能,在网上搜了一遍基本都是使用DFA算法由敏感词构造树,然后遍历输入文本,每次从树的根节点往下匹配,匹配成功则替换成*之类的即可,搜了一圈没有发现OC版的算法,故按着算法用OC写了一遍,分享一波。

   类定义如下:

#import "WordFilter.h"

#define EXIST @"isExists"

@interface WordFilter()

@property (nonatomic,strong) NSMutableDictionary *root;

@property (nonatomic,assign) BOOL isFilterClose;

@end

@implementation WordFilter

static WordFilter *instance;

+ (instancetype)sharedInstance{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc]init];
    });
    return instance;
}
   算法:

- (void)initFilter:(NSString *)filepath{
    
    self.root = [NSMutableDictionary dictionary];
    char word[1024];
    FILE *fp;
    char *p;
    
    //打开文件
    fp = fopen([filepath UTF8String], "r");
    
    //按行读取内容
    while (fgets(word, sizeof(word), fp)) {
        p = word;
        
        while (*p != 0) {
            if (*p == '\r' || *p == '\n' || *p == ' ') {
                *p = 0;
                break;
            }
            p++;
        }
        
        //插入字符,构造节点
        [self insertWords:[NSString stringWithUTF8String:word]];
    }
}

-(void)insertWords:(NSString *)words{
    NSMutableDictionary *node = self.root;
    
    for (int i = 0; i < words.length; i ++) {
        NSString *word = [words substringWithRange:NSMakeRange(i, 1)];
        
        if (node[word] == nil) {
            node[word] = [NSMutableDictionary dictionary];
        }
        
        node = node[word];
    }

    //敏感词最后一个字符标识
    node[EXIST] = [NSNumber numberWithInt:1];
}

- (NSString *)filter:(NSString *)str{
    
    if (self.isFilterClose || !self.root) {
        return str;
    }
    
    NSMutableString *result = result = [str mutableCopy];
    
    for (int i = 0; i < str.length; i ++) {
        NSString *subString = [str substringFromIndex:i];
        NSMutableDictionary *node = [self.root mutableCopy] ;
        int num = 0;
        
        for (int j = 0; j < subString.length; j ++) {
            NSString *word = [subString substringWithRange:NSMakeRange(j, 1)];
            
            if (node[word] == nil) {
                break;
            }else{
                num ++;
                node = node[word];
            }
            
            //敏感词匹配成功
            if ([node[EXIST]integerValue] == 1) {

                NSMutableString *symbolStr = [NSMutableString string];
                for (int k = 0; k < num; k ++) {
                    [symbolStr appendString:@"*"];
                }
                
                [result replaceCharactersInRange:NSMakeRange(i, num) withString:symbolStr];
                
                i += j;
                break;
            }
        }
    }
    
    return result;
}

- (void)freeFilter{
    self.root = nil;
}

- (void)stopFilter:(BOOL)b{
    self.isFilterClose = b;
}


你可能感兴趣的:(iOS)