C语言:将txt文件的单词导入链表&&删除链表重复单词
文章目录
前言
主要分为两个实现部分,按个人需求浏览
可以在目录中找到对应位置进行浏览。
1:将文件单词导入链表
2:删除链表重复的单词内容
首先明确几个任务
我们下面用链表存储txt文件中单词作为内容进行去重,学会了这个操作之后应该对其他内容形式的存储也会得心应手,只要修改一下存储的内容形式是什么就可以,主要是代码思想的重要性。
下面的几个任务对应的函数我在文章后面都会详细解释。
①需要一个寻找txt文件中最长单词的函数。
( 可以跳转置下面博客链接,在本篇文章中我就不再赘述了,里面写得比较详细。##如何找到txt文件中最长单词## )
③需要一个导入文件单词函数
④需要一个去除重复单词内容的函数
先过一遍如何操作的流程。
第一步:首先找到文件中最长单词的长度
第二步:按照该长度进行分配空间,就可以把每一个单词都装下
(这个方法比较耗费空间,留白给大家自行优化喔~)
第三步:分配工作完成后就可以直接把文件中的所有单词导入到单链表中
第四步:把单链表中重复的单词删除掉
①全局变量和结构体代码部分
以下是全局变量 ↓
- 如果你不想定义全局变量,那么你需要在函数参数里面添加多几个参数,在用函数的时候把这些变量传进来进行操作,这样也可以实现。
//用于Find_MAXword函数,具体的解释跳转我的另一篇博客
char FindMAXword[50];
/*辅助功能,用来临时存放最长的单词,
因为在函数内部定义想要返回数组就会造成内存泄漏*/
int C_link_len, C_maxword_len;
//存放数组的顺序表的空间大小和最长单词的长度
/*单词单链表*/
struct Wordc{
char *s;
int num;
struct Wordc *next;
};
struct Wordc *L2 = NULL;
②实现:将文件单词导入链表
a: 寻找txt文件中最长单词的函数
b: 导入文件单词函数
#以下用到的函数包含在ctype.h函数里面,用之前记得包含该头文件#
isalpha函数:判断字符是否为函数
isupper函数:判断是否为大写字母
tolower函数:把字母转换为小写字母
具体代码思想:
if 遇到是字母就继续录入,一个一个字符进行录入,进入后如果是大写字母就将该字符进行转换成为小写字母。
start是表示你现在是进行ing录入单词,当遇到不是单词的时候就else if,这里的start就发挥了作用,如果不是等于1的话就不会进入,这样的好处是防止了txt文件中有一些内容根本就不是字母形式,以防录入不必要的信息,进入else if 后首先把start赋值为-1,因为这时候已经是代表一个单词的录入完成了,要对下一个单词进行录入。
接下来就可以正常的进行开辟链表节点空间,这里是基本的尾插法,就不作详细解释了。
比较重要的点: 咱的表头是链表指针,所以传进来的第一个链表参数就必须是二级指针。
void saveword_to_L2(struct Wordc **L2, FILE *fp)//保存到链表中
{
char ch;
struct Wordc *newWord;
struct Wordc *temp = (*L2);
int index = 0, n = 0, start = -1;
while(!feof(fp))
{
ch = fgetc(fp);
if(isalpha(ch))
{
if(isupper(ch))
{
ch = tolower(ch);
}
start = 1;
temp->s[n] = ch;
n++;
}
else if(start == 1)
{
start = -1;
temp->s[n] = '\0';//变成字符串单词
newWord = (struct Wordc*)malloc(sizeof(struct Wordc));
newWord->s = (char*)malloc(sizeof(char)*C_maxword_len+1);//不能漏了这一步
temp->next = newWord;
newWord->next = NULL;
temp = newWord;//移动到尾部
n = 0;
}
}
}
③实现:删除链表重复的单词内容
看我我博客的人看到这个代码块肯定窃喜了,因为这和学生信息的增删的部分代码思想是一模一样的。但是我在这还是要再解释一下哈。
1:首先我们需要一个前趋指针和后继指针,就是分别用来存放链表中某一个节点的前面的空间和后面一个空间的地址,所以叫前趋和后继,很显然,头指针是没有前趋,尾指针没有后继。
2:我们还需要另一个临时指针用来遍历当前位置下,后面的所有链表空间,简单的来说:你在排队的时候你想看看排在你后面的人有没有你认识的,但是你现在在排队肯定不能出来,所以你需要另一个人来帮你看,这个临时指针就起到这样一个作用。
3:上面说排队找朋友,我们这个找肯定就是找到要删除的那个空间节点了,所以下面说一下删除链表节点要注意的事情。
第一点:要先把该删除的空间的前趋和后继先连接起来,因为不能破坏链表的结构,所以pre和cur->next这个前趋后继节点就起到了这样一个作用,接下里就是直接把该位置cur的空间删除掉。
- 记住你删除这个节点后要回到你现在排队的位置,因为你不知道后面还有没有,这个临时指针只能告诉你一个重复的空间。
gt = temp;也就是起到了这样一个作用。*
同样的在传入链表的时候需要传入二级指针。
void Delete_Linklist_recur(struct Wordc **L2)
{
char *ch;
int c = 1;
struct Wordc *temp = (*L2);
struct Wordc *pre;
struct Wordc *cur = temp->next;
struct Wordc *gt;
while(temp!=NULL)
{
gt = temp;
while(gt->next != NULL)
{
pre = gt;
cur = gt->next;
gt = gt->next;
if(strcmp(temp->s,cur->s)==0 )
{
pre->next = cur->next;
free(cur);
gt = temp;
}
}
temp = temp->next;
}
}
结尾
- 这几个函数的具体实现功能大概就是这些,全局变量和结构体这些声明一定不能漏掉,这些是构成函数的基本要素。
(再次叮嘱↓)
- 如果你不想定义全局变量,那么你需要在函数参数里面添加多几个参数,在用函数的时候把这些变量传进来进行操作,这样也可以实现。
本文来自博客园,作者:竹等寒,转载请注明原文链接。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析