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;
}

運行截圖:



 

 


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章