数据结构与算法——周练2

A. DS顺序表--类实现

输入

第1行先输入n表示有n个数据,即n是实际长度;接着输入n个数据
第2行输入要插入的位置和新数据
第3行输入要插入的位置和新数据
第4行输入要删除的位置
第5行输入要删除的位置
第6行输入要查找的位置
第7行输入要查找的位置

输出

数据之间用空格隔开

第1行输出创建后的顺序表内容,包括顺序表实际长度和数据

每成功执行一次操作(插入或删除),输出执行后的顺序表内容

每成功执行一次查找,输出查找到的数据

如果执行操作失败(包括插入、删除、查找等失败),输出字符串error,不必输出顺序表内容

#include <iostream>
using namespace std;

#define ok 0
#define error -1

class SeqList
{
private:
	int* list;
	int maxsize;
	int size;
public:
	SeqList();
	SeqList(int n)
	{
		maxsize = 1000;
		size = n;
		list = new int[maxsize];
		for (int i = 0; i < size; i++)
		{
			cin >> list[i];
		}
	}
	~SeqList();
	int list_size(int n)
	{
		size = n;
		return size;
	}
	int list_insert(int i, int item)
	{
		if (item > size+1 || item <= 0)
		{
			cout << "error" << endl;
			return 0;
		}
		else
		{
			int* list2 = new int[size + 1];
			list2[0] = i;
			for (int j = item - 1,k=1; j < size; k++,j++)
			{
				list2[k] = list[j];
			}
			size++;
			for (int k = item-1,j=0; k < size; k++,j++)
			{
				list[k] = list2[j];
			}
			list_display();
			return 0;
		}

	}
	int list_del(int i)
	{
		if (i > size||i<=0)
		{
			cout << "error" << endl;
		}
		else
		{
			for (int j = i-1; j < size - 1; j++)
			{
				list[j] = list[j + 1];
			}
			size--;
			list_display();
		}
		return 0;
	}
	void list_get(int i)
	{
		if (i > size || i <= 0)
		{
			cout << "error" << endl;
		}
		else
		{
			cout << list[i-1] << endl;
		}
	}
	void list_display()
	{
		cout << size << " ";
			for (int i = 0; i < size; i++)
			{
				cout << list[i] << " ";
			}
			cout << endl;
	}
};

SeqList::SeqList()
{
	maxsize = 1000;
	size = 0;
	list = new int[maxsize];
}


SeqList :: ~SeqList()
{
	delete[]list;
}


int main()
{
	int n;
	cin >> n;
	SeqList p(n);
	p.list_display();

	int index;
	int lnew;
	cin >> index >> lnew;
	p.list_insert(lnew, index);
	//p.list_display();

	cin >> index >> lnew;
	p.list_insert(lnew, index);
	//p.list_display();

	cin >> index;
	p.list_del(index);

	cin >> index;
	p.list_del(index);

	cin >> index;
	p.list_get(index);

	cin >> index;
	p.list_get(index);

	return 0;
}

 这道题主要在于插入和删除,有一个思路是,先执行一次插入或者删除的动作,然后可以重复n次,就可以插入或者删除n次。

ps:注意函数类型,正确使用返回值,以及返回值的位置也很重要。

B. DS顺序表--连续操作

题目描述

建立顺序表的类,属性包括:数组、实际长度、最大长度(设定为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行输出执行连续删除后的顺序表内容

#include <iostream>
using namespace std;

#define ok 0
#define error -1

class SeqList
{
private:
	int* list;
	int maxsize;
	int size;
public:
	SeqList();
	SeqList(int n)
	{
		maxsize = 1000;
		size = n;
		list = new int[maxsize];
		for (int i = 0; i < size; i++)
		{
			cin >> list[i];
		}
	}
	~SeqList();
	int list_size(int n)
	{
		size = n;
		return size;
	}
	int list_insert(int i, int item)
	{
		if (item > size+1 || item <= 0)
		{
			cout << "error" << endl;
			return 0;
		}
		else
		{
			int* list2 = new int[size + 1];
			list2[0] = i;
			for (int j = item - 1,k=1; j < size; k++,j++)
			{
				list2[k] = list[j];
			}
			size++;
			for (int k = item-1,j=0; k < size; k++,j++)
			{
				list[k] = list2[j];
			}
			return 1;
		}

	}
	int list_del(int i)
	{
		if (i > size||i<=0)
		{
			cout << "error" << endl;
			return 0;
		}
		else
		{
			for (int j = i-1; j < size - 1; j++)
			{
				list[j] = list[j + 1];
			}
			size--;
			//list_display();
			return 1;
		}
	}
	void list_get(int i)
	{
		if (i > size || i <= 0)
		{
			cout << "error" << endl;
		}
		else
		{
			cout << list[i-1] << endl;
		}
	}
	void list_display()
	{
		cout << size << " ";
			for (int i = 0; i < size; i++)
			{
				cout << list[i] << " ";
			}
			cout << endl;
	}
};

SeqList::SeqList()
{
	maxsize = 1000;
	size = 0;
	list = new int[maxsize];
}


SeqList :: ~SeqList()
{
	delete[]list;
}


int main()
{
	int n;
	cin >> n;
	SeqList p(n);
	p.list_display();

	int index;
	int lnew;
	//cin >> index >> lnew;
	//p.list_insert(lnew, index);
	p.list_display();

	//cin >> index >> lnew;
	//p.list_insert(lnew, index);
	p.list_display();

	//cin >> index;
	//p.list_del(index);

	//cin >> index;
	//p.list_del(index);

	//cin >> index;
	//p.list_get(index);

	//cin >> index;
	//p.list_get(index);
	

	//第二题
	int k;
	cin >> index >> k;
	for (int i = index; i < index+k; i++)
	{
		int a;
		cin >> a;
		p.list_insert(a, i);
	}
	p.list_display();
	cin >> index >> k;
	for (int i = index,j=0; j < k; j++)
	{
		p.list_del(i);
	}
	p.list_display();

	return 0;
}

说白了就是对于之前那题的升级,没什么说的,就是重复那个思想继续贯彻一下

C. DS顺序表--合并操作

题目描述

建立顺序表的类,属性包括:数组、实际长度、最大长度(设定为1000)

已知两个递增序列,把两个序列的数据合并到顺序表中,并使得顺序表的数据递增有序

输入

第1行先输入n表示有n个数据,接着输入n个数据,表示第1个序列,要求数据递增互不等

第2行先输入m表示有m个数据,接着输入m个数据,表示第2个序列,要求数据递增互不等

输出

顺序表内容包括顺序表的实际长度和数据,数据之间用空格隔开

第1行输出创建后的顺序表内容

#include <iostream>
#include <cstdio>
#include<algorithm>
using namespace std;

class SeqList
{
private:
	int* list;
	int maxsize;
	int size;
public:
	SeqList(int n)
	{
		size = n;
		maxsize = 1000;
		list = new int[maxsize];
	}
	void getlist()
	{
		for (int i = 0; i < size; i++)
		{
			cin >> list[i];
		}
	}
	//int getList()
	//{
	//	return *list;
	//}
	void list_display()
	{
		cout << size << " ";
		for (int i = 0; i < size; i++)
		{
			cout << list[i] << " ";
		}
		cout << endl;
	}
	SeqList operator+ (const SeqList& p)
	{
		SeqList temp(p.size+size);
		for (int i = 0; i < p.size; i++)
		{
			temp.list[i] = p.list[i];
		}
		for (int i = p.size,k=0; i < p.size+size; k++,i++)
		{
			temp.list[i] = list[k];
		}
		sort(temp.list, temp.list + p.size + size);
		return temp;
	}
};




int main()
{

	int n;
	int m;
	cin >> n;
	SeqList p(n);
	p.getlist();
	cin >> m;
	SeqList q(m);
	q.getlist();
	SeqList a(n + m);
	a = p + q;
	a.list_display();
}

我自我感觉这题我写的不是很对,因为题目要求是使用归并的算法,但是我没有我直接两个数组组合在一起然后直接sort了,非常有待于优化改进。

D. DS顺序表之循环移位

题目描述

顺序表的移位是循环移位,例如顺序表:1,2,3,4,5,6。如果左移1位,即原来的头元素移动到末尾,其它元素向左移1位,变成2,3,4,5,6,1。同理,如果右移1位,即原来的尾元素移动到头,其它元素向右移1位,变成6,1,2,3,4,5。以下是移位的多个例子:

原数据:1,2,3,4,5,6

左移3位:4,5,6,1,2,3,与原数据对比

右移4位:3,4,5,6,1,2,与原数据对比

请编写程序实现顺序表的循环移位操作

输入

第1行输入n表示顺序表包含的·n个数据

第2行输入n个数据,数据是小于100的正整数

第3行输入移动方向和移动的位数,左移方向为0,右移方向为1

第4行输入移动方向和移动的位数,左移方向为0,右移方向为1

注意:移动操作是针对上一次移动后的结果进行的

输出

第一行输出创建后,顺序表内的所有数据,数据之间用空格隔开

第二行输出第一次移位操作后,顺序表内的所有数据,数据之间用空格隔开

第三行输出第二次移位操作后,顺序表内的所有数据,数据之间用空格隔开

#include <iostream>
using namespace std;


class SeqList
{
private:
	int* list;
	int maxsize;
	int size;
public:
	SeqList(int n)
	{
		size = n;
		maxsize = 1000;
		list = new int[maxsize];
	}
	void getlist()
	{
		for (int i = 0; i < size; i++)
		{
			cin >> list[i];
		}
	}
	void list_display()
	{
		for (int i = 0; i < size; i++)
		{
			cout << list[i] << " ";
		}
		cout << endl;
	}
	void right_move(int t)
	{
		while (t--) {
			int x = list[size - 1];
			for (int i = size - 1; i > 0; i--) {
				list[i] = list[i - 1];
			}
			list[0] = x;
		}
	}
	void lift_move(int t)
	{
		while (t--) {
			int x = list[0];
			for (int i = 0; i < size - 1; i++) {
				list[i] = list[i + 1];
			}
			list[size - 1] = x;
		}
	}
};

int main()
{
	int n;
	cin >> n;
	SeqList p(n);
	p.getlist();
	p.list_display();
	int s, k;
	cin >> s >> k;
	if (s == 0)
	{
		p.lift_move(k);
	}
	else
	{
		p.right_move(k);
	}
	p.list_display();


	cin >> s >> k;
	if (s == 0)
	{
		p.lift_move(k);
	}
	else
	{
		p.right_move(k);
	}
	p.list_display();
}

这道题我是有借鉴网上内容的,因为我之前在写密码学的时候对于循环位移使用的就是很愚蠢的办法,这次循环位移的数字不固定了,我就不知道怎么循环了,没想到还是重复的思想,先编写循环一个个的算法,然后循环n次即可。

E. 三串合一(指针与字符数组)

题目描述

输入三个字符串,通过指针读取各个字符串的子串(子串是指字符串中连续的一小部分),把它们合并成一个新字符串

要求:

1. 三个字符串的创建和输入可以使用数组,也可以不用

2. 输入后,根据三个字符串的子串的长度,计算出新字符串的长度

3. 使用动态数组的方法创建新的字符串,并且使用指针读取三个字符串的不同部分,并且复制到新字符串中,要求整个过程都不能使用数组下标

4. 使用指针输出新的字符串

输入

第一行输入t表示有t个测试实例

连续三行输入三个字符串,每个字符串都包含10个字符

连续三行,每行输入数字a和b,表示每个子串的开始和结束位置。注意字符串的位置是按照一般意义从1开始计算,和编程中的数组位置不同。例如字符串abcdefg,开始位置是3,结束位置是5,那么子串就是cde

依次输入t个实例

输出

每行输出合并后的新字符串

#include <iostream>
using namespace std;



int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		char a[10];
		char b[10];
		char c[10];
		for (int i = 0; i < 10; i++)
		{
			cin >> a[i];
		}		
		for (int i = 0; i < 10; i++)
		{
			cin >> b[i];
		}
		for (int i = 0; i < 10; i++)
		{
			cin >> c[i];
		}
		int x1, y1, x2, y2, x3, y3;
		cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
		int size = y1 - x1 + y2 - x2 + y3 - x3 + 3;
		char* p = new char[size];
		for (int i = 0; i < y1-x1+1; i++)
		{
			*(p + i) = *(a + x1 - 1 + i);
		}
		for (int i = y1 - x1 + 1,k=0; i < y1 - x1 + 1+y2-x2+1;k++, i++)
		{
			*(p + i) = *(b + x2 - 1 + k);
		}
		for (int i = y1 - x1 + 1 + y2 - x2 + 1,k=0; i < size; k++,i++)
		{
			*(p + i) = *(c + x3 - 1 + k);
		}
		for (int i = 0; i < size; i++)
		{
			cout << *(p + i);
		}
		cout << endl;
	}

}

纯纯基础题,随便ac

F. 判断矩形是否重叠(结构)

题目描述

用具有x,y两个整型变量成员的结构类型SPoint来表示坐标点。用SRect结构类型来描述矩形,其中包含p1和p2两个SPoint成员分别表示矩形对角线上的两个点。

编写判断两个矩形是否重叠的函数。

输入

判断次数

矩形1的对角线顶点坐标x1、y1、x2、y2

矩形2的对角线顶点坐标x1、y1、x2、y2

......

输出

是否重叠

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

struct SPoint
{
	int x, y;
};


struct SRect
{
	SPoint p1;
	SPoint p2;
};

void change(SRect& rect)
{
	if (rect.p1.x>rect.p2.x)
	{
		swap(rect.p1.x, rect.p2.x);
	}
	if (rect.p1.y > rect.p2.y)
	{
		swap(rect.p1.y, rect.p2.y);
	}
}

int check(const SRect& rect1, const SRect& rect2)
{
	if (rect1.p1.x > rect2.p2.x || rect1.p1.y > rect2.p2.y || rect1.p2.x < rect2.p1.x || rect1.p2.y < rect2.p1.y)
	return 0;
	return 1;
}

int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		SRect rect1, rect2;
		cin >> rect1.p1.x >> rect1.p1.y >> rect1.p2.x >> rect1.p2.y;
		cin >> rect2.p1.x >> rect2.p1.y >> rect2.p2.x >> rect2.p2.y;
		change(rect1);
		change(rect2);
		if (check(rect1, rect2))
		{
			cout << "overlapped" << endl;
		}
		else
		{
			cout << "not overlapped" << endl;
		}
	}


}

一开始想的是暴力ac他,就是循环什么的搞来搞去,但是我觉得很早之前写的那题也是这种无脑暴力,我还是想我写的代码优雅一点,于是又到网上借鉴了一下,发现这个方法更加方便,就是先把角对其,然后比大小,比完就出答案,非常方便,强烈推荐

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值