1. 程式人生 > >IOS菜鳥的所感所思(十一)——統計文字中單詞出現的次數並按照次數高低排序

IOS菜鳥的所感所思(十一)——統計文字中單詞出現的次數並按照次數高低排序

//確認我放英文檔案的目錄下又該檔案,

- (NSString *)getFileData{

    //這是放在其沙盒路徑下

//    NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];

//    NSLog(@"The file path is:%@",docDirPath);

//

NSFileManager *fileManager = [NSFileManagerdefaultManager];

//    NSString *filePath = [NSString stringWithFormat:@"%@/wordContents.txt",docDirPath];

//這是放在當前工程的路徑下,你可以下載文字資料來源:點選開啟連結

NSString *filePath = [[NSBundlemainBundle]pathForResource:@"wordContents"ofType:@"txt"];

   NSLog(@"filePath:%@",filePath);

   if([fileManagerfileExistsAtPath:filePath]){

NSLog(@"successful");

       NSDictionary *dic=  [fileManagerattributesOfItemAtPath:filePatherror

:nil];

//判斷該檔案有多大,是否有資料

//NSNumber *fileNum = [dic objectForKey:NSFileSize];

//NSLog(@"fileNum : %f",[fileNum floatValue]);

    }

   return [selfgetData:filePath];

}

//將檔案中的資料以字串的形式在程式碼獲得

- (NSString *)getData:(NSString *)filePath{

   NSString *fileString;

NSFileHandle *fileIn = [NSFileHandlenew];

    fileIn = [NSFileHandle

fileHandleForReadingAtPath:filePath];

   if (fileIn !=nil) {

       NSData *fileContent = [fileInavailableData];

        fileString = [[NSStringalloc]initWithData:fileContentencoding:NSUTF8StringEncoding];

//NSLog(@"The String:%@",fileString);

    }

    [fileIncloseFile];

   return fileString;

}

說明:這裡的NSLog()主要是我在測試的時候用的,看程式是否執行了我期望的操作。

d.這裡我們可以把拿到的string放在手機介面中顯示出來,所以在ViewController.m中

//這裡的wordContent需要關聯

@property (weak, nonatomic) IBOutletUITextView *wordContent;

@property (nonatomic,strong)FileContent *fileContent;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

//初始化兩個物件,以保證可以使用物件中的方法

_fileContent = [FileContentnew];  

    [selfinitTheTextContent];   

}

- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

- (void)initTheTextContent{

   NSString *getFileString = [_fileContentgetFileData];

//將程式碼中的字串在介面中顯示出來

   _wordContent.text = getFileString;

}

現在我們就可以在手機介面中看到本文檔案中的資料了

效果:


e.我們已經拿到了文字中的單詞,現在我們需要做的是將這個NSString的物件拆分個若干個單詞,(其中不需要各種標點符號)這裡我們需要另一個介面api

建立一個類GetMostWord繼承NSObject,共有方法:- (NSArray *)putTheWordIntoArray:(NSString *)fileString;

具體實現:

//獲得字串中的單詞,並放在陣列中,以便於統計

- (NSArray *)putTheWordIntoArray:(NSString *)fileString{

NSCharacterSet *doNotWant = [NSCharacterSetcharacterSetWithCharactersInString:@" ,   -  .  ?  :  “   ”   \n  "];

NSMutableArray *newArray = [NSMutableArraynew];

   NSArray *array = [fileStringcomponentsSeparatedByCharactersInSet:doNotWant];

//去掉陣列中有空格的物件元素

    [arrayenumerateObjectsUsingBlock:^(id obj,NSUInteger idx,BOOL *stop) {

       if([objisEqualToString:@""]){

//NSLog(@"kongge");

        }else{

//重新新增到一個新的陣列中

            [newArrayaddObject:obj];

        }

    }];

//列印輸出經過處理後的陣列

//    [newArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

//        NSLog(@"newArray: %@",obj);

//    }];

   return [selfgetMostWord:newArray];

}

//統計陣列中單詞出現的次數

- (NSArray *)getMostWord:(NSMutableArray *)wordArrays{

//建立一個word的物件,並且用陣列儲存起來,word中有兩個屬性,一個是單詞的名字,

//一個是單詞出現的次數

//這個可變陣列是儲存統計後的word物件

NSMutableArray *wordClassArray = [NSMutableArraynew];

//具體的演算法:將陣列中第0個單詞與後面的從第一個開始進行比較,若相同,則將counter值加一,

//等著內層迴圈完畢之後,就將第0個單詞以及該單詞出現的次數counter去初始化一個word的物件

//並將該物件新增可變陣列wordClassArray中,接著為了讓迴圈次數的減少,就將已經查詢

//的單詞從wordArrays中刪除,並且將counter值設為1,方便下一個單詞的計數。

   NSUInteger counter =1;

   for (int i =0; ;) {

       for (int j = i+1; j < [wordArrayscount]; j++) {

           //

           if ([wordArrays[i]isEqualToString:wordArrays[j]]) {

                counter++;

            }

        }

// NSLog(@"%@,%ld",wordArrays[i],counter);

       WordClass *wordClass = [WordClassnew];

        [wordClassputWord:wordArrays[i]count:counter];

        [wordClassArrayaddObject:wordClass];

        [wordArraysremoveObject:wordArrays[i]];

//當將單詞陣列中元素全部刪除的時候,這時候就可以跳出迴圈體。

       if (wordArrays.count ==0) {

           break;

        }

//        [wordArrays enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

//            NSLog(@" %@",obj);

//        }];

        counter =1;

    }

//這裡是檢驗是否按照設想進行

   for (WordClass *wordClassin wordClassArray) {      

// NSLog(@"wordName:%@,wordCount:%ld",wordClass.wordName,wordClass.WordCounts);     

    }

//這裡是將word物件陣列中的物件按照wordName進行排序

   NSArray *sortedArrayByWordName = [wordClassArraysortedArrayUsingComparator:^NSComparisonResult(WordClass *obj1,WordClass *obj2) {

       return [obj1.wordNamecompare:obj2.wordName];

    }];

//列印輸出看看

   for (WordClass *wordClassin sortedArrayByWordName) {

// NSLog(@"wordName:%@,wordCount:%ld",wordClass.wordName,wordClass.WordCounts);

    }

//返回得到的物件陣列

   return sortedArrayByWordName;

}

說明:程式碼中有詳細的解釋,所以這裡我就不作多得贅敘。當然程式碼中有個WordClass的類,所以你得建立一個WordClass類繼承NSObject

WordClass.h檔案中:

@property (nonatomic,strong)NSString *wordName;

@property (nonatomic)NSUInteger WordCounts;

- (void)putWord:(NSString *)wordString count:(NSUInteger)count;

WordClass.m檔案中:

- (void)putWord:(NSString *)wordString count:(NSUInteger)count{

   self.wordName = wordString;

   self.WordCounts = count;

}

建立完之後,你得#import"WordClass.h"

f.現在我們拿到了物件的陣列(該物件中的屬性有:單詞的名字和單詞出現的次數),這樣我們就可以把陣列中的資料在UITableView檢視中顯示出來,所以接下來得目標就是建立一個UITableView的控制器WordAndCount繼承UITableViewController

具體實現:

WordAndCount.m檔案中:

#import "WordAndCount.h"

#import "FileContent.h"

#import "GetMostWord.h"

#import "WordClass.h"

@interface WordAndCount ()<UITableViewDataSource,UITableViewDelegate>

@property (nonatomic,strong)FileContent *fileContent;

@property (nonatomic,strong)GetMostWord *getWord;

@property (nonatomic,strong)NSArray *getWordCount;

@end

@implementation WordAndCount

- (void)viewDidLoad {

    [superviewDidLoad];

//建立類的物件,方便呼叫其中的fangf

_getWord = [GetMostWordnew];

_fileContent = [FileContentnew];

//呼叫方法獲得文字中的內容

   NSString *getFileString = [_fileContentgetFileData];

//呼叫方法獲得物件陣列

   _getWordCount = [_getWordputTheWordIntoArray:getFileString];

self.tableView.delegate =self;

self.tableView.dataSource =self;

}

- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{

   return1;

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

return_getWordCount.count;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

   staticNSString *myStaticCellIdentifier =@"WordCell";

   UITableViewCell *wordCell = [tableViewdequeueReusableCellWithIdentifier:myStaticCellIdentifier];

   if (wordCell ==nil) {

        wordCell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleSubtitlereuseIdentifier:myStaticCellIdentifier];

    }

//初始化cell的資訊

   WordClass *wordClass =_getWordCount[indexPath.row];

    wordCell.textLabel.text = [NSStringstringWithFormat:@"WordName:%@",wordClass.wordName];

    wordCell.detailTextLabel.text = [NSStringstringWithFormat:@"Count:%ld",wordClass.WordCounts];

    wordCell.detailTextLabel.textColor = [UIColorblueColor];

   return wordCell;

}

@end


g.當然你要在Main.storyboard中新增檢視,它應該是這樣的,第三個檢視我們待會兒會用到

Main.storyboard準備工作弄好後

效果:


說明:該單詞的排序是按照單詞大寫或是小寫的字母排序的。

h.但我們需要的是按照單詞出現的次數進行排序的,所以我們還得在GetMostWord類中寫我們的具體演算法

具體實現:

//我們需要的是將物件陣列中的物件按照單詞出現次數的高低進行排序,所以我們需要重新弄個演算法

//具體演算法:

/*

基本思想還是和上面的那個演算法相似,內層的for迴圈的作用是找出單詞出現次數最多的那個物件,裡層迴圈結束後就將那個物件新增到可變陣列中,再將該物件從物件陣列中刪除(可變陣列和物件陣列是兩個陣列,不要弄出一個去了),這樣就能保證每次迴圈都是找刪除後的最大物件,當然外層迴圈都是從第一個開始(注意for (int j = i; j<wordArrays.count ; j++)而不是j=i+1)當我們的陣列都刪除了,沒有了物件時,這樣我們可以根據wordArrays.count == 0語句跳出外層的迴圈體。

 */

- (NSArray *)sortedArrayByCount:(NSArray *)wordArray{

   NSMutableArray *wordArrays = [NSMutableArrayarrayWithArray:wordArray];

   NSMutableArray *sortedArrayByCount = [NSMutableArraynew];

   for (int i =0;;) {

       WordClass *theMostWord;

       NSInteger max =0;

       for (int j = i; j<wordArrays.count ; j++) {

           WordClass *oneWord = wordArrays[j];

           if (max <= oneWord.WordCounts) {

                max = oneWord.WordCounts;

                theMostWord = wordArrays[j];

            }

        }

//NSLog(@"The most word:%@",theMostWord.wordName);

        [sortedArrayByCountaddObject:theMostWord];

        [wordArraysremoveObject:theMostWord];

       if (wordArrays.count ==0) {

           break;

        }      

    }

   return sortedArrayByCount;

}

說明:這個方法是個共有的方法

h.我們現在拿到了按單詞出現次數的物件排序的陣列了,接著我們可以在WordByCountVC中用這些資料來源了,所以我們需要建立一個繼承UITableViewController的類WordByCountVC

具體實現:

#import "WordByCountVC.h"

#import "FileContent.h"

#import "GetMostWord.h"

#import "WordClass.h"

@interface WordByCountVC ()

@property (nonatomic,strong)FileContent *fileContent;

@property (nonatomic,strong)GetMostWord *getWord;

@property (nonatomic,strong)NSArray *getWordByCount;

@end

@implementation WordByCountVC

- (void)viewDidLoad {

    [superviewDidLoad];

_getWord = [GetMostWordnew];

_fileContent = [FileContentnew];

   NSString *getFileString = [_fileContentgetFileData];

   NSArray *getWordCount = [_getWordputTheWordIntoArray:getFileString];

   _getWordByCount = [_getWordsortedArrayByCount:getWordCount];

}

- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

// Return the number of sections.

   return1;

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

return_getWordByCount.count;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

   staticNSString *myStaticCellIdentifier =@"WordByCountCell";

   UITableViewCell *wordByCountCell = [tableViewdequeueReusableCellWithIdentifier:myStaticCellIdentifier];

   if (wordByCountCell ==nil) {

        wordByCountCell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleSubtitlereuseIdentifier:myStaticCellIdentifier];

    }

   WordClass *wordClass =_getWordByCount[indexPath.row];

    wordByCountCell.textLabel.text = [NSStringstringWithFormat:@"WordName:%@",wordClass.wordName];

    wordByCountCell.detailTextLabel.text = [NSStringstringWithFormat:@"Count:%ld",wordClass.WordCounts];

    wordByCountCell.detailTextLabel.textColor = [UIColorblueColor];

   return wordByCountCell;

}

@end

說明:這裡的程式碼和之前控制器的差不多就不作過多的解釋了。

效果:


這樣我們就完成了作業中要求的。

下載完整程式碼請點選:點選開啟連結