vector类可能的字段:
template <class T>
class vector
{
T *start; // 指向分配的数组首地址(初始为 1KB字节)
T *finish; // 指向紧随向量最后一项之后的位置
T *end_of_storage; // 指向紧随数组占据的最后一个空间之后的位置
};
vector类的一个实现:
vector<double> weights;
weights.push_back(7.3);
// 分配堆中一个存储块(1KB),一个double占据8个字节,就分配了128个double型数组
假设将另外的127个double型插入weights后,finish = end_of_storage意味着分配给weights的当前块用完;
weights.push_back(15.5);
// 如果一个向量对象对应的数组已满且又尝试新的插入,那么这个数组的容量将加倍
对比数组优势:1)可以自动调整大小;2)快速随机访问和尾部插入;
缺点:1)在除尾部之外的单元插入是很慢的(必须移动其他项)
#include <vector>
vector模板类的方法接口:
vector模板类的方法接口:
vector(); // 构造器
vector(const vector<T>& x); // 拷贝构造器
void push_back(const T& x); // 在向量尾部插入 X 的拷贝(可看成insert()方法的特例)
iterator insert(iterator position, const T& x); // 在position所在位置插入 X 的拷贝;
void pop_back(); // 删除向量尾部的项(可看成insert()方法的特例)
iterator erase(iterator position); // 删除position位置的项
iterator erase(iterator _first, iterator _last); // 删除_first 与 _last 之间的所有项
unsigned size() const; // 返回向量中项的数量
bool empty() const; // 向量不包含任何项 ?true : false
T& operator[](unsigned n); // 返回对向量的从开头算起的第 n 项的引用
iterator begin(); // 返回位于向量开头的迭代器
iterator end(); // 返回恰好位于向量最后一项之后位置的迭代器
T& front(); // 返回对这个向量开头项的引用
T& back(); // 返回对向量尾部项的引用。如果该向量为空,则返回值是未定义的
#include <algorithm>
C++的标准模版库(STL)中最重要的头文件之一,提供了大量基于迭代器的非成员模版函数
void reverse(bidirectionalIterator _first, bidirectionalIterator _last );
// 反转双向迭代器 _first 与 _last 之间元素的顺序
#include <ctime>
long time(long *timer); // 参数为 NULL时,返回自 1970 年一月 1 日午夜 (00:00) 到系统时钟之间的秒数
(一个非常长的整数类)头文件very_long_int class.h
#ifndef _VERY_LONG_INT
#define _VERY_LONG_INT
#include <iostream>
#include <vector>
#include <algorithm> // reverse()
using namespace std;
/*----------------------------------------
向量应用:高精度算法 -- 非常长的整数的运算
----------------------------------------*/
class very_long_int
{
vector<char> digits;
public:
// very_long_int() {} // 编译器会自动生成
// very_long_int operator=(const very_long_int& other_very_long); // 编译器会自动生成
// 前置条件: n >= 0
// 后置条件: 返回对象的阶乘
very_long_int factorial(int n) const;
very_long_int operator--(int);
very_long_int operator*(const very_long_int& other_very_long) const;
very_long_int operator+(const very_long_int& other_very_long) const;
// 前置条件: 输入一系列char位,遇到 ‘X’ 结束输入;
// 忽略无效的char、空格和行尾标志;
// 后置条件: very_long包含非常长的整数
friend istream& operator>>(istream& in, very_long_int& very_long);
// 后置条件: 输出very_long
friend ostream& operator<<(ostream& out, const very_long_int& very_long);
};
#endif
(一个非常长的整数类)类实现very_long_int class.cpp
#include "very_long_int class.h"
/*
very_long_int very_long_int::operator=(const very_long_int& other_very_long)
{
digits.erase(digits.begin(), digits.end());
for (int i = 0; i < other_very_long.digits.size(); i++)
digits.push_back(other_very_long.digits[i]);
return *this;
}
*/
very_long_int very_long_int::factorial(int n) const
{
very_long_int temp = *this,
sum = *this;
if (n == 0){
sum.digits.erase(sum.digits.begin(), sum.digits.end()); // 释放sum占用的所有内存
sum.digits.push_back('0'-'0'); // 分配一个字节存储 0
}
else
for (; n != 1; n--)
sum = sum * temp; // 累乘求阶乘
return sum;
}
very_long_int very_long_int::operator--(int)
{
if (digits[digits.size()-1] > 0) // 个位数 > 0
digits[digits.size()-1]--;
else // 个位数 = 0,产生借位
{
unsigned bit = 0; // 向digits[bit]位 借位
for (unsigned i = 1; i < digits.size(); i++)
if (digits[digits.size()-1-i] != 0){
bit = digits.size()-1-i;
break;
}
digits[bit]--;
for (unsigned i = digits.size()-1; i > bit; i--)
digits[i] = 9; // 借位后,低于digits[bit]的所有位 变成9
}
if (digits[0] == 0) // 借位后如果最高位为0,就删除这个最高位
digits.erase(digits.begin());
return *this;
}
very_long_int very_long_int::operator*(const very_long_int& other_very_long) const
{
very_long_int sum = other_very_long;
very_long_int temp = *this;
if ((temp.digits.size() == 1 && temp.digits[0] == 0) ||
(other_very_long.digits.size() == 1 && other_very_long.digits[0] == 0)){
sum.digits.erase(sum.digits.begin(), sum.digits.end()); // 释放sum占用的所有内存
sum.digits.push_back('0'-'0'); // 分配一个字节存储 0
}
else{
while (temp.digits.size() != 1 || temp.digits[0] != 1){
sum = sum + other_very_long; // 累加求积
temp--;
}
}
return sum;
}
very_long_int very_long_int::operator+(const very_long_int& other_very_long) const
{
very_long_int sum; // 和(返回值)
int carry = 0, // 进位值
small_size, // *this和other_very_long对象位数较小者
big_size, // *this和other_very_long对象位数较大者
value; // *this和other_very_long对象位数相加的和
if (digits.size() > other_very_long.digits.size()){
big_size = digits.size();
small_size = other_very_long.digits.size();
}
else{
big_size = other_very_long.digits.size();
small_size = digits.size();
}
vector<char>::const_iterator iter1 = digits.end(),
iter2 = other_very_long.digits.end(); //const_iterator用于遍历const容器
for (int i = 0; i < big_size; i++){
if (i < small_size){
iter1--; iter2--;
value = *iter1 + *iter2 + carry;
carry = value / 10; // 是否产生进位
sum.digits.push_back(value % 10);
} // 个位数为 sum.digits[0],应为 sum.digits[sum.digits.size()-1];
else if (big_size == digits.size()){
iter1--;
value = *iter1 + carry;
carry = value / 10; // 是否产生进位
sum.digits.push_back(value % 10);
}
else if (big_size == other_very_long.digits.size()){
iter2--;
value = *iter2 + carry;
carry = value / 10; // 是否产生进位
sum.digits.push_back(value % 10);
}
}
if (carry == 1) // 是否产生新位
sum.digits.push_back(carry);
reverse(sum.digits.begin(), sum.digits.end()); // 反转sum.digits中各元素的顺序
return sum;
}
istream& operator>>(istream& in, very_long_int& very_long)
{
very_long.digits.erase(very_long.digits.begin(), very_long.digits.end());
// cout << "Please enter a very_long_int data, 'X' to quit:\n"; (提示信息在main())
char ch_temp;
cin >> ch_temp; // 忽略空格和行尾标志
while (ch_temp != 'X'){
if (ch_temp >= '0' && ch_temp <= '9')
very_long.digits.push_back(ch_temp-'0'); // 合法字符转换成数字
cin >> ch_temp;
}
while (very_long.digits[0] == 0 && very_long.digits.size() != 1) // 删除very_long中对应整数前的所有0
very_long.digits.erase(very_long.digits.begin());
return in;
}
ostream& operator<<(ostream& out, const very_long_int& very_long)
{
// cout << "The very_long_int data =\n"; (提示信息在main())
for (unsigned i = 0; i < very_long.digits.size(); i++)
cout << (int)very_long.digits[i];
return out;
}
(一个非常长的整数类)驱动程序test.cpp
#include "very_long_int class.h"
#include <ctime> // time()
int main()
{
very_long_int very_long1, very_long2;
cout << "Please enter a very_long_int data, 'X' to quit:\n";
cin >> very_long1;
cout << "Please enter a very_long_int data, 'X' to quit:\n";
cin >> very_long2;
cout << "(First): " << very_long1 << endl
<< "(Second): " << very_long2 << endl << endl;
very_long_int very_long3;
very_long3 = very_long1 + very_long2;
cout << "(Third = First + Second):\n" << very_long3 << endl << endl;
very_long3--;
cout << "(Third--):\n" << very_long3 << endl << endl;
long start_time, finish_time;
start_time = time(NULL);
cout << "(Fourth = First * Second):\n"
<< very_long1 * very_long2 << endl;
finish_time = time(NULL);
cout << "time = " << finish_time-start_time << " Second.\n\n";
start_time = time(NULL);
cout << "(Fifth = First ^ 5):\n"
<< very_long1.factorial(5) << endl;
finish_time = time(NULL);
cout << "time = " << finish_time-start_time << " Second.\n";
return 0;
}
(一个非常长的整数类)测试:
operator*的重载与 factorial() 是很糟糕的算法,很耗运行时间