1、查找子串
本题要求实现一个字符串查找的简单函数。
输入:输入两个字符串s、t
输出:输出子串t在s中的首地址pos
优化目标:提高效率
#include <stdio.h>
#include <string.h>
#define MAXS 30
char *search(char *s, char *t);
void ReadString( char s[] ); /* 裁判提供,细节不表 */
int main()
{
char s[MAXS], t[MAXS], *pos;
ReadString(s);
ReadString(t);
pos=search(s, t);
if ( pos!= NULL )
printf("%d\n", pos-s);
else
printf("-1\n");
return 0;
}
char *search(char *s,char *t){
int i=0,j=0,l;
while(s[i]!='\0'&&t[j]!='\0'){
if(s[i]==t[j]){//相等则后移
++i;
++j;
}
else
i=i-j+1;j=0; //子串从下标0重新开始比,主串来到下一个位置
}
if(j==strlen(t)){//子串被遍历完
l=i-strlen(t);
return s+l;//定位子串
}
else
return NULL;
}
ps:这种方法比昨天写的方法效率高一点,昨天采用了暴力枚举的思想。还想对它进行改进的话,就是采用kmp算法。
2、奇数值结点链表
本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表。
输入:输入一系列正整数,按照读入顺序建立单链表L。
输出:分别输出奇数值结点组成的新链表Odd以及旧链表L的序列
优化目标:无
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
struct ListNode *readlist();
struct ListNode *getodd( struct ListNode **L );
void printlist( struct ListNode *L )
{
struct ListNode *p = L;
while (p) {
printf("%d ", p->data);
p=p->next;
}
printf("\n");
}
int main()
{
struct ListNode *L, *Odd;
L=readlist();
Odd=getodd(&L);//可在函数内改变L的值
printlist(Odd);
printlist(L);
return 0;
}
链表不带头结点:
struct ListNode *readlist()//尾插法
{
int data;
struct ListNode *head=NULL; //头节点为空
struct ListNode *p;
while(scanf("%d",&data)&&data!=-1)
{
struct ListNode *q=(struct ListNode*)malloc(sizeof(struct ListNode));
q->data=data;
q->next=NULL;//不要忘记了
if(head==NULL)
head=p;
else {
p->next=q; //添加到末尾
}
p=q; //尾指针往后走
}
return head; //返回头节点
}
//不带头结点的单链表奇数结点分离组成新链表
struct ListNode *getodd( struct ListNode **L ) //二级指针
{
struct ListNode *head0=NULL,*head1=NULL,*p0,*p1;
while((*L)!=NULL)
{
int data=(*L)->data;
struct ListNode *q=(struct ListNode*)malloc(sizeof(struct ListNode));//创建新结点
if(data%2)//奇数结点插入新链表head1
{
q->data=data;
q->next=NULL;
if(head1!=NULL)
{
p1->next=q;
}
else head1=q;//,头指针为空时,将头指针指向第一个节点
p1=q; //尾指针后移
}
else//偶数结点插入新链表head0
{
q->data=data;
q->next=NULL;
if(head0!=NULL)
p0->next=q;
else head0=q;
p0=q;
}
*L=(*L)->next; //继续遍历下一个结点
}
*L=head0; // L中存储的地址改为删除了奇数值结点后的链表的头结点地址
return head1; //返回奇链表head1
}
链表带头结点:
struct ListNode *readlist()//尾插法
{
int data;
struct ListNode *head,*p;
head=(struct ListNode*)malloc(sizeof(struct ListNode));
head->next=NULL; //创建头结点
p=head;
while(scanf("%d",&data)&&data!=-1)
{
struct ListNode *q=(struct ListNode*)malloc(sizeof(struct ListNode));
q->data=data;
q->next=NULL;
p->next=q; //末尾插入
p=q;
}
return head; //返回头节点
}
struct ListNode *getodd( struct ListNode **L ) //二级指针
{
struct ListNode *head0,*head1,*p0,*p1;
head0=(struct ListNode*)malloc(sizeof(struct ListNode));//奇数结点链表
head1=(struct ListNode*)malloc(sizeof(struct ListNode));//偶数结点链表
head0->next=NULL;
head1->next=NULL;
p0=head0;
p1=head1;
while(((*L)->next)!=NULL)//从第一个结点开始遍历
{
int data=((*L)->next)->data;
struct ListNode *q=(struct ListNode*)malloc(sizeof(struct ListNode));
if(data%2)
{
q->data=data;
q->next=NULL;
p1->next=q;
p1=q;
}
else
{
q->data=data;
q->next=NULL;
p0->next=q;
p0=q;
}
*L=(*L)->next;
}
*L=head0;
return head1;
}
总结:今天练习了一些pta的题,并且把之前练习的内容复习完了,明天计划对重要的内容如链表和排序进行针对性复习。