關(guān)于搜索出來的內(nèi)容根據(jù)權(quán)重進(jìn)行排序

這是整個功能的流程。

對于這需求要做到百度搜索我呸,谷歌搜索的權(quán)重排序官扣,我接到這個需求是拒絕的。后來經(jīng)過和小伙伴的研究产捞,覺得這個按照權(quán)重排序是可以實現(xiàn)的醇锚。

下面說一下具體思路。

@[@"abcd",@"1abcd",@"abcd1",@"ab1cd",@"1ab2cd",@"abdc"]

上面是一個數(shù)組的字符串坯临,就當(dāng)是我們查找出來的字符串?dāng)?shù)組,但是我們要按照我們搜索出來的關(guān)鍵詞的相似度進(jìn)行排序恋昼。

假設(shè)我們需要搜索的字符串是abcd看靠,對于人眼來說直接包含abcd的是排在最前面的。

但是包含abcd的有abcd,1abcd,abcd1液肌。很明顯這三個順序abcd,abcd1,1abcd.

我們?nèi)庋凼强梢钥闯鰜淼牡浅绦虿恢佬妫@就涉及到權(quán)重的問題了。

我們按照字母所在的位置進(jìn)行權(quán)重的計算嗦哆,權(quán)重越低的排在最前面谤祖。

abcd權(quán)重是0+1+2+3 = 6

abcd1權(quán)重是0+1+2+3 = 6

1abcd的權(quán)重是1+2+3+4 = 10

現(xiàn)在出現(xiàn)了兩個權(quán)重為6的,但是abcd這個完全和我們輸入的一樣老速。abcd1多了一個1,我們按照同樣的權(quán)重粥喜,字符串長度越短越排在前面。

那么這三個字符串排序變成了abcd abcd1 1abcd

剩下的字符串ab1cd 1ab2cd abdc了橘券。

我們進(jìn)行模糊搜索额湘,但是怎么進(jìn)行模糊搜索呢?小伙伴說進(jìn)行輸入的文字一個一個的進(jìn)行查找,找到就超找剩下的旁舰。

我們按照這個方法查找ab1cd 1ab2cd兩個锋华。

但是這兩個怎么排序呢 還是進(jìn)行權(quán)重排序。

ab1cd的權(quán)重 0+1+3+4 = 8

1ab2cd的權(quán)重是 1+2+4+5 = 12

那么這兩個進(jìn)行權(quán)重排序是ab1cd 1ab2cd

剩下的不滿足精確搜索和模糊搜索箭窜,應(yīng)該直接過濾掉的但是考慮到可能這個算法有問題就暫時按照字符串的長度進(jìn)行排序 全部放在最后毯焕。

下面是實現(xiàn)的代碼。

GBSortSearchCountryManger

對搜索出來的結(jié)果進(jìn)行排序的管理類磺樱。

/**
 需要進(jìn)行排序的數(shù)組字符串
 */
@property (nonatomic, strong) NSArray<NSString *> *searchResult;

進(jìn)行過濾的數(shù)據(jù)源

/**
 對數(shù)據(jù)源進(jìn)行按照權(quán)重排序之后的數(shù)組

 @param searchText 搜索的字符串
 @return 按照權(quán)重排序數(shù)組
 */
- (NSArray<NSString *> *)sortSearchResultWithSearchText:(NSString *)searchText;

進(jìn)行過濾的方法

- (NSArray<NSString *> *)sortSearchResultWithSearchText:(NSString *)searchText {
    _currentSortLevelType = SSCSortLevelTypeExactMatch; // 開始設(shè)置精確的搜索
    _currentSearchText = searchText;
    NSMutableArray<GBSortSearchCountryItem *> *sortItems = [NSMutableArray array];
    NSMutableArray<NSString *> *sortTempList = [NSMutableArray array];
    [self.searchResult enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        // 組裝數(shù)據(jù)源
        GBSortSearchCountryItem *item = [[GBSortSearchCountryItem alloc] init];
        item.text = obj;
        [sortItems addObject:item];
    }];
    while (_currentSortLevelType <= SSCSortLevelTypeOther) {
        // 當(dāng)查詢的狀態(tài)大于其他查詢就退出
        NSArray *sortItemList = [self sortItemWithLevelType:_currentSortLevelType sortResultItems:sortItems];
        [sortItemList enumerateObjectsUsingBlock:^(GBSortSearchCountryItem *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [sortTempList addObject:obj.text];
        }];
        [sortItems removeObjectsInArray:sortItemList];
        _currentSortLevelType ++;
    }
    return sortTempList;
}

實現(xiàn)方法

/**
 查詢當(dāng)前查詢的數(shù)據(jù)

 @param levelType 查詢的類型
 @param items 剩余的數(shù)據(jù)源
 @return 返回查詢出來的對象
 */
- (NSArray<GBSortSearchCountryItem *> *)sortItemWithLevelType:(SSCSortLevelType)levelType
                                              sortResultItems:(NSArray<GBSortSearchCountryItem *> *)items {
    NSMutableArray<GBSortSearchCountryItem *> *sortItems = [NSMutableArray array]; // 保存查詢出來的數(shù)據(jù)源
    switch (levelType) {
        case SSCSortLevelTypeExactMatch: {
            // 精確搜索
            [items enumerateObjectsUsingBlock:^(GBSortSearchCountryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                NSRange range = [obj.text rangeOfString:_currentSearchText]; // 查詢查詢的字符串是否在查找的字符串存在
                if (range.location != NSNotFound) {
                    // 如果存在就符合精確查找的結(jié)果
                    obj.levelTag = [self exactMatchCountWithRange:range]; // 查找權(quán)重
                    [sortItems addObject:obj];
                }
            }];
            sortItems = [NSMutableArray arrayWithArray:[self sortWithList:sortItems]]; // 根據(jù)權(quán)重進(jìn)行排序
        }
            break;
        case SSCSortLevelTypeFuzzySearch: {
            // 按照順序模糊搜索
            [items enumerateObjectsUsingBlock:^(GBSortSearchCountryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                NSInteger count = [self fuzzySearchLevelTagWithItem:obj]; // 查詢模糊搜索的權(quán)重 如果是0代表沒找到
                if (count != NSNotFound) {
                    obj.levelTag = count;
                    [sortItems addObject:obj];
                }
            }];
            sortItems = [NSMutableArray arrayWithArray:[self sortWithList:sortItems]];
        }
            break;
        case SSCSortLevelTypeOther: {
            [items sortedArrayUsingComparator:^NSComparisonResult(GBSortSearchCountryItem *  _Nonnull obj1, GBSortSearchCountryItem *  _Nonnull obj2) {
                if (obj1.text.length > obj2.text.length) {
                    return NSOrderedDescending;
                }else if(obj1.text.length < obj2.text.length) {
                    return NSOrderedAscending;
                }else {
                    return NSOrderedSame;
                }
            }];
            // 剩余的結(jié)果 防止算法有問題 造成數(shù)據(jù)帥選的bug
            [sortItems  addObjectsFromArray:items];
        }
            break;
        default:
            break;
    }
    return sortItems;
}

根據(jù)需要過濾的類型進(jìn)行過濾

/**
 計算精確搜索出來的權(quán)重

 @param range 搜索字符串的位置
 @return 權(quán)重
 */
- (NSUInteger)exactMatchCountWithRange:(NSRange)range {
    NSUInteger currentIndex = range.location;
    NSUInteger count = 0;
    while (currentIndex < range.location + range.length) {
        count += currentIndex;
        currentIndex ++;
    }
    return count;
}

計算精確搜索的權(quán)重

/**
 查詢模糊搜索的權(quán)重

 @param item 模糊搜索的字符串
 @return 權(quán)重
 */
- (NSUInteger)fuzzySearchLevelTagWithItem:(GBSortSearchCountryItem *)item {
    NSUInteger count = 0; // 權(quán)重
    NSUInteger quertCharactersLocation = 0; // 查詢字符串所在的位置
    NSString *itemText = item.text; // 需要查找的字符串
    while (quertCharactersLocation < item.text.length) {
        // 當(dāng)字符串查找完畢跳出循環(huán)
        NSString *character = [item.text substringWithRange:NSMakeRange(quertCharactersLocation, 1)]; // 截取查找的字符
        NSRange range = [itemText rangeOfString:character]; // 查找字符所在字符串的位置
        if (range.location == NSNotFound) {
            // 如果沒有找到跳出方法
            return NSNotFound;
        }
        count += range.location; // 計算權(quán)重
        quertCharactersLocation ++; // 進(jìn)行下一個字符查找
        itemText = [itemText substringFromIndex:quertCharactersLocation]; // 過濾剩下的字符串 可以根據(jù)輸入順序查找
    }
    return count;
}

模糊搜索的權(quán)重

/**
 對搜索出來的結(jié)果進(jìn)行排序

 @param list 列表
 @return 根據(jù)權(quán)重排序之后的列表
 */
- (NSArray<GBSortSearchCountryItem *> *)sortWithList:(NSArray<GBSortSearchCountryItem *> *)list {
    NSMutableArray *sortList = [NSMutableArray arrayWithArray:list];
    [sortList sortUsingComparator:^NSComparisonResult(GBSortSearchCountryItem *  _Nonnull obj1, GBSortSearchCountryItem * _Nonnull obj2) {
        if (obj1.levelTag > obj2.levelTag) {
            // 如果權(quán)重高就排在最后
            return NSOrderedDescending;
        }else if (obj1.levelTag < obj2.levelTag) {
            // 權(quán)重低就排在最前面
            return NSOrderedAscending;
        }else {
            // 權(quán)重一樣
            if (obj1.text.length > obj2.text.length) {
                // 字符串長的排在后面
                return NSOrderedDescending;
            }else if (obj1.text.length < obj2.text.length) {
                // 字符串短的排在前面
                return NSOrderedAscending;
            }else {
                // 一樣就相等
                return NSOrderedSame;
            }
        }
    }];
    return sortList;
}

根據(jù)權(quán)重進(jìn)行排序

我們進(jìn)行測試纳猫。

    NSArray *array = @[@"abcd",@"1abcd",@"abcd1",@"ab1cd",@"1ab2cd",@"abdc"];
    GBSortSearchCountryManger *manger = [[GBSortSearchCountryManger alloc] init];
    manger.searchResult = array;
    NSArray *sortList =  [manger sortSearchResultWithSearchText:@"abcd"];
    [sortList enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSLog(@"->>>%@",obj);
    }];
2016-12-19 13:44:11.578 GearBest[5812:189459] ->>>abcd
2016-12-19 13:44:11.579 GearBest[5812:189459] ->>>abcd1
2016-12-19 13:44:11.579 GearBest[5812:189459] ->>>1abcd
2016-12-19 13:44:11.579 GearBest[5812:189459] ->>>ab1cd
2016-12-19 13:44:11.580 GearBest[5812:189459] ->>>1ab2cd
2016-12-19 13:44:11.580 GearBest[5812:189459] ->>>abdc

上面就是權(quán)重排序算法的實現(xiàn)婆咸。這個算法有點笨拙,如果搜索范圍大一定卡的要命续担,但是對于我們需求只有兩百個國家還可以擅耽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市物遇,隨后出現(xiàn)的幾起案子乖仇,更是在濱河造成了極大的恐慌,老刑警劉巖询兴,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乃沙,死亡現(xiàn)場離奇詭異,居然都是意外死亡诗舰,警方通過查閱死者的電腦和手機警儒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眶根,“玉大人蜀铲,你說我怎么就攤上這事∈舭伲” “怎么了记劝?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長族扰。 經(jīng)常有香客問我厌丑,道長,這世上最難降的妖魔是什么渔呵? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任怒竿,我火速辦了婚禮,結(jié)果婚禮上扩氢,老公的妹妹穿的比我還像新娘耕驰。我一直安慰自己,他們只是感情好类茂,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布耍属。 她就那樣靜靜地躺著,像睡著了一般巩检。 火紅的嫁衣襯著肌膚如雪后室。 梳的紋絲不亂的頭發(fā)上烤蜕,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音,去河邊找鬼肘习。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播舍咖,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锉桑!你這毒婦竟也來了排霉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤民轴,失蹤者是張志新(化名)和其女友劉穎攻柠,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體后裸,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡瑰钮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了微驶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浪谴。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖因苹,靈堂內(nèi)的尸體忽然破棺而出苟耻,到底是詐尸還是另有隱情,我是刑警寧澤扶檐,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布梁呈,位于F島的核電站,受9級特大地震影響蘸秘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蝗茁,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一醋虏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哮翘,春花似錦颈嚼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至艰匙,卻和暖如春限煞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背员凝。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工署驻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓旺上,卻偏偏與公主長得像瓶蚂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宣吱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理窃这,服務(wù)發(fā)現(xiàn),斷路器征候,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法杭攻,類相關(guān)的語法,內(nèi)部類的語法倍奢,繼承相關(guān)的語法朴上,異常的語法,線程的語...
    子非魚_t_閱讀 31,622評論 18 399
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,233評論 0 4
  • 1.能量的第一個層級卒煞,叫做「外求」: 一直活在物質(zhì)的世界里痪宰,一輩子被物質(zhì)假象迷惑所困,全部精力去追求財富名利和欲望...
    近知閱讀 445評論 0 0
  • 多半秋緒 半步的燭火席虜了一城的風(fēng)畔裕,摻織著椰黃落葉的柔情衣撬,像是訴訴低喃。香秋序冬扮饶,多半是相思蜜友的起引具练。彎彎慨月,...
    眠西閱讀 187評論 0 0