本次作业要求如下:
创建一个list容器,放置6个整型数值[0, 1, 30, 20, 10, 0]
- 从后向前打印出容器内的元素
- 向list容器后面添加两个元素,并对容器内的值求和并打印
- 打印链表的中间元素
- 找到不为0的元素,复制到一个vector中并打印vector元素
根据要求需要两种容器,还需要输入输出所以包含了三个头文件,所以搭起了这样的框架
#include
#include
#include
using namespace std;
typedef list INTLIST;
int main()
{
return 0;
}
然后是存6个元素到list,倒着打印。这个地方我为了防止打印的时候程序当掉用了plist = --(L.end())。限定条件没有写,因为如果写迭代器不等于begin的话会少打印一个元素。
INTLIST L;
L.push_front (0);
L.push_back (1);
L.push_back (30);
L.push_back (20);
L.push_back (10);
L.push_back (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不是快指针,而是调用了两次。
第四问其实没东西就是遍历过程中判断,插入,然后打印出来
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;
整个的实现就是这样,
运行截图: