IOS菜鸟的所感所思(十一)——统计文本中单词出现的次数并按照次数高低排序

来源:互联网 发布:浙江省网络文化节 编辑:程序博客网 时间:2024/05/17 00:13

目标:统计一个txt文本中单词出现的频率,并且按照其出现次数的高低排序

这是我们在上数据结构时,老师留给我们的学科的大作业,当然会用到算法还有数据结构之类的知识了。
每个语言都会用到数据结构和算法,所以这个作业我就准备用IOS来写了

步聚:

1.创建一个空得工程项目DataStructWork
2.细化目标:

a.需要一个有单词的txt文件,并且可以把它放在当前工程的路径下(当然你也可以放在其沙盒路径下)
b.那么你可以创建一个继承NSObject的类FileContent用于把文件中的数据写入程序中来
c.在FileContent.h文件中写一个共有的api,用于把文件中的内容全部传给NSString的对象
具体实现:

//确认我放英文文件的目录下又该文件,

- (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 = [NSFileHandlefileHandleForReadingAtPath: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

说明:这里的代码和之前控制器的差不多就不作过多的解释了。

效果:




这样我们就完成了作业中要求的。


下载完整代码请点击:点击打开链接





0 0
原创粉丝点击