iOS面試必問的一道面試題

前言

最近面試了幾家公司, 我總結(jié)出來了兩點(diǎn)與大家共勉, 該文章就是圍繞以下兩點(diǎn)開展:

  • 個(gè)人發(fā)展和工資想更上一層樓, 必須熟悉算法和數(shù)據(jù)結(jié)構(gòu)
  • 程序員的英文水平很重要

1.出乎我所料的很多公司都問到了有關(guān)topK的問題. 所謂topK問題就是在海量數(shù)據(jù)中, 找到頻率最高的K個(gè)數(shù)據(jù).例如在淘寶中選擇'價(jià)格由高到低' , 就會(huì)在所有相關(guān)的物品中把價(jià)格最高的前K個(gè)展示給用戶.
一般topK問題會(huì)使用堆(heap)和快速排序, 面試時(shí)答上來這兩點(diǎn), 基本就已經(jīng)滿足面試官想要的回答了.使用OC的實(shí)現(xiàn)代碼我會(huì)在下面講解.但是我有一點(diǎn)愚見,OC因?yàn)檎Z(yǔ)言的局限性, 可能不適用于上億數(shù)據(jù)的搜索和排序, 但是在萬(wàn)級(jí)別的topK中效率也是很高的
2.強(qiáng)烈給大家安利一個(gè)我最近在用的背單詞神器墨墨背單詞, 這個(gè)App最吸引我的是可以自定義文本題詞. 我之前再用扇貝和百詞斬的時(shí)候, 推送給我的單詞百分之80對(duì)我現(xiàn)在的工作沒有意義. 但是墨墨可以自定義想背的單詞, 可是如何獲取到有效的單詞呢. 我在閱讀英文文檔的時(shí)候, 會(huì)把不會(huì)的單詞寫入墨墨中. 可是一個(gè)一個(gè)查找效率低, 所以我寫了一個(gè)計(jì)算文本中所有單詞的頻率, 并按頻率大小進(jìn)行排序的工具.源碼已經(jīng)上傳到Github, 方便大家進(jìn)行理解.

正文

1.效果展示

將txt文本的內(nèi)容進(jìn)行展示


文本展示

計(jì)算單詞頻率并按需求排序

人往高處走, 水往低處流.

2.代碼講解

使用NSFileManager和NSFileHandle獲取txt的文字內(nèi)容

- (NSString *)getWordData
{
    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"word" ofType:@"txt"];
    
    if ([manager fileExistsAtPath:filePath]) {
        NSString *str = [self getStringFrom:filePath];
        return str;
    } else {
        [NSException raise:NSGenericException format:@"word.txt did not exist in filePath"];
        return nil;
    }
}

- (NSString *)getStringFrom:(NSString *)filePath
{
    NSString *txtStrings = nil;
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
    if (fileHandle != nil) {
        NSData *wordData = fileHandle.availableData;
        txtStrings = [[NSString alloc] initWithData:wordData encoding:NSUTF8StringEncoding];
    }
    [fileHandle closeFile];
    return txtStrings;
}

使用NSCharacterSet對(duì)英文內(nèi)容進(jìn)行處理, 拆分出每一個(gè)英文單詞, 使用NSPredicate去空

- (NSArray *)getWordArray
{
    NSString *txtStrings = [self getWordData];
    NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@", . ; ( ) : — \n-"];
    NSArray *originalWordArray = [txtStrings componentsSeparatedByCharactersInSet:characterSet];

    //使用謂語(yǔ)對(duì)數(shù)據(jù)進(jìn)行去空, 使用forin對(duì)數(shù)組進(jìn)行遍歷去空雖然也行, 但是使用謂語(yǔ)性能更好
    NSArray *noBlankArray = [originalWordArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self <> ''"]];
    return noBlankArray;
}

計(jì)算每一個(gè)單詞的頻率, 并將結(jié)果保存到字典中. key為單詞, value為單詞的頻率. 判斷是否支持大小寫敏感
我曾經(jīng)看過一篇技術(shù)文章, forin是iOS中遍歷性能最高的一個(gè)函數(shù). 使用雙層遍歷. 外層遍歷每一個(gè)單詞, 內(nèi)層遍歷計(jì)算該單詞的頻率.
有一種特殊的情況, 如果一個(gè)單詞文檔中包含100個(gè)heap單詞和100stack單詞, 這種情況如果外層遍歷仍然遍歷200次的話, 那么性能極差.所以我用了一行代碼來優(yōu)化這個(gè)算法: [tempArray removeObject:word];. 這行代碼會(huì)將計(jì)算過頻率的單詞從元數(shù)組中刪除, 所以優(yōu)化后的代碼的外層循環(huán)只會(huì)循環(huán)兩次. 時(shí)間復(fù)雜度沒有變, 但是N(優(yōu)) < N(原), 在乘以內(nèi)層遍歷的所需的時(shí)間, 性能差別就很明顯了.

- (NSMutableDictionary *)getWordFrequencyDictIsCaseSensitive:(BOOL)isCaseSensitive
{
    NSArray *wordArray = [self getWordArray];
    NSMutableArray *originalArray = [wordArray mutableCopy];
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    NSMutableArray *tempArray = [originalArray mutableCopy];
    NSInteger times = 0;
 

    for (NSInteger i = 0; i <= originalArray.count; i++) {

        i = 0;
        NSString *compareWord = originalArray[i];
        NSInteger count = 0;
        for (NSString *word in originalArray) {
            
            if (isCaseSensitive == YES) {
                if ([compareWord isEqualToString:word]) {
                    count += 1;
                    times += 1;
                    [tempArray removeObject:word];
                }
            } else {
                if ([compareWord caseInsensitiveCompare:word] == NSOrderedSame) {
                    count += 1;
                    times += 1;
                    [tempArray removeObject:word];
                }
            }
        }

        originalArray = [tempArray mutableCopy];
        dict[compareWord] = [NSString stringWithFormat:@"%zd", count];
        NSLog(@"%計(jì)算次數(shù)zd>>>>>", times);
    }
    return dict;
}

排序本來想用快排來實(shí)現(xiàn), 可是在數(shù)據(jù)量不是很多的. 用系統(tǒng)自帶的排序方法性能會(huì)更好.
排序前需要了解NSComparisonResult, 它是一個(gè)枚舉類型, 有三個(gè)成員變量.

  • NSOrderedAscendingThe left operand is smaller than the right operand. 左邊的操作對(duì)象小于右邊的
  • NSOrderedSameThe two operands are equal.兩個(gè)操作對(duì)象相同
  • NSOrderedDescendingThe left operand is greater than the right operand.左邊的操作對(duì)象大于右邊的操作對(duì)象

排序

- (NSArray *)getSortKeysFromDictionary:(NSMutableDictionary *)dictionary withSortType:(SortType)type
{
    NSMutableDictionary *dict = dictionary;
    NSArray *sortArray = [dict keysSortedByValueUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        if ([obj1 integerValue] > [obj2 integerValue]) {
            if (type == KLowerType) {
               return (NSComparisonResult)NSOrderedAscending;
            } else {
               return (NSComparisonResult)NSOrderedDescending;
            }
        }
        if ([obj1 integerValue] < [obj2 integerValue]) {
            if (type == KLowerType) {
                return (NSComparisonResult)NSOrderedDescending;
            } else {
                return (NSComparisonResult)NSOrderedAscending;
            }
        }
        return (NSComparisonResult)NSOrderedSame;
    }];
    return sortArray;
}

結(jié)尾

以上就是我的代碼. 因?yàn)槲蚁嘈糯蠹业乃蕉己芨? 就沒有講的很細(xì). 想深入了解的話, 可以看我的源碼歡迎大家fork and pull requests, 因?yàn)閭€(gè)人水平所限, 性能還可以在提升, 如果pull request被我接受, 我會(huì)發(fā)一個(gè)6.66的紅包表示感謝的~~~
希望大家能通過我的這篇文章有一些收貨.在職的努力提高英文水平和算法水平, 找工作的可以找到理想的工作,
加油

                2017夏天的某一天于家中
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荸型,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡炸茧,警方通過查閱死者的電腦和手機(jī)帆疟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宇立,“玉大人踪宠,你說我怎么就攤上這事÷栲冢” “怎么了柳琢?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我柬脸,道長(zhǎng)他去,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任倒堕,我火速辦了婚禮灾测,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘垦巴。我一直安慰自己媳搪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布骤宣。 她就那樣靜靜地躺著秦爆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪憔披。 梳的紋絲不亂的頭發(fā)上等限,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音芬膝,去河邊找鬼望门。 笑死,一個(gè)胖子當(dāng)著我的面吹牛锰霜,可吹牛的內(nèi)容都是我干的筹误。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼锈遥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼纫事!你這毒婦竟也來了勘畔?” 一聲冷哼從身側(cè)響起所灸,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炫七,沒想到半個(gè)月后爬立,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡万哪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年侠驯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奕巍。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吟策,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出的止,到底是詐尸還是另有隱情檩坚,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站匾委,受9級(jí)特大地震影響拖叙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赂乐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一薯鳍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挨措,春花似錦挖滤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至担租,卻和暖如春砸民,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背奋救。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工岭参, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尝艘。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓演侯,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親背亥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秒际,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,737評(píng)論 25 707
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法狡汉,內(nèi)部類的語(yǔ)法娄徊,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法盾戴,線程的語(yǔ)...
    子非魚_t_閱讀 31,598評(píng)論 18 399
  • 從不奢求著什么,因?yàn)榕陆o他的壓力太大衅斩,也給自己最后的失望畫上未完待續(xù)的省略號(hào)盆顾。有時(shí)候真的這樣甘心過,也許這一世畏梆,我...
    a_u_love閱讀 233評(píng)論 0 0
  • 一、虛擬存儲(chǔ)技術(shù) 所謂虛擬存儲(chǔ)技術(shù)是指:當(dāng)進(jìn)程運(yùn)行時(shí)蚕涤,先將其一部分裝入內(nèi)存筐赔,另一部分暫留在磁盤,當(dāng)要執(zhí)行的指令或訪...
    yjaal閱讀 3,517評(píng)論 0 6
  • 先講個(gè)故事,是關(guān)于我身邊的一位哎呀小姐的成長(zhǎng)史天吓。 之所以這么稱呼她贿肩,是因?yàn)樗率露紩?huì)以抱怨的情緒開始。 記得有一年...
    陳大眼兒閱讀 357評(píng)論 2 2