内容
1.链表匹配问题
2.和谐词汇
3.过滤注释
4.拆分链表
1.链表匹配问题
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct node
{
int data;
struct node* next;
}Lnode, *Linklist;
//创建链表
Linklist Create()
{
int n;
Linklist headPtr=NULL,lastPtr=NULL,curPtr=NULL;
scanf("%d",&n);
while(n!=-1)
{
curPtr=(Linklist)malloc(sizeof(Lnode));
if(curPtr!=NULL)
{
curPtr->data=n;
if(headPtr==NULL)
{
headPtr=curPtr;
lastPtr=curPtr;
}
else
{
lastPtr->next=curPtr;
lastPtr=curPtr;
}
}
scanf("%d",&n);
}
lastPtr->next=NULL;
return headPtr;
}
//销毁链表
void Destroy(Linklist *headPtr)
{
Linklist ptr;
while(*headPtr!=NULL)
{
ptr=*headPtr;
*headPtr=(*headPtr)->next;
free(ptr);
}
}
//查找值为value的第一个节点,返回指针,失败返回NULL
Linklist find(Linklist headPtr, int value)
{
Linklist firstPtr = headPtr;
while ( firstPtr != NULL && firstPtr->data != value )
firstPtr = firstPtr->next;
return firstPtr;
}
int JudgeSub(Linklist headAPtr,Linklist headBPtr)
{ //返回值0,说明B不是A的连续子序列;为1,说明是;
Linklist curPtr,changedAPtr,curBPtr;
curBPtr=headBPtr;
int flag;//falg为0,说明B不是A的连续子序列;为1,说明是
//changedAPtr=headAPtr;
while(headAPtr!=NULL)
{
curPtr=find(headAPtr,curBPtr->data);
//printf("%d",curBPtr->data);
if(curPtr==NULL)
return 0;
else
{
headAPtr=curPtr;
flag=1;
for(;curBPtr!=NULL&&curPtr!=NULL;curBPtr=curBPtr->next,curPtr=curPtr->next)
if(curBPtr->data!=curPtr->data)
{
flag=0;
break;
}
}
if(flag==1&&curBPtr!=NULL) //A和B中有匹配项,但是A已经结束了,B仍未结束的情况
return 0;
else if(flag==1&&curBPtr==NULL)
return 1;
else if(flag==0)
{
//注意重新更新的地方
headAPtr=headAPtr->next;
curBPtr=headBPtr;
}
}
return flag;
}
int main()
{
Linklist headAPtr,headBPtr;
int i;
headAPtr=Create();
headBPtr=Create();
i=JudgeSub(headAPtr,headBPtr);
if(i==1)
printf("ListB is the sub sequence of ListA.");
else if(i==0)
printf("ListB is not the sub sequence of ListA.");
Destroy(&headAPtr);
Destroy(&headBPtr);
}
/*要注意的问题:
1. A:4,5,6,9
B:6,9,8,7
有相匹配的地方,但是到A结束时,B还没有结束
2.A:4,5,6,3,2,1,8
B:4,6,3
B中的元素都在A中出现,但是并不是连续的子序列
2.和谐词汇
//需要注意的是,这个单词可能是和谐词汇或者包含和谐词汇
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int GetLen(char *str) //计算字符串的长度
{
int i=0;
while(str[i]!='\0'&&str[i]!='\n')
{
i++;
}
return i;
}
char** Save(FILE *fp,int *n)
{
char** str;
int i=0,u=0,v=0;
char s[10];
//分配空间
str=malloc(10*sizeof(char*)); //为str分配空间
for(i=0;i<10;i++)
*(str+i)=malloc(sizeof(s));
while(!feof(fp))
{
fgets(s,sizeof(s),fp); //在字符串末尾自动加上'\0'
i=0;
v=0;
while(s[i]!='\n'&&s[i]!='\0') //此时,读取的字符串最后为'\n'
{
str[u][v]=s[i];
v++;
i++; //注意读取该行的下一个字符
}
str[u][v]='\0'; //最后将字符加上字符串结尾符
u++;
}
*n=u;
return str;
}
//将字符串temp进行是否是和谐词汇的判断和修改
void Modify(char temp[1000],int* i,char** str,int n)
{
int flag=0; //表示是否找到了相应的和谐词汇
int num=0; //num表示当前和谐词汇的长度
int t=0,j=0,ii=*i; //t代表此时temp的对应位置
char tt[10]; //临时建立
for(j=0;j<n&&flag==0;j++) //判断temp与对应的str[j]是否相等
{
num=GetLen(str[j]);
// printf("str[j]=%s,num=%d\n",str[j],num);
if(temp[ii]==str[j][0]&&strlen(temp+ii)>num-1)
{
for(t=0;t<num;t++) //将相应的完全赋给tt
tt[t]=temp[ii+t];
tt[t]='\0'; //注意将字符串结尾改为字符串结束符
// printf("tt=%s\n",tt);
if(strcmp(tt,str[j])==0)
{
flag=1;
printf("!@#$%^&*");
(*i)+=num;
return ;
}
}
}
if(flag==0)
{
printf("%c",temp[ii]);
(*i)++;
return ;
}
}
int main()
{
//将输入的字符串存入某字符指针指向的地址中
char ch[1000]="\0",tt[100]; //用来存储输入的字符串
char** str; //用来存储屏蔽词汇 str[i]是指向字符的指针
int flag=0; //判断是否含有屏蔽词汇
int n=0; //n代表和谐词汇的个数
int i=0,j=0;
// scanf("%s",ch); //问题,该函数只能将空白(空格,tab,换行符等)之前的字符存入ch中
// gets(ch); //遇到换行符或者EOF才停止
//
while(gets(tt)!=NULL)
{
if(strlen(tt)==0) //测字符串长度,长度为0结束
break;
strcat(ch,tt);
strcat(ch,"\n");
}
// printf("ch:%s\n",ch);
FILE *fp;
if((fp=fopen("dict.dic","r"))==NULL)
{
printf("can't open the file\n");
return 0;
}
//将屏蔽词汇存入str[]中
str=Save(fp,&n);
/* printf("Save over\n");
for(i=0;i<n;i++)
printf("%s\n",str[i]); */
while(ch[i]!='\0') //在字符串读取结束之前
{
//进行比对
Modify(ch,&i,str,n); //输入不同的ch字符串,并且修改i的数值
}
fclose(fp);
return 0;
}
3.过滤注释
#include<stdio.h>
void ClrAndPrt(FILE *fp,int m,int n) //在指定文件中去除指定行数的注释代码,并且输出
{
int i,j;
char ch;
char s[100];
int flag=0; //flag=0表示此时遇到的代码不是在注释中,flag=1表示遇到的代码在注释
for(i=1;i<m;i++)
{
fgets(s,sizeof(s),fp);
}
//fp现在为第m行开头的指针
for(i=m;i<=n;i++)//当指针未达到该停留的行数的时候
{
flag=0;
j=0;
fgets(s,sizeof(s),fp);//读取一行数据,进行分析
// printf("i am seeing you:%s\n",s);
//空行的单独分析
if(s[0]=='\n')
printf("\n");
else
{
for(j;s[j]!='\n'&&flag!=1;j++)
{
if(s[j]=='/'&&s[j+1]=='/')//过滤单行注释
{
flag=2; //单行注释过滤结束
printf("\n");
break;
}
else if(s[j]=='/'&&s[j+1]=='*')//读取多行注释
{
flag=1;
j+=2;
loop:
while(s[j]!='\n')//没有换行之前
{
if(s[j]=='*'&&s[j+1]=='/')
{
flag=3; //多行注释过滤结束
//j+=2;
j+=1;
// printf("s[j+1]=%c\n",s[j+1]);
break;
}
j++;
}
//如果注释结束
/* if(flag==3)//直接输出换行存在问题
{
printf("\n");
// break;
} */
//注释里碰到换行符
if(s[j]=='\n'&&flag==1)
{
i++; //行数增加
fgets(s,sizeof(s),fp); //进入下一行代码
// printf("i am seeing you in error:%s\n",s);
j=0;
if(i>n)
return ;
goto loop;
}
}
else
printf("%c",s[j]);
}
if(s[j]=='\n'&&flag!=1)
printf("\n");
}
}
return ;
}
int main()
{
FILE *fp;
int n,ch,i=0;
int a[5]={0}; //用于存储前5行的数字
if((fp=fopen("dict.dic","rt"))==NULL)
{
printf("can't open the file\n");
return 0;
}
scanf("%d",&n); //表示去除第n段的代码
for(i=0;i<5;i++)
{
ch=fgetc(fp);//从文件中读取一个数字,存入ch中
while(ch!='\n') //当没有换行的时候
{
a[i]=a[i]*10+ch-'0';
ch=fgetc(fp);
}
// printf("a[%d]=%d\n",i,a[i]);
}
rewind(fp); //将文件指针还原到文件开头位置
if(n==1)
ClrAndPrt(fp,6,a[0]);
else
ClrAndPrt(fp,a[n-2]+1,a[n-1]);
return 0;
}
4.拆分链表
题目:
将链表拆分成字母的A链表和数字的B链表和其他的C链表;
解决:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct lnode
{
char data;
struct lnode* next;
}Lnode,*Linklist;
//创建链表
Linklist Create()
{
char ch[4];
Linklist headPtr=NULL,lastPtr=NULL,curPtr=NULL;
scanf("%s",ch); //该函数遇到回车或空格输入结束,并自动将输入的字符串结束符'\0'输入数组中
if(strcmp(ch,"-1")==0)
{
return headPtr;
}
//建立带有头结点的链表
while(strcmp(ch,"-1")!=0)
{
curPtr=(Linklist)malloc(sizeof(Lnode));
if(curPtr!=NULL)
{
curPtr->data=ch[0]; //给curPtr->data赋值
if(headPtr==NULL)
{
headPtr=(Linklist)malloc(sizeof(Lnode));
headPtr->next=curPtr;
lastPtr=curPtr;
}
else
{
lastPtr->next=curPtr;
lastPtr=curPtr;
}
}
scanf("%s",ch);
}
lastPtr->next=NULL;
return headPtr;
}
void Print(Linklist headPtr,char a)
{
//输出链表A的元素
Linklist curptr;
curptr=headPtr->next;
if(curptr==NULL)
printf("There is no item in %c list.\n",a);
else
{
printf("The list %c is: ",a);
while(curptr->next!=NULL)
{
printf("%c ",curptr->data);
curptr=curptr->next;
}
printf("%c\n",curptr->data);
}
}
//销毁链表
void Destroy(Linklist *headPtr)
{
Linklist ptr;
ptr=(*headPtr)->next;
while((*headPtr)!=NULL)
{
ptr=*headPtr;
*headPtr=(*headPtr)->next;
free(ptr);
}
}
void Sort(Linklist *headPtr) //选择排序算法 /将这里完全改成 Linklist *headPtr也都可以
{
Linklist AprePtr,BprePtr,APtr,BPtr,temPtr;
//APtr和BPtr是需要交换的两个指针,BPtr是未排序的部分中数据最小的结点
//AprePtr和BprePtr是分别指向APtr和BPtr的前一个结点的指针
//temPtr是临时创建的指针
int i=0;
AprePtr=*headPtr;
APtr=(*headPtr)->next;
if(APtr==NULL) //考虑链表为空的情况
return ;
while(APtr->next!=NULL)
{
// printf("the layer 1\n");
temPtr=APtr;
BprePtr=AprePtr;
BPtr=APtr;
while(temPtr->next!=NULL)
{
//及时更改BPtr、BprePtr的位置,使其指向未确定结点当中值最小的结点
if((temPtr->next->data)<(BPtr->data))
{
BprePtr=temPtr;
BPtr=BprePtr->next;
}
temPtr=temPtr->next;
}
//将APtr与BPtr交换
// printf("the layer 2\n");
if(APtr!=BPtr)
{
if(APtr->next!=BPtr) //如果A和B结点相邻
{
temPtr=BPtr->next;
BPtr->next=APtr->next;
AprePtr->next=BPtr;
BprePtr->next=APtr;
APtr->next=temPtr;
}
else //如果A和B结点不相邻
{
temPtr=BPtr->next;
AprePtr->next=BPtr;
BPtr->next=APtr;
APtr->next=temPtr;
}
}
AprePtr=AprePtr->next;
APtr=AprePtr->next;
}
}
void Change(Linklist* headPtr,Linklist* headAPtr,Linklist* headBPtr,Linklist* headCPtr)
{
; //分别建立链表A,B,C的头结点
Linklist curPtr,temPtr,curAPtr=NULL,curBPtr=NULL,curCPtr=NULL;
curPtr=(*headPtr)->next;
*headAPtr=(Linklist)malloc(sizeof(Lnode));
*headBPtr=(Linklist)malloc(sizeof(Lnode));
*headCPtr=(Linklist)malloc(sizeof(Lnode));
curAPtr=*headAPtr;
curBPtr=*headBPtr;
curCPtr=*headCPtr;
while(curPtr!=NULL)
{
temPtr=curPtr->next;
if((curPtr->data>='A'&&curPtr->data<='Z')||(curPtr->data>='a'&&curPtr->data<='z')) //字母的情况
{
// printf("字母:%c\n",curPtr->data);
curAPtr->next=curPtr;
curPtr->next=NULL; //已经将每次链表A,B,C尾结点指向NULL了
curPtr=temPtr;
curAPtr=curAPtr->next;
}
else if(curPtr->data>='0'&&curPtr->data<='9')
{
// printf("数字:%c\n",curPtr->data);
curBPtr->next=curPtr;
curPtr->next=NULL;
curPtr=temPtr;
curBPtr=curBPtr->next;
}
else
{
// printf("其他:%c\n",curPtr->data);
curCPtr->next=curPtr;
curPtr->next=NULL;
curPtr=temPtr;
curCPtr=curCPtr->next;
}
}
//考虑没有元素的情况
if(curAPtr==(*headAPtr))
(*headAPtr)->next=NULL;
if(curBPtr==(*headBPtr))
(*headBPtr)->next=NULL;
if(curCPtr==(*headCPtr))
(*headCPtr)->next=NULL;
Sort(headAPtr);
Sort(headBPtr);
Sort(headCPtr);
Print(*headAPtr,'A');
Print(*headBPtr,'B');
Print(*headCPtr,'C');
Destroy(headAPtr);
Destroy(headBPtr);
Destroy(headCPtr);
}
int main()
{
Linklist LPtr,headAPtr,headBPtr,headCPtr;
LPtr=Create();
// Print(LPtr,'L');
if(LPtr==NULL)
{
printf("There is no item in A list.\n");
printf("There is no item in B list.\n");
printf("There is no item in C list.\n");
return 0;
}
Change(&LPtr,&headAPtr,&headBPtr,&headCPtr);
Destroy(&LPtr);
return 0;
}