STL中的list和vector使用(一)_第三门课_第二周_作业

喜欢的朋友可以关注收藏一下:  http://blog.csdn.NET/qq_31201973

本文如有错误,请及时私信我。

原版要求:

 

创建一个list容器,放置6个整型数值[0, 1, 30, 20, 10, 0]

1. 从后向前打印出容器内的元素

2. 向list容器后面添加两个元素,并对容器内的值求和并打印

3. 打印链表的中间元素

4. 找到不为0的元素,复制到一个vector中并打印vector元素

根据要求需要两种容器,还需要输入输出所以包含了三个头文件,所以我搭起了这样的框架

#include<iostream>
#include<list>
#include<vector>


using namespace std;
typedef list<int> INTLIST;

int main()
{
	system("pause");
	return 0;
}

然后是存6个元素到list,倒着打印。这个地方我为了防止打印的时候当掉用了plist = --(L.end())。限定条件没有写,因为如果写迭代器不等于begin的话会少打印一个元素。

	INTLIST L{0,1,30,20,10,0};
	INTLIST::iterator plist;
	cout << "1. 从后向前打印出容器内的元素." << endl;
	for (plist = --(L.end());; --plist)		//for无限定条件时不判断
	{
		cout << *plist << "  ";
		if (plist == L.begin())				//在此处判断并不影响效率		
		{
			break;
		}
	}

第一问就解决了,第二问要求添加两个元素后求和,添加元素用push_back,求和用c++ 新标准的for循环,因为要做+ - 所以 auto后面要加引用

	cout << endl << endl << "2. 向list容器后面添加两个元素,并对容器内的值求和并打印." << endl;
	cout << "请任意输入两个int类型数字:";
	for (i = 0; i < 2; ++i)
	{
		cin >> a;
		L.push_back(a);
	}
	for (auto& plist : L)
	{
		sum+=plist;
	}
	cout << "list容器内" << L.size() << "个元素的和为:" << sum << endl << endl;


但是这个程序有个bug就是如果超过int的范围会越过循环,一开始我本来要采取上周的办法解决,但是发现问题层出不禁,具体看我的注释

		while (a < -2147483647 || a > 2147483647)			//int范围边界的判断,经测试实际范围应该是-2147483648~2147483647。
		{//但是加判断里加负号以后会显示错误	1	error C4146: 一元负运算符应用于无符号类型,结果仍为无符号类型。
		//这一问题是由于编译器SDL安全检查认为这一操作(通常是为无符号整形取负的操作)无效而产生的.
		//当编译器看到2147483648时会自动认为超过了2147483647,直接转换成unsigned int.当编译器看到负号的时候直接取反是它本身,编译器存不了那么大的数,详细看一元运算符。
			cout << "整数(int)范围非法,请重新输入整数(int   -2147483648~2147483647):";
			cin >> a;
		}

最后我还用函数清了一下缓存区,结果也不理想,最后我只能把变量定义为long long int 来缓解这个问题

	cout << endl << endl << "2. 向list容器后面添加两个元素,并对容器内的值求和并打印." << endl;
	cout << "请任意输入两个int类型数字:";
	for (i = 0; i < 2; ++i)
	{
		cin >> a;
		while (a < -2147483647 || a > 2147483647)			//int范围边界的判断,经测试实际范围应该是-2147483648~2147483647。
		{//但是加判断里加负号以后会显示错误	1	error C4146: 一元负运算符应用于无符号类型,结果仍为无符号类型。
			//这一问题是由于编译器SDL安全检查认为这一操作(通常是为无符号整形取负的操作)无效而产生的.
			//当编译器看到2147483648时会自动认为超过了2147483647,直接转换成unsigned int.当编译器看到负号的时候直接取反是它本身,编译器存不了那么大的数,详细看一元运算符。
			cout << "整数(int)范围非法,请重新输入整数(int   -2147483648~2147483647):";
			cin >> a;
		}
		L.push_back(a);
	}
	for (auto& plist : L)
	{
		sum+=plist;
	}
	cout << "list容器内" << L.size() << "个元素的和为:" << sum << endl << endl;


第三个问题实际上就是迭代器和计数器的应用,我也采取了快慢指针的做法,虽然效率要比传统快慢指针要慢,但是减少了循环次数

	cout << "3. 打印链表的中间元素" << endl;
	if ((L.size()) % 2 == 0)				//如果是偶数用速度会少循环一般次数
	{
		i = (L.size()) / 2;					//中间元素这里默认是中间靠前的一个,这样无论容器元素是偶数还是奇数都适用;
		for (plist = L.begin();; ++++plist)		//有点类似于快指针,虽然少循环了一半的次数,但不是严格意义上的快指针,严格意义快指针是fast=fast->next->next; ,速度稍微快一点。
		{
			----i;
			if (i == 0)
			{
				cout << "中间元素为:" << *plist << endl << endl;		//打印的是第四个元素L{0,1,30,20,10,0,输入元素1,输入元素2} ,如果总元素是8个,那应该打印第4个,30 !!!
				break;					//防止再进入接下来的循环
			}
		}
	}
	else
	{
		i = (L.size()) / 2;					//中间元素这里默认是中间靠前的一个,这样无论容器元素是偶数还是奇数都适用;
		for (plist = L.begin();; ++plist)
		{
			--i;
			if (i == 0)
			{
				cout << "中间元素为:" << *plist << endl << endl;		//打印的是第四个元素L{0,1,30,20,10,0,输入元素1,输入元素2} ,如果总元素是8个,那应该打印第4个,30 !!!
				break;					//防止再进入接下来的循环
			}
		}
	}


那为什么++++plist不是快指针,而是调用了两次呢,我用断点做了这样的实验

第一张图是从标准库截取的,它在运行到for循环时候,++重载运行了两次,这就说明并不是传统的快指针。

同时我还发现++i --i 比 i++ i-- 速度要快,因为前者少了一步,标准库的代码如下

	_Myiter& operator++()
		{	// preincrement
		++(*(_Mybase *)this);
		return (*this);
		}

	_Myiter operator++(int)
		{	// postincrement
		_Myiter _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	_Myiter& operator--()
		{	// predecrement
		--(*(_Mybase *)this);
		return (*this);
		}

	_Myiter operator--(int)
		{	// postdecrement
		_Myiter _Tmp = *this;
		--*this;
		return (_Tmp);
		}
	};


这样来看如果循环次数较多那么效率差别就很大。

第四问其实没东西就是遍历过程中判断,插入,然后打印出来

cout << "4. 找到不为0的元素,复制到一个vector中并打印vector元素" << endl;
	for (auto plist: L)
	{
		if (plist != 0)
		{
			V.push_back(plist);
		}
	}
	cout << "不为0的元素已经插入到vector中,共" << V.size() << "个元素." << endl;
	cout << "vector中的元素为:";
	for (auto pvector : V)
	{
		cout << pvector << "  ";
	}
	cout << endl << endl;

整个的实现就是这样,下面附完整源代码:

//						main.cpp
#include<iostream>
#include<list>
#include<vector>


using namespace std;
typedef list<int> INTLIST;

int main()
{
	INTLIST L{0,1,30,20,10,0};
	INTLIST::iterator plist;
	int sum = 0, i;
	long long int a;
	vector<int> V;
	vector<int>::iterator pvector = V.begin();

	cout << "1. 从后向前打印出容器内的元素." << endl;
	for (plist = --(L.end());; --plist)		//for无限定条件时不判断
	{
		cout << *plist << "  ";
		if (plist == L.begin())				//在此处判断并不影响效率		
		{
			break;
		}
	}

	cout << endl << endl << "2. 向list容器后面添加两个元素,并对容器内的值求和并打印." << endl;
	cout << "请任意输入两个int类型数字:";
	for (i = 0; i < 2; ++i)
	{
		cin >> a;
		while (a < -2147483647 || a > 2147483647)			//int范围边界的判断,经测试实际范围应该是-2147483648~2147483647。
		{//但是加判断里加负号以后会显示错误	1	error C4146: 一元负运算符应用于无符号类型,结果仍为无符号类型。
			//这一问题是由于编译器SDL安全检查认为这一操作(通常是为无符号整形取负的操作)无效而产生的.
			//当编译器看到2147483648时会自动认为超过了2147483647,直接转换成unsigned int.当编译器看到负号的时候直接取反是它本身,编译器存不了那么大的数,详细看一元运算符。
			cout << "整数(int)范围非法,请重新输入整数(int   -2147483648~2147483647):";
			cin >> a;
		}
		L.push_back(a);
	}
	for (auto& plist : L)
	{
		sum+=plist;
	}
	cout << "list容器内" << L.size() << "个元素的和为:" << sum << endl << endl;

	cout << "3. 打印链表的中间元素" << endl;
	if ((L.size()) % 2 == 0)				//如果是偶数用速度会少循环一般次数
	{
		i = (L.size()) / 2;					//中间元素这里默认是中间靠前的一个,这样无论容器元素是偶数还是奇数都适用;
		for (plist = L.begin();; ++++plist)		//有点类似于快指针,虽然少循环了一半的次数,但不是严格意义上的快指针,严格意义快指针是fast=fast->next->next; ,速度稍微快一点。
		{
			----i;
			if (i == 0)
			{
				cout << "中间元素为:" << *plist << endl << endl;		//打印的是第四个元素L{0,1,30,20,10,0,输入元素1,输入元素2} ,如果总元素是8个,那应该打印第4个,30 !!!
				break;					//防止再进入接下来的循环
			}
		}
	}
	else
	{
		i = (L.size()) / 2;					//中间元素这里默认是中间靠前的一个,这样无论容器元素是偶数还是奇数都适用;
		for (plist = L.begin();; ++plist)
		{
			--i;
			if (i == 0)
			{
				cout << "中间元素为:" << *plist << endl << endl;		//打印的是第四个元素L{0,1,30,20,10,0,输入元素1,输入元素2} ,如果总元素是8个,那应该打印第4个,30 !!!
				break;					//防止再进入接下来的循环
			}
		}
	}

	cout << "4. 找到不为0的元素,复制到一个vector中并打印vector元素" << endl;
	for (auto plist: L)
	{
		if (plist != 0)
		{
			V.push_back(plist);
		}
	}
	cout << "不为0的元素已经插入到vector中,共" << V.size() << "个元素." << endl;
	cout << "vector中的元素为:";
	for (auto pvector : V)
	{
		cout << pvector << "  ";
	}
	cout << endl << endl;
	cout << "经测试程序结果符合要求." << endl << endl;

	system("pause");
	return 0;
}

运行截图:



 

 


 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值