#include "VectorCpx.h"
#include <cstdlib>
#include <cstdio>
#include <climits>
#include <limits>
#include <iostream>
#include <fstream>
using namespace std;
/*
第一段是Complex class,除了Complex與VectorCpx之間乘法的operator函式以外,都是用助教提供的
*/
/***********************************constructor***********************************/
Complex::Complex(double _real, double _imag): mReal(_real), mImag(_imag)
{
}
/***********************************constructor***********************************/
/*************************************功能函式************************************/
const double& Complex::real() const
{
return mReal;
}
const double& Complex::imag() const
{
return mImag;
}
void Complex::real(double value)
{
mReal = value;
}
void Complex::imag(double value)
{
mImag = value;
}
/*************************************功能函式************************************/
/************************************重載運算子***********************************/
Complex Complex::operator + (const Complex& cpx)const
{
Complex cpOut;
cpOut.real(mReal + cpx.real());
cpOut.imag(mImag + cpx.imag());
return cpOut;
}
Complex Complex::operator - (const Complex& cpx)const
{
Complex cpOut;
cpOut.real(mReal - cpx.real());
cpOut.imag(mImag - cpx.imag());
return cpOut;
}
Complex Complex::operator * (const Complex& cpx)const
{
Complex cpOut;
cpOut.real( mReal * cpx.real() - mImag * cpx.imag() );
cpOut.imag( mReal * cpx.imag() + mImag * cpx.real() );
return cpOut;
}
VectorCpx Complex::operator * (const VectorCpx& vc)const //Complex*vector的自定義乘法,把每個vector裡的資料都再乘以Complex值。這段要自己寫
{
VectorCpx outVec;
for(unsigned int i = 0; i < vc.size(); i++)
{
Complex cpOut;
cpOut.real( mReal * vc[i].real() - mImag * vc[i].imag() );
cpOut.imag( mReal * vc[i].imag() + mImag * vc[i].real() );
outVec.push_back(cpOut);
}
return outVec;
}
Complex Complex::operator / (const Complex& cpx)const
{
Complex cpOut;
double rDiv = cpx.real() * cpx.real() + cpx.imag() * cpx.imag();
if( rDiv < DBL_MIN) return cpOut;
cpOut.real( (mReal * cpx.real() + mImag * cpx.imag()) / rDiv );
cpOut.imag( (mImag * cpx.real() - mReal * cpx.imag()) / rDiv );
return cpOut;
}
/************************************重載運算子***********************************/
/************************************自定義輸出***********************************/
ostream& operator<<(ostream& ostr, const Complex& cp)
{
ostr << "R:" << cp.real() << ", I:" << cp.imag();
return ostr;
}
/************************************自定義輸出***********************************/
//////////////////////////////////////////////////////VectorCpx//////////////////////////////////////////////////////////////////////
/***********************************constructor***********************************/
VectorCpx::VectorCpx():pCpx(NULL),mSize(0),mCapacity(0) //default constructor,不給預設值的話會造成程式崩潰
{
//耶不用寫
}
VectorCpx::VectorCpx(unsigned size, const Complex& cpx) //constructor
{
int capacity = 1;
while(size > capacity) //一直乘到capacity比size大,因為capacity一定是2的次方因此乘以2
capacity *= 2;
pCpx = new Complex[capacity]; //最後new出一個該大小的新陣列,把給定的Complex值填進去
for(int i = 0; i < size; i++)
pCpx[i] = cpx;
mSize = size;
mCapacity = capacity;
}
VectorCpx::VectorCpx(unsigned capacity) //constructor,因為實在很不爽一定要給資料數量和資料內容才能做vector,所以自己寫了一個只要給capatity就可以做出一個空vector
{
pCpx = new Complex[capacity];
mSize = 0;
mCapacity = capacity;
}
VectorCpx::VectorCpx(const VectorCpx& vc) //copy constructor
{
mSize = vc.mSize;
mCapacity = vc.mCapacity;
pCpx = new Complex[mCapacity];
for(unsigned int i = 0; i < mSize; i++)
pCpx[i] = vc.pCpx[i];
}
VectorCpx::~VectorCpx() //destructor
{
delete[] pCpx;
}
/***********************************constructor***********************************/
/*************************************功能函式************************************/
VectorCpx& VectorCpx::push_back(const Complex& cpx) //這個函式是要把一個值存到vector裡
{
if(mSize == mCapacity) //如果原本的vector已經滿了,那就做一個新的vector,大小會是原本vector兩倍
{
VectorCpx newVec(mCapacity + 1,cpx); //這裡的mCapacity+1,事實上等於newVec的mSize。為了省事全部填入cpx
for(unsigned int i = 0; i < mSize; i++) //然後除了位於位置mCapacity+1上的cpx,前面全部換回原本pCpx vector裡的所有值
newVec.pCpx[i] = pCpx[i];
delete[] pCpx; //別忘記砍掉它,它已經沒有利用價值了
/********************************************************************************/
/**/memcpy(this, &newVec , sizeof(VectorCpx)); /**/
/**/newVec.pCpx = NULL; /**/
/** **/
/**因為原本我的程式碼在delete[] pCpx之後,pCpx指向的記憶體位置裡的資料仍然沒變 **/
/**因此利用這段程式碼 **/
/** memcpy(this, &newVec , sizeof(VectorCpx)); **/
/** newVec.pCpx = NULL; **/
/**來把newVec.pCpx指向非法位址,就可以把newVec.pCpx留在v1.pCpx **/
/**以避免return時newVec被delete掉 **/
/** **/
/**delete只是告訴OS這個空間不再使用 並不會清掉空間裡的資料 **/
/**memcpy幫你把newVec的資料複製到你目前的這個物件 **/
/**把指標指向NULL只是讓你不小心存取到這個指標時看得出錯誤 **/
/**提取NULL指標的內容會產生runtime error 讓你看得出錯誤 **/
/**newVec是local variable所以離開function後就會消失 **/
/**return一個local variable的reference不合法的 **/
/********************************************************************************/
return newVec;
}
else
{
pCpx[mSize] = cpx; //沒滿的話就直接扔進去就好
mSize++;
//cout << this << endl;
return *this;
}
}
VectorCpx& VectorCpx::resize(unsigned place, const Complex& cpx)
{
/*
這個函式會傳入一個整數place,可能還會有一個Complex cpx。
如果傳入的整數比vector的大小還大,那就把vector擴張到適合的大小,並且從原本的資料之後一直到place的位置都填入cpx,如果當初沒有傳入cpx則填0
如果傳入的整數比vector裡面資料個數還少,那vector大小不變,但原本的資料從尾開始砍到剩下符合的數量
*/
if(place >= mSize)
{
VectorCpx newVecBig(place, cpx);
for(unsigned int i = 0; i < mSize; i++)
newVecBig.pCpx[i] = pCpx[i];
delete[] pCpx;
memcpy(this, &newVecBig , sizeof(VectorCpx));
newVecBig.pCpx = NULL;
return newVecBig;
}
else
{
VectorCpx newVecSmall(mCapacity);
for(unsigned int i = 0; i < place; i++)
newVecSmall.pCpx[i] = pCpx[i];
delete[] pCpx;
newVecSmall.mSize = place;
memcpy(this, &newVecSmall , sizeof(VectorCpx));
newVecSmall.pCpx = NULL;
return newVecSmall;
}
}
unsigned VectorCpx::size() const //回傳size大小
{
return mSize;
}
unsigned VectorCpx::capacity() const //回傳capacity大小
{
return mCapacity;
}
/*************************************功能函式************************************/
/************************************重載運算子***********************************/
Complex VectorCpx::operator*(const VectorCpx& vc) const //vector*vector的自定義乘法,把每個香對應位置的Complex值乘起來之後全部加起來回傳,有多出來的不用管他
{
Complex result;
if(mSize >= vc.mSize)
{
for(unsigned int i = 0; i < vc.mSize; i++)
result = result + pCpx[i] * vc.pCpx[i];
}
else
{
for(unsigned int i = 0; i < mSize; i++)
result = result + pCpx[i] * vc.pCpx[i];
}
return result;
}
VectorCpx VectorCpx::operator*(const Complex& cpx) const //vector*Complex的自定義乘法,把每個vector裡的資料都再乘以Complex值
{
VectorCpx copyVec = *this; //這裡不能直接用pCpx[i] = pCpx[i] * cpx然後return *this的方法,因為會造成被乘vector的值改變
for(unsigned int i = 0; i < mSize; i++)
copyVec[i] = pCpx[i] * cpx;
return copyVec;
}
Complex& VectorCpx::operator[](const int& place) const //vector的自定義中括號,vc[i]即可得到位於vector vc中i位置的值
{
if(place < 0) //如果輸入位置小於0,則自動變成0
return pCpx[0];
else if(place >= mSize) //如果輸入位置超過資料數目,則扔出最後一筆
return pCpx[mSize - 1];
else
return pCpx[place];
}
VectorCpx VectorCpx::operator=(const VectorCpx& vc) //vector的自定義=符號
{
mSize = vc.mSize;
int capacity = 1;
while(mSize > capacity) //一直乘到capacity比size大,因為capacity一定是2的次方因此乘以2
capacity *= 2;
mCapacity = capacity;
delete[] pCpx; //先把原本的pCpx砍掉之後,再new一個新的pCpx出來存資料
pCpx = new Complex[mCapacity];
for(unsigned int i = 0; i < mSize; i++)
pCpx[i] = vc.pCpx[i];
return *this;
}
/************************************重載運算子***********************************/
/************************************自定義輸出***********************************/
ostream& operator<<(ostream& ostr, const VectorCpx vc)
{
unsigned int size = vc.size();
if(size==0) //由於size和vc.size()都是unsigned型態,如果直接在下面的for迴圈0-1,會直接跳到最大值去,造成程式無法結束,因此要另外設一個size==0的if判斷式
{
ostr << endl;
return ostr;
}
for(unsigned int i = 0; i < size - 1; i++)
ostr << vc[i] << "; ";
ostr << vc[size - 1] << endl;
return ostr;
}
/************************************自定義輸出***********************************/