2.5打印链表信息(用于检查链表是否初始化成功,实际使用时注释掉)
一、问题描述
用户输入一个以@为结束符的字母序列
判断是否为形如‘序列 1& 序列 2’模式的字符序列。
其中序列 1 和序列 2 中都不含字符‘&’,且序列 2 是序列 1的逆序列。
二、需求分析
1、功能需求分析
用户输入的字符串(字符串中间以&隔开,字符串结尾用@表示),程序判断用户输入的字符串是否是序列1&序列二且序列2是序列1逆序列的字符串。
2、算法分析
用户输入完字符串后把字符串分开,以序列1的顺序为“正顺序“,把序列2倒序保存,再分别输出第一个、第二个......一直到第n个字符进行比较,如果字符全部都相同,输出字符串是该模式的字符序列;如果比较时有一个字符不同,则直接输出该字符串不是该模式下的字符序列。
三、数据结构定义
为了防止定义的数组太小使字母序列在保存时溢出,也为了防止直接定义一个大数组造成空间上的浪费。我们采用链式存储来解决这个问题。
对于顺序保存前半字符序列和倒叙保存后半字符序列,我们可以分别采用链表的尾插法和头插法,尾插法来顺序保存,头插法来倒序保存(当然也可以利用队列的链式存储进行顺序保存,用栈的链式存储来倒叙保存),再利用for循环来判断是否相同。
定义一个string类型的变量让用户输入这个字母序列,string类型的这个变量实际上是一个字符数组,我们定义的数据类型包含char类型的数据(data)和指向下一个的指针变量(next);定义了初始化链表的函数void inlistNode(listNode*& L)来初始化这个链表,定义了头插法函数void headlistNode(listNode& L, char n)和尾插法函数void createlistNode(listNode& L, char n)用来数据入链表;定义了打印链表函数void putlistNode(listNode* L)用来测试两种入链方式是否正确(在用户的实际使用时把该函数注释掉);定义了取第一个元素函数void outlistNode(listNode& L, char &n)用来取链表的第一个元素用于判断是否相等,并且让头结点指向下一个结点。
四、详细代码
1.数据结构
//链表
struct listNode {
char data;
listNode* next;
};
2.函数
2.1链表的初始化
//初始化链表
void inlistNode(listNode*& L) {
L = (listNode*)malloc(sizeof(listNode));
L->next = NULL;
}
2.2头插法插入数据
//头插法插入数据
void headlistNode(listNode& L, char n) {
listNode* p = (listNode*)malloc(sizeof(listNode));
p->data = n;
p->next = L.next;
L.next = p;
}
2.3尾插法插入数据
//尾插法插入数据
void createlistNode(listNode& L, char n) {
listNode* p = (listNode*)malloc(sizeof(listNode));
p->data = n;
p->next = NULL;
listNode* cur = &L;
while (cur->next != NULL) cur = cur->next;
cur->next = p;
}
2.4取第一个元素(用于比较是否相同)
//取第一个元素
void outlistNode(listNode& L, char &n) {
listNode* p = (listNode*)malloc(sizeof(listNode));
if (L.next != NULL) {
p = L.next;
n = p->data;
L.next = p->next;
n = p->data;
}
}
2.5打印链表信息(用于检查链表是否初始化成功,实际使用时注释掉)
//打印链表
void putlistNode(listNode* L) {
cout << "打印链表:";
listNode* m = L->next;
while (m != NULL) {
cout << m->data << " ";
m = m->next;
}
cout << endl;
}
3.详细代码
#include<iostream>
#include<string>
using namespace std;
//链表
struct listNode {
char data;
listNode* next;
};
//初始化链表
void inlistNode(listNode*& L) {
L = (listNode*)malloc(sizeof(listNode));
L->next = NULL;
}
//头插法插入数据
void headlistNode(listNode& L, char n) {
listNode* p = (listNode*)malloc(sizeof(listNode));
p->data = n;
p->next = L.next;
L.next = p;
}
//尾插法插入数据
void createlistNode(listNode& L, char n) {
listNode* p = (listNode*)malloc(sizeof(listNode));
p->data = n;
p->next = NULL;
listNode* cur = &L;
while (cur->next != NULL) cur = cur->next;
cur->next = p;
}
//取第一个元素
void outlistNode(listNode& L, char &n) {
listNode* p = (listNode*)malloc(sizeof(listNode));
if (L.next != NULL) {
p = L.next;
n = p->data;
L.next = p->next;
n = p->data;
}
}
//打印链表
void putlistNode(listNode* L) {
cout << "打印链表:";
listNode* m = L->next;
while (m != NULL) {
cout << m->data << " ";
m = m->next;
}
cout << endl;
}
int main() {
int i = 0, j;
string str;
cout << "请输入一个以@为结束符的字母序列" << endl;
cout << "程序会帮您判断输入序列是否是形如‘序列 1& 序列 2’模式的字符序列。"<<endl;
cout << "其中序列 1 和序列 2 中都不含字符‘ & ’,且序列 2 是序列 1 的逆序列。"<<endl;
cout << "例如,‘a + b & b + a’是属该模式的字符序列,而‘1 + 3 & 3-1’则不是" << endl;
cout << "字母序列:";
cin >> str;
cout << endl;
listNode* L2;
inlistNode(L2);
listNode* L1;
inlistNode(L1);
while (str[i] != '&') {
if (str[i] == '&') break;
createlistNode(*L1, str[i]);
i++;
}
j = 1 + i;
while (str[j] != '@') {
if (str[j] == '@') break;
headlistNode(*L2, str[j]);
j++;
}
putlistNode(L1);
putlistNode(L2);
if (i != (j - i - 1)) {
cout << "序列不是形如‘序列 1&序列 2’模式的字符序列" << endl;
return 0;
}
else {
char m, n;
for (int k = 0; k < i; k++) {
outlistNode(*L1, m);
outlistNode(*L2, n);
if (m != n) {
cout << "序列不是形如‘序列 1&序列 2’模式的字符序列" << endl;
return 0;
}
}
cout<< "序列是形如‘序列 1&序列 2’模式的字符序列" << endl;
}
return 0;
}