**
《程序设计实践》第05练——指针Part(2/2)
- 指针——字符串1
1.1. 学生模拟题:SC6_4B.cpp(本题15分)
【题目描述】 将字符串中的正、负整数取出求和。如字符串“w&sk234 K3wzm3455kdf43dkf-56slk%9” 中正、负整数取出的和=234+3+3455+43-56+9=3688,程序运行后输出3688。
**注意:
(1)需要考虑字符串中出现的正负号(+, -),即所有转换结果为正或负整数。
(2)空格为字符串的有效字符、不能忽略。例如,字符串"-□345.123"(□表示空格)应转换为-0,345,123三个整数,而不是-345和123两个整数!
(3)需要考虑’0’开始的数字字符串情况,比如"00035",应转换为整数35;"000"应转换为整数0;"00.0035"应转换为整数0和35(忽略小数点:mmm.nnn当成两个数mmm和nnn来识别)。
(4)不考虑转换后整数超出范围情况,即测试用例中可能出现的最大整数不会超过unsigned int可处理的范围;
(5)输入字符串不会超过100 Bytes,请不用考虑超长字符串的情况。
打开SC6_4B.cpp文件,完成程序的编写。
【输入】
输入文件SC6_4B.in有1行,一个字符串。
【输出】
输出文件SC6_4B.out有1个整数,是字符串中所有正、负整数的和。
【输入输出样例1】
SC6_4B.in SC6_4B.out
w&sk234 K3wzm3455kdf43dkf-56slk%9 3688
【输入输出样例2】
SC6_4B.in SC6_4B.out
w&- 123sk0400dkf-12.3slk%-876 -362
【数据限制】
0≤字符串长度≤1000;-1010≤输出结果≤1010。
在这里插入代码片
#include "stdio.h"
#include "string.h"
int sumInt( char *s ){
int sum=0, t=0, sign; //sum-正负整数之和; t-字符串中的整数; sign-字符串中的正负号
char *p=s; //p-指向字符串的指针(遍历字符串)
bool inNumber=false; // 用于表示当前*p是否为数字, 默认情况下:不是
//******************************************
while(*p){
if(!inNumber && *p>='0' && *p<='9'){ //(1)由非数字状态转入数字状态
/*(1.1)*/
inNumber = true;
t = 0;
/*(1.2)正负整数 符号控制*/
if(p>s && *(p-1)=='-'){//判断前一个字符是否为'-'
sign = -1;
}else{
sign = 1;
}
}
if(inNumber && (*p < '0' || *p > '9')){ //(2)由数字状态转入非数字状态
inNumber = false;
sum += t * sign;
}
if(inNumber){ //(3)累加当前数字状态的那个整数
t = t*10 + (*p-'0');
}
p++; //(4)字符串序列的下一个'字符'
}
//字符串序列->串尾字符为数字字符(整数)
if(inNumber){
sum += t * sign;
}
//==========================================
return sum;
}
int main(){
char s[1000+1]; //a字符串数组
FILE *fp;
if((fp=fopen("SC6_4B.in", "r")) != NULL ){
fclose(fp); //存在的话,要先把之前打开的文件关掉
freopen("SC6_4B.in", "r", stdin);
freopen("SC6_4B.out", "w", stdout);
}
gets(s); //输入字符串
printf("%d\n", sumInt(s)); //调用函数sumInt(s),并输出字符串中的正、负整数的和
return 0;
}
1.2. 拓展题:SC6_4C.cpp(本题15分)
【题目描述】 求2个大正整数之和。打开SC6_4C.cpp文件,完成程序的编写。
【输入】
输入文件SC6_4C.in有2行,每行是1个大正整数。
【输出】
输出文件SC6_4C.out有1个整数,是上面2个大整数的和。
【输入输出样例1】
SC6_4C.in SC6_4C.out
45656834234234095782376907905623
93890352982340549798035 45656834328124448764717457703658
【输入输出样例2】
SC6_4C.in SC6_4C.out
457830640354181320210024
15499999951351567434165464541155 15500000409182207788346784751179
【数据限制】
0≤数字长度≤500。
【思考与扩展】
(1)两个相加的正整数有符号(正号’+’、负号’-’);
(2)两个大(正负)整数的加、减、乘、除四则运算的实现;
(3)任意两个数字(整数、浮点数)的加、减、乘、除四则运算的实现;
在这里插入代码片
#include "stdio.h"
#include "string.h"
const int N0=500;
int longIntegerSum( char a[], char b[], int c[] ){
char *pa, *pb; //pa,pb-指向两个大正整数字符串序列的指针;
int *pc, len; //pb-指向 两大正整数字之和数组int c[]的指针; len-相加结果的位数
pa=a+strlen(a)-1; // pa指向第一个正整数的最低位
pb=b+strlen(b)-1; // pb指向第二个正整数的最低位
//******************************************
pc = c; //指针pc指向和数组c
int carry = 0; //是否有进位? 1-yes;0-no
while(pa>=a || pb>=b){ //只要还有数位没处理,则一直循环下去.....
if(pa >= a && pb >= b){ //【1】两个加数相应位置上都还有值....
if(carry){ //if(carry==1){ //低位->有进位
if(((*pa-'0') + (*pb-'0') +1 ) > 9 ){ //当前位相加后-->产生进位
*pc = ((*pa-'0') + (*pb-'0') + 1) % 10;
carry = 1;
}else{
*pc = (*pa-'0') + (*pb-'0') + 1; //当前位相加后-->'不'产生进位
carry = 0;
}
}else{ //低位->没有进位
if(((*pa-'0') + (*pb-'0')) > 9 ){ //当前位相加后-->产生进位
*pc = ((*pa-'0') + (*pb-'0')) % 10;
carry = 1;
}else{
*pc = (*pa-'0') + (*pb-'0'); //当前位相加后-->'不'产生进位
carry = 0;
}
}
pa--; //第1个加数往高位移1位
pb--; //第2个加数往高位移1位
pc++; //和指针往后移动1位
}else if(pa < a){ //【2】第1个加数pa较短,已经没值了,只需要累加第2个加数后面的高位....
while(pb >= b){
if(carry == 1){//此位的低1位-->有进位
if( ((*pb - '0')+1) > 9){
*pc = ((*pb - '0')+1) % 10;
carry = 1;
}else{
*pc = *pb - '0' +1;
carry = 0;
}
}else{//没有进位
*pc = *pb - '0';
//carry = 0;
}
pc++; //和指针往后移动1位
pb--; //第2个加数往高位移1位
}
}else if(pb < b){ //【3】第2个加数pa较短,已经没值了,只需要累加第1个加数后面的高位....
while(pa >= a){
if(carry == 1){//此位的低1位-->有进位
if( ((*pa - '0')+1) > 9){
*pc = ( (*pa - '0')+1 ) % 10;
carry = 1;
}else{
*pc = (*pa - '0')+1;
carry = 0;
}
}else{//没有进位
*pc = *pa - '0';
//carry = 0;
}
pc++; //和指针往后移动1位
pa--; //第1个加数往高位移1位
}
}
}
/*(2)求两大整数相加结果的位数*/
len = pc - c;
//==========================================
return len;
}
int main(){
char a[N0+1], b[N0+1]; // 用两个字符数组存放两个加数(大正整数)
int c[N0+5]={ 0 }, *pc, len; // 变量len表示相加结果的位数
// 用一个整型数组存放两数相加的和,c[0]存放最低位,c[len-1]存放最高位
FILE *fp;
if((fp=fopen("SC6_4C.in", "r")) != NULL ){
fclose(fp); //存在的话,要先把之前打开的文件关掉
freopen("SC6_4C.in", "r", stdin);
freopen("SC6_4C.out", "w", stdout);
}
gets(a); //输入第一个加数(大正整数1)
gets(b); //输入第二个加数(大正整数2)
len=longIntegerSum( a, b, c); //调用函数计算a+b的和c, 结果以低位到高位'倒序(反序)'的方式存储在c中
for(pc=c+len-1; pc>=c; pc--){ //输出结果-两个加数(大正整数)之和==>低位到高位'倒序(反序)'存储
printf("%d", *pc);
}
printf("\n");
return 0;
}
- 指针——字符串2
2.1. 学生模拟题:SC6_5B.cpp(本题15分)
**
【题目描述】 在主字符串中删除所有子字符串。打开SC6_5B.cpp文件,完成程序的编写
**。
【输入】
输入文件SC6_5B.in有2行,第1行是主字符串,第2行是子字符串。
【输出】
输出文件SC6_5B.out有1行,即删除所有子字符串后的主字符串。
【输入输出样例1】
SC6_5B.in SC6_5B.out
hyuaaaabcad;dsj2390aaabcadldkaaaaabcaaabcade
aaabcad hyua;dsj2390ldkaaaaabce
hyua;dsj2390ldkaaaaabcaaabcade
【输入输出样例2】注意此例运行结果!
SC6_5B.in SC6_5B.out
123aaaaaaaabcaabcbcaabcbcbcbc567
aabc 123bc567
【输入输出样例3】
SC6_5B.in SC6_5B.out
123aaaaaaaabcaabcbdecaabcbrgcjkaabc
aabc 123aaaaaabdecbrgcjk
【数据限制】
0≤字符串长度≤1000。
在这里插入代码片
#include "stdio.h"
#include "string.h"
const int N0=1000;
char *index( char *s, char *sub ){ //在s中查找sub,找到则返回首字符地址,找不到则返回空(0)
//int i=0, j=0; //i,j-循环控制(游标)变量
char *p=sub; //子字符串
if( *sub=='\0' ) //字符串为空? 若空则非法,退出程序.
return NULL;
//******************************************
while( *s){ //while( *s && ( strlen(s) >= strlen(p) ) ){ //主串非空, 且主串比子串'长',才有搜索的必要
if(*p == '\0'){ //若已达到子串的末尾, 则匹配成功, 在主串中找到子串
//s = s - (p-sub) + 1; //主串指针回退(子串指针移位步长-1)=(p-sub)-1, 进行下一轮搜索
//p = sub; //子串指针p重新回到子串的首部sub
return s - (p-sub); //
}
if( *s == *p ){ //当前字符匹配成功,则子串&主串指针后移一位
s++;
p++;
}else{ //当前字符匹配'不'成功, 子串&主串 回退相应位数
s = s - (p-sub) + 1; //主串指针回退(子串指针移位步长-1)=(p-sub)-1, 进行下一轮搜索
p = sub; //子串指针p重新回到子串的首部sub
}
}
if(*p == '\0'){//子串的
return s - (p-sub);
}else{
return NULL;
}
//==========================================
}
int main(){
char s[N0+1], sub[N0+1], *p, *q; //s[]-主字符串; sub[]-子字符串; p,q-子串在主串中第一次出现的首地址&(尾地址+1)
int sublen; //sublen-子字符串长度
FILE *fp;
if((fp=fopen("SC6_5B.in", "r")) != NULL ){
fclose(fp); //存在的话,要先把之前打开的文件关掉
freopen("SC6_5B.in", "r", stdin);
freopen("SC6_5B.out", "w", stdout);
}
gets(s); //输入主字符串s
gets(sub); //输入子字符串sub
sublen=strlen( sub ); //子字符串长度
while( p=index(s, sub) ) { //若在主串中找到子串, 即p不为空(0)
q = p + sublen; //子字符串(在主字符串中)的结束地址-的下一个位置!
while( *p++=*q++ ); //在s中删除p指向的子串sub--[位置p~(q-1)], 即把q及其之和的字符整体往前挪到p位置.
}
puts(s); //输出 删除所有子字符串后的主字符串。
return 0;
}
2.2. 拓展题:SC6_5C.cpp(本题15分)
【题目描述】 输入3行字符串,分别是s字符串,t字符串和r字符串。如果s字符串中有包含t字符串,则用r字符串替换之。例如:s=“12aaabc3aaaaaabc# %aaabc”,t=“aaabc”,r=“abc”,将s中的“aaabc”替换成“abc”之后,s=“12abc3aabc# %abc”。输出替换之后的s字符串。打开SC6_5C.cpp文件,完成程序的编写。
【输入】
输入文件SC6_5C.in包含有3行字符串,分别是s字符串,t字符串和r字符串。
【输出】
输出文件SC6_5C.out将s字符串中包含的t字符串,用r字符串替换之,输出替换之后的s字符串。
【输入输出样例1】
SC6_5C.in SC6_5C.out
ALKJFOE23DLS67AFAOE
OE
XYZ ALKJFXYZ23DLS67AFAXYZ
【输入输出样例2】
SC6_5C.in SC6_5C.out
12aaabc3aaaaaabc#KaTeX parse error: Expected 'EOF', got '#' at position 28: … abc 12abc3aabc#̲%abc
【数据限制】
0≤字符串长度≤1000。
在这里插入代码片
#include "stdio.h"
#include "string.h"
const int N0=1000;
char *index( char *s, char *sub ){ //在s中查找sub,找到返回首字符地址,找不到返回空
//int i=0, j=0; //i,j-循环控制(游标)变量
char *p=sub; //子字符串
if( *sub=='\0' ) //字符串为空? 若空则非法,退出程序.
return NULL;
//******************************************
while( *s){ //while( *s && ( strlen(s) >= strlen(p) ) ){ //主串非空, 且主串比子串'长',才有搜索的必要
if(*p == '\0'){ //若已达到子串的末尾, 则匹配成功, 在主串中找到子串
//s = s - (p-sub) + 1; //主串指针回退(子串指针移位步长-1)=(p-sub)-1, 进行下一轮搜索
//p = sub; //子串指针p重新回到子串的首部sub
return s - (p-sub); //
}
if( *s == *p ){ //当前字符匹配成功,则子串&主串指针后移一位
s++;
p++;
}else{ //当前字符匹配'不'成功, 子串&主串 回退相应位数
s = s - (p-sub) + 1; //主串指针回退(子串指针移位步长-1)=(p-sub)-1, 进行下一轮搜索
p = sub; //子串指针p重新回到子串的首部sub
}
}
if(*p == '\0'){//子串的
return s - (p-sub);
}else{
return NULL;
}
//==========================================
}
void insStr( char *s, char *r, char *p ){ //往主串s的位置p插入子串r (s中p之后的字符往后挪动)
char *pi, *pj;
//******************************************
/*(0)待插入的字符串非空, 即有发生实际的插入操作! 否则直接跳出,不做插入!*/
if(strlen(r) < 1){
return;
}
/*(1)插入位置p起始 及其之后的所有字符向后移(挪)动---> '插入串r长度strlen(r)' */
pi = s + strlen( s ); //指针pi指向主串s的末尾
//*(pi+strlen(r)) = '\0'; //手动指定新主串s的末尾的字符串结束符
while(pi >= p){ //从主串的末尾到指针p的所有元素,往后挪动strlen(r)个位置
*(pi+strlen(r)) = *pi;
//*pi = ' '; //抹除掉移(挪)位掉的字符信息, 跟踪(显示)输出操作过程时更清楚!
pi--;
}
/*(2)插入串r插入到主串s的指定位置 p*/
pi = p; //pi指向主串s中字符串插入的位置
pj = r; //pj指向插入串r的起始位置
while(*pj != '\0'){ //当插入串非空, 则循环插入...
*pi++ = *pj++;
}
//==========================================
}
int main(){
char s[N0+1], t[N0+1], r[N0+1], *p, *p1, *q; //s,t,r-执行三个字符串的指针; p,p1-子串t在主串s中首次出现的首地址&q为(尾地址+1)
int tlen; //字符串t的长度
FILE *fp;
if((fp=fopen("SC6_5C.in", "r")) != NULL ){
fclose(fp); //存在的话,要先把之前打开的文件关掉
freopen("SC6_5C.in", "r", stdin);
freopen("SC6_5C.out", "w", stdout);
}
gets(s); //输入字符串s
gets(t); //输入字符串t
gets(r); //输入字符串r
tlen=strlen( t ); //字符串t的长度
while( p=p1=index( s, t ) ){ //查找子串t在主串s中的位置p1, 若存在,则
q = p + tlen; //子串t在主串s中的结束位置的-->下一个位置
while( *p++ = *q++ ); //从主串s中删除找到的子串t (s中p~q之间的字符, q之后的字符往前挪)
insStr( s, r, p1 ); //往主串s的位置p1插入子串r (s中p1之后的字符往后挪动)
}
puts(s); //输出字符串s
return 0;
}
- 指针——链表
3.1. 学生模拟题:SC6_6B.cpp(本题20分)
【题目描述】 有2个从小到大已经排序好的(有序)表,每个结点的数据是1个整数,已知两个表的数据存放在带头结点的单向链表中,将2个有序表合并成1个新的有序表,要求新的有序表中去掉重复相同的数据。打开SC6_6B.cpp文件,完成程序的编写
。
【输入】
输入文件SC6_6B.in有4行,第1行有1个整数n,即第1个表的结点数,第2行有n个整数;第3行有1个整数m,即第2个表的结点数,第4行有m个整数。整数之间用空格隔开。
【输出】
输出文件SC6_6B.out有1行,将上述2个表的数据从小到大排序输出,数据中没有相同项,每个整数之后输出1个空格。
【输入输出样例1】
SC6_6B.in SC6_6B.out
6
3 6 11 25 67 84
10
-5 3 8 25 25 43 67 92 96 99 -5 3 6 8 11 25 43 67 84 92 96 99
【输入输出样例2】
SC6_6B.in SC6_6B.out
11
-5 3 8 13 16 25 43 67 92 96 99
8
3 6 11 13 25 67 84 123 -5 3 6 8 11 13 16 25 43 67 84 92 96 99 123
【数据限制】
0≤m, n;1≤m+n;所有数据均为整数。
在这里插入代码片
#include "stdio.h"
const int INF=0x7fffffff; //无穷大整数
struct ND{ //链表节点结构
int data; //链表节点数据: 一个整数
struct ND *next; //指向下一个链表节点的指针
};
ND *createLink( ) { //创建链表, 并返回链表头指针
ND *head, *p; //head-链表头指针; p-遍历链表的链表游标
int n; //链表长度(节点数目)
head = p = new ND; //链表头指针head, 链表游标p指向链表头
scanf("%d", &n); //链表长度(节点数目)
while( n-- ) {
p->next = new ND; //创建1个新的链表节点
p = p->next; //链表游标 -> 后移一个节点
scanf("%d", &p->data); //输入链表节点数据
}
p->next = NULL; //链表最后一个节点指向下一个节点的指针 --> 指向空NULL
return head; //返回链表头指针
}
void printLink( ND *head ) { //打印链表
ND *p = head->next;
if( p==NULL ){ //若链表为空, 直接返回
return ;
}
while( p ) { //逐个打印链表节点上的数据
printf( "%d ", p->data );
p=p->next;
}
printf("\n");
}
void deleteLink( ND *head) { //删除整个链表
ND *p=head;
while( p ) { //若链表节点存在,...
head = p->next; //链表头指针往后移动
delete p; //删除链表节点('新'头指针之前的一个节点)
p = head; //更新当前链表节点指针
}
}
ND * megerLink( ND *ha, ND *hb ){ //合并2有序表,返回合并后链表头结点的地址
ND *pa=ha->next, *pb=hb->next, *hc, *pc; //三个链表的头指针p*(a,b,c)及其链表游标h*(a,b,c)
int data, lastData=INF; //lastData为上一个结点的数据项,用于判定是否有相同数据
hc=pc=new ND; //hc-合并完后的链表的头指针; pc-游标指针,初始时刻指向链表头
//************************************************
while(pa!=NULL || pb!=NULL){ //只要待合并的两个链表其中之一不为空, 则继续进行合并操作
if(pa == NULL){ //若链表1为空, 则合并链表2剩下的所有数据
while(pb){
if(pb->data != lastData){
pc->next = new ND; //创建1个新的链表节点
pc = pc->next; //链表游标 -> 后移一个节点
pc->data = pb->data;
pc->next = NULL;
lastData = pc->data;
}
pb = pb->next;
}
}else if(pb == NULL){//若链表2为空, 则合并链表1剩下的所有数据
while(pa){
if(pa->data != lastData){
pc->next = new ND; //创建1个新的链表节点
pc = pc->next; //链表游标 -> 后移一个节点
pc->data = pa->data;
pc->next = NULL;
lastData = pc->data;
}
pa = pa->next;
}
}else{//(pa != NULL) && (pb != NULL) //两个链表都非空
if(pa->data > pb->data){//pa节点数据>pb节点数据,则先合并pb
if(pb->data != lastData){
pc->next = new ND; //创建1个新的链表节点
pc = pc->next; //链表游标 -> 后移一个节点
pc->data = pb->data;
pc->next = NULL;
lastData = pc->data;
}
pb = pb->next;
}else{//即(pa->data < pb->data) //pa节点数据<pb节点数据,则先合并pa
if(pa->data != lastData){
pc->next = new ND; //创建1个新的链表节点
pc = pc->next; //链表游标 -> 后移一个节点
pc->data = pa->data;
pc->next = NULL;
lastData = pc->data;
}
pa = pa->next;
}
}
}
//=================================================
return hc;
}
int main(){
ND *ha, *hb, *hc; //ha,hb-指向两个给定的有序链表头; hc-指向合并后的有序链表
FILE *fp;
if((fp=fopen("SC6_6B.in", "r")) != NULL ){
fclose(fp); //存在的话,要先把之前打开的文件关掉
freopen("SC6_6B.in", "r", stdin);
freopen("SC6_6B.out", "w", stdout);
}
ha = createLink(); //创建有序链表ha
hb = createLink(); //创建有序链表hb
hc = megerLink( ha, hb ); //调用函数megerLink(...)合并两个有序链表ha & hb, 并去除其中重复元素
printLink( hc ); //打印输出合并后的有序链表hc
deleteLink( ha ); //删除有序链表ha
deleteLink( hb ); //删除有序链表hb
deleteLink( hc ); //删除有序链表hc
return 0;
}
3.2. 拓展题:SC6_6C.cpp(本题20分)
有2个从小到大已经排序好的(有序)表,每个结点的数据是1个整数,已知两个表的数据存放在带头结点的单向链表中,将2个有序表合并成1个新的有序表,并要求新表中仅包含2个原表的交集。打开SC6_6C.cpp文件,完成程序的编写。
【输入】
输入文件SC6_6C.in有4行,第1行有1个整数n,即第1个表的结点数,第2行有n个整数;第3行有1个整数m,即第2个表的结点数,第4行有m个整数。整数之间用空格隔开。
【输出】
输出文件SC6_6C.out有1行,将上述2个表数据的交集从小到大排序输出,每个整数之后输出1个空格。
【输入输出样例1】
SC6_6C.in SC6_6C.out
7
3 6 11 25 67 84 92
10
-5 3 8 25 25 43 67 92 96 99 3 25 67 92
【输入输出样例2】
SC6_6C.in SC6_6C.out
8
3 6 11 25 25 67 84 92
10
-5 3 8 25 25 43 67 92 96 99 3 25 25 67 92
【数据限制】
0≤m, n;1≤m+n;所有数据均为整数。
在这里插入代码片
#include "stdio.h"
const int INF=0x7fffffff; //无穷大整数
/*链表节点结构*/
struct ND{
int data; //链表节点数据: 一个整数
struct ND *next; //指向下一个链表节点的指针
};
/*创建链表, 并返回链表头指针*/
ND *createLink( ) {
ND *head, *p; //head-链表头指针; p-遍历链表的链表游标
int n; //链表长度(节点数目)
head = p = new ND; //链表头指针head, 链表游标p指向链表头
scanf("%d", &n); //链表长度(节点数目)
//printf("-->%d", n);
while( n-- ) {
p->next = new ND; //创建1个新的链表节点
p = p->next; //链表游标 -> 后移一个节点
scanf("%d", &p->data); //输入链表节点数据
}
p->next = NULL; //链表最后一个节点指向下一个节点的指针 --> 指向空NULL
return head; //返回链表头指针
}
/*打印链表*/
void printLink( ND *head ) {
ND *p = head->next;
if( p == NULL ){ //若链表为空, 直接返回
return ;
}
while( p ) { //逐个打印链表节点上的数据
printf( "%d ", p->data );
p=p->next;
}
printf("\n");
}
/*删除整个链表*/
void deleteLink( ND *head) {
ND *p=head;
while( p ) { //若链表节点存在,...
head = p->next; //链表头指针往后移动
delete p; //删除链表节点('新'头指针之前的一个节点)
p = head; //更新当前链表节点指针
}
}
/*合并2有序表, 返回合并后链表头结点的地址*/
ND * megerLink( ND *ha, ND *hb ){
ND *pa=ha->next, *pb=hb->next, *hc, *pc; //三个链表的头指针p*(a,b,c)及其链表游标h*(a,b,c)
//int data, lastData=INF; //lastData为上一个结点的数据项,用于判定是否有相同数据
hc=pc=new ND;
//************************************************
while(pa!=NULL || pb!=NULL){ //只要待合并的两个链表其中之一不为空, 则继续进行合并操作
if( (pa != NULL) && (pb != NULL) ){ //两个链表都非空
if(pa->data > pb->data){ //pb向后遍历
pb = pb->next;
}else if(pa->data < pb->data){ //pa向后遍历
pa = pa->next;
}else{//pa->data == pb->data //是交集元素,为结果集创建新节点, 并使pa & pb都向后遍历
pc->next = new ND; //创建1个新的链表节点
pc = pc->next; //链表游标 -> 后移一个节点
pc->data = pb->data;
//pc->next = NULL; //最后一个节点指向NULL,在返回结果头指针hc之前处理
//lastData = pc->data;
pa = pa->next;
pb = pb->next;
}
}else if(pa == NULL){ //若链表1为空, 则合并链表2剩下的所有数据
break;
}else if(pb == NULL){//若链表2为空, 则合并链表1剩下的所有数据
break;
}
}
pc->next = NULL; //合并完的链表的 最后一个节点的下一个节点为NULL
//=================================================
return hc;
}
int main(){
ND *ha, *hb, *hc; //ha,hb-指向两个给定的有序链表头; hc-指向合并后的有序链表
FILE *fp;
if((fp=fopen("SC6_6C.in", "r")) != NULL ){
fclose(fp); //存在的话,要先把之前打开的文件关掉
freopen("SC6_6C.in", "r", stdin);
freopen("SC6_6C.out", "w", stdout);
}
ha = createLink(); //创建有序链表ha
hb = createLink(); //创建有序链表hb
hc = megerLink( ha, hb ); //调用函数megerLink(...)合并两个有序链表ha & hb, 并去除其中重复元素
printLink( hc ); //打印输出合并后的有序链表hc
deleteLink( ha ); //删除有序链表ha
deleteLink( hb ); //删除有序链表hb
deleteLink( hc ); //删除有序链表hc
return 0;
}