题目描述
已知两个由正整数组成的无序序列A、B,每个序列的元素个数未知,但至少有一个元素。你的任务是判断序列B是否是序列A的连续子序列。假设B是“1 9 2 4 18”,A是“33 64 1 9 2 4 18 7”,B是A的连续子序列;假设B是“1 9 2 4 18”,A是“33 1 9 64 2 4 18 7”,B不是A的连续子序列。
要求:
建立两个单链表A、B用于存储两个正整数序列,然后按照题目的要求,判断链表B是否是链表A的连续子序列。正整数的输入用-1作为结束标志,注意-1不算这个正整数序列中的元素(不要统计-1)。在程序结束前要释放链表A、B中的所有节点。
输入
依次输入两个乱序的正整数序列A、B,序列中元素个数未知,但每个序列至少有一个元素,并以输入“-1”结束,每个序列占一行。
输出
如果序列B是序列A的连续子序列,则输出“ListB is the sub sequence of ListA.”,否则输出“ListB is not the sub sequence of ListA.”。
数据最多的测试用例节点数在100这个数量级,所有整数可以用int型存储。
请注意输入输出格式。
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node * nextPtr;
}LISTNODE, * LISTNODEPTR;
void createListHead(LISTNODEPTR *,LISTNODEPTR *);
void insertEnd(LISTNODEPTR *,int);
int isContinuousSubsequence(LISTNODEPTR *,LISTNODEPTR *);
void destroyList(LISTNODEPTR);
int main(){
LISTNODEPTR headPtr1,lastPtr1,headPtr2,lastPtr2;
createListHead(&headPtr1,&lastPtr1);
createListHead(&headPtr2,&lastPtr2);
int value;
scanf("%d",&value);
while(value != -1){
insertEnd(&lastPtr1,value);
scanf("%d",&value);
}
scanf("%d",&value);
while(value != -1){
insertEnd(&lastPtr2,value);
scanf("%d",&value);
}
if(isContinuousSubsequence(&headPtr1,&headPtr2)){
printf("ListB is the sub sequence of ListA.\n");
}
else printf("ListB is not the sub sequence of ListA.\n");
destroyList(headPtr1);
destroyList(headPtr2);
return 0;
}
void createListHead(LISTNODEPTR * headPtrPtr,LISTNODEPTR * lastPtrPtr){
(*headPtrPtr) = malloc(sizeof(LISTNODE));
if((*headPtrPtr) != NULL){
(*headPtrPtr)->nextPtr = NULL;
(*lastPtrPtr) = (*headPtrPtr);
}
else{
printf("Error!");
}
}
void insertEnd(LISTNODEPTR * lastPtrPtr,int value){
LISTNODEPTR newPtr = malloc(sizeof(LISTNODE));
if(newPtr != NULL){
newPtr->data = value;
newPtr->nextPtr = NULL;
(*lastPtrPtr)->nextPtr = newPtr;
(*lastPtrPtr) = newPtr;
}
}
int isContinuousSubsequence(LISTNODEPTR * headPtrPtr1,LISTNODEPTR * headPtrPtr2){//判断是否为连续子序列
int turevalue = 0,flag = 1;//真值默认为零
LISTNODEPTR headPtr1 = (*headPtrPtr1)->nextPtr,headPtr2 = (*headPtrPtr2)->nextPtr;
while(headPtr1 != NULL&&flag){
LISTNODEPTR headPtr1Flag = headPtr1;//将此时刻的头指针暂存在临时变量中
while((headPtr1->data == headPtr2->data)&&(headPtr1->nextPtr != NULL)&&(headPtr2->nextPtr != NULL)){
headPtr1 = headPtr1->nextPtr;
headPtr2 = headPtr2->nextPtr;
}//进行检测循环
if((headPtr1->data == headPtr2->data)&&(headPtr2->nextPtr == NULL)){
turevalue = 1;
flag = 0;
}//最后一个相等且Ptr2已经结束,则为连续子序列,改变标记变量,结束循环
headPtr1 = headPtr1Flag->nextPtr;//ptr1从标记的地方继续
headPtr2 = (*headPtrPtr2)->nextPtr;//ptr2从头开始
}
return turevalue;
}
void destroyList(LISTNODEPTR headPtr){//销毁链表
LISTNODEPTR tempPtr;
while(headPtr != NULL){
tempPtr = headPtr;
headPtr = headPtr->nextPtr;
free(tempPtr);
}
}