问题 A: DS顺序表--类实现
时间限制: 1 Sec 内存限制: 128 MB提交: 1385 解决: 437
[ 提交][ 状态][ 讨论版]
题目描述
实现顺序表的用C++语言和类实现顺序表
属性包括:数组、实际长度、最大长度(设定为1000)
操作包括:创建、插入、删除、查找
类定义参考
输入
输出
数据之间用空格隔开
第1行输出创建后的顺序表内容,包括顺序表实际长度和数据
每成功执行一次操作(插入或删除),输出执行后的顺序表内容
每成功执行一次查找,输出查找到的数据
如果执行操作失败(包括插入、删除、查找等失败),输出字符串error,不必输出顺序表内容
样例输入
样例输出
提示
第i个位置是逻辑意义的位置,从1开始,在实际编程用数组,从0开始,对应数组i-1位置
/* 注意点:在有参构造函数的时候,list数组需要开辟一定的空间,
* 不然如果有后续操作开辟新的数组空间的话,可能会导致空间占用,数值出错。
*/
#include <iostream>
using namespace std;
#define ok 0
#define error -1
class SeqList {
int *list;
int maxsize;
int size;
public:
SeqList() {
maxsize = 1000;
size = 0;
list = new int[maxsize];
}
SeqList(int n) {
maxsize = 1000;
size = n;
list = new int[maxsize];
for(int i = 0; i < n; i++) {
cin >> list[i];
}
}
~SeqList() {
delete []list;
}
int list_size() {
return size;
}
int list_insert(int i, int item) {
if(i < 1 || i > size + 1 || i > maxsize)
return error;
size++;
for(int j = size - 1; j >= i - 1; j--) {
list[j] = list[j - 1];
}
list[i - 1] = item;
return ok;
}
int list_del(int i) {
if(i < 1 || i > size || i > maxsize)
return error;
for(int j = i - 1; j < size - 1; j++) {
list[j] = list[j + 1];
}
size--;
return ok;
}
int list_get(int i) {
if(i < 1 || i > size || i > maxsize)
return 1001;
return list[i - 1];
}
void list_display() {
cout << this->list_size() << ' ';
for(int i = 0; i < size; i++) {
cout << list[i] << ' ';
}
cout << endl;
}
};
int main() {
int n;
cin >> n;
SeqList list(n);
list.list_display();
int item;
for(int i = 0; i < 2; i++) {
cin >> n >> item;
if(!list.list_insert(n, item)){
list.list_display();
} else {
cout << "error" << endl;
}
}
for(int i = 0; i < 2; i++) {
cin >> n;
if(!list.list_del(n)) {
list.list_display();
} else {
cout << "error" << endl;
}
}
for(int i = 0; i < 2; i++) {
cin >> n;
if(list.list_get(n) != 1001) {
cout << list.list_get(n) << endl;
} else {
cout << "error" << endl;
}
}
return 0;
}
问题 B: DS顺序表--连续操作
时间限制: 1 Sec 内存限制: 128 MB提交: 780 解决: 417
[ 提交][ 状态][ 讨论版]
题目描述
建立顺序表的类,属性包括:数组、实际长度、最大长度(设定为1000)
该类具有以下成员函数:
构造函数:实现顺序表的初始化。
插入多个数据的multiinsert(int i, int n, int item[])函数,实现在第i个位置,连续插入来自数组item的n个数据,即从位置i开始插入多个数据。
删除多个数据的multidel(int i, int n)函数,实现从第i个位置开始,连续删除n个数据,即从位置i开始删除多个数据。
编写main函数测试该顺序表类。
输入
第1行先输入n表示有n个数据,即n是实际长度;接着输入n个数据
第2行先输入i表示插入开始的位置,再输入k表示有k个插入数据,接着输入k个数据
第3行先输入i表示删除开始的位置,再输入k表示要删除k个数据
输出
顺序表内容包括顺序表的实际长度和数据,数据之间用空格隔开
第1行输出创建后的顺序表内容
第2行输出执行连续插入后的顺序表内容
第3行输出执行连续删除后的顺序表内容
样例输入
样例输出
/* 注意点:同问题A的点,在开辟空间的时候需要开辟maxsize的空间,因为我只开辟了n个空间,
* 导致后面连续操作的时候,再开辟空间给数组,重复空间,数值被覆盖,导致错误。
* 另外就是连续操作移动数值的规律,拿张纸出来画画,好好思考,不要粗心,因为他说跳跃的复制而不是连续单个复制。
*/
#include <iostream>
using namespace std;
#define ok 0
#define error -1
class SeqList {
int *list;
int maxsize;
int size;
public:
SeqList() {
maxsize = 1000;
size = 0;
list = new int[maxsize];
}
SeqList(int n) {
maxsize = 1000;
size = n;
list = new int[maxsize];
for(int i = 0; i < n; i++) {
cin >> list[i];
}
}
~SeqList() {
delete []list;
}
int list_size() {
return size;
}
int list_insert(int i, int item) {
if(i < 1 || i > size + 1 || i > maxsize)
return error;
size++;
for(int j = size - 1; j >= i - 1; j--) {
list[j] = list[j - 1];
}
list[i - 1] = item;
return ok;
}
int list_del(int i) {
if(i < 1 || i > size || i > maxsize)
return error;
for(int j = i - 1; j < size - 1; j++) {
list[j] = list[j + 1];
}
size--;
return ok;
}
int list_get(int i) {
if(i < 1 || i > size || i > maxsize)
return 1001;
return list[i - 1];
}
void list_display() {
cout << this->list_size() << ' ';
for(int i = 0; i < size; i++) {
cout << list[i] << ' ';
}
cout << endl;
}
void multiinsert(int i, int n, int item[]) {
size += n;
for(int j = size - 1; j - n >= i - 1; j--) {
list[j] = list[j - n];
}
for(int j = 0; j < n; j++, i++) {
list[i - 1] = item[j];
}
}
void multidel(int i, int n) {
for(int j = i - 1; j < size - 1; j++) {
list[j] = list[j + n];
}
size -= n;
}
};
int main() {
int n;
cin >> n;
SeqList list(n);
list.list_display();
int i;
cin >> i >> n;
int *item = new int[n];
for(int j = 0; j < n; j++) {
cin >> item[j];
}
list.multiinsert(i, n, item);
list.list_display();
cin >> i >> n;
list.multidel(i, n);
list.list_display();
return 0;
}
问题 C: DS顺序表--合并操作
时间限制: 1 Sec 内存限制: 128 MB提交: 629 解决: 400
[ 提交][ 状态][ 讨论版]
题目描述
建立顺序表的类,属性包括:数组、实际长度、最大长度(设定为1000)
已知两个递增序列,把两个序列的数据合并到顺序表中,并使得顺序表的数据递增有序
输入
第1行先输入n表示有n个数据,接着输入n个数据,表示第1个序列,要求数据递增互不等
第2行先输入m表示有m个数据,接着输入m个数据,表示第2个序列,要求数据递增互不等
输出
顺序表内容包括顺序表的实际长度和数据,数据之间用空格隔开
第1行输出创建后的顺序表内容
样例输入
样例输出
/* 这里我用的是直接传入两个SeqList,合并后再排序。有一个地方需要注意,就是合并函数传进去的时候,
* 需要传引用!这里很重要,如果不传引用,会导致程序崩溃。原因是这里传参数进去会用的拷贝构造函数,
* 所以最后我传进去的参数会被析构两次,导致错误!
*
* 其次就是类的无参构造函数,是不需要带括号的。。
*
* 然后这个合并有两种操作,两两比较再合并。再将多余的直接复制下来。放在下一个文档进行尝试。
*/
#include <iostream>
using namespace std;
#define ok 0
#define error -1
class SeqList {
int *list;
int maxsize;
int size;
public:
SeqList() {
maxsize = 1000;
size = 0;
list = new int[maxsize];
}
SeqList(int n) {
maxsize = 1000;
size = n;
list = new int[maxsize];
for(int i = 0; i < n; i++) {
cin >> list[i];
}
}
~SeqList() {
delete []list;
}
int list_size() {
return size;
}
int list_insert(int i, int item) {
if(i < 1 || i > size + 1 || i > maxsize)
return error;
size++;
for(int j = size - 1; j >= i - 1; j--) {
list[j] = list[j - 1];
}
list[i - 1] = item;
return ok;
}
int list_del(int i) {
if(i < 1 || i > size || i > maxsize)
return error;
for(int j = i - 1; j < size - 1; j++) {
list[j] = list[j + 1];
}
size--;
return ok;
}
int list_get(int i) {
if(i < 1 || i > size || i > maxsize)
return 1001;
return list[i - 1];
}
void list_display() {
cout << this->list_size() << ' ';
for(int i = 0; i < size; i++) {
cout << list[i] << ' ';
}
cout << endl;
}
void multiinsert(int i, int n, int item[]) {
size += n;
for(int j = size - 1; j - n >= i - 1; j--) {
list[j] = list[j - n];
}
for(int j = 0; j < n; j++, i++) {
list[i - 1] = item[j];
}
}
void multidel(int i, int n) {
for(int j = i - 1; j < size - 1; j++) {
list[j] = list[j + n];
}
size -= n;
}
void combine(int s, SeqList &list_1, SeqList &list_2) {
this->size = s;
int i = 0;
for(i = 0; i < list_1.size; i++) {
list[i] = list_1.list[i];
}
for(int j = 0; j < list_2.size; j++, i++) {
list[i] = list_2.list[j];
}
for(i = 1; i < size; i++) {
for(int j = 0; j < size - i; j++) {
if(list[j] > list[j + 1])
swap(list[j], list[j + 1]);
}
}
}
};
int main() {
int n1, n2;
cin >> n1;
SeqList list_1(n1);
cin >> n2;
SeqList list_2(n2);
SeqList list;
list.combine(n1 + n2, list_1, list_2);
list.list_display();
return 0;
}
以下为另一种方法
/* 算法的时间复杂度为O(La.size + Lb.size)
*/
void MergeList(SeqList &La, SeqList &Lb) {
this->size = La.size + Lb.size;
int *pa_last = La.list + La.size - 1;
int *pb_last = Lb.list + Lb.size - 1;
int *pa = La.list;
int *pb = Lb.list;
int *pc = this->list;
while(pa <= pa_last && pb <= pb_last) {
if(*pa <= *pb) {
*pc++ = *pa++; // C编译器认为*和++是同优先级操作符,且都是从右至左结合的,所以*p++中的++只作用在p上,和*(p++)意思一样;在(*p)++中,由于()的优先级比*和++都高,所以++作用在()内的表达式*p上。*p++是使指针变量p本身增1。
// *pc = *pa;
// pc++;
// pa++;
} else {
*pc++ = *pb++; // 因为是升序排序,如果小的话,就把小的放在list中,否则放另外一个。然后指针加一。
}
}
while(pa <= pa_last) {
*pc++ = *pa++; // 将后面的元素照搬下来。
}
while(pb <= pb_last) {
*pc++ = *pb++;
}
}