计导相关问题

内容
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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值