fork download
  1. #include "VectorCpx.h"
  2. #include <cstdlib>
  3. #include <cstdio>
  4. #include <climits>
  5. #include <limits>
  6. #include <iostream>
  7. #include <fstream>
  8.  
  9. using namespace std;
  10.  
  11. /*
  12. 第一段是Complex class,除了Complex與VectorCpx之間乘法的operator函式以外,都是用助教提供的
  13. */
  14. /***********************************constructor***********************************/
  15. Complex::Complex(double _real, double _imag): mReal(_real), mImag(_imag)
  16. {
  17.  
  18. }
  19. /***********************************constructor***********************************/
  20.  
  21. /*************************************功能函式************************************/
  22. const double& Complex::real() const
  23. {
  24. return mReal;
  25. }
  26.  
  27. const double& Complex::imag() const
  28. {
  29. return mImag;
  30. }
  31.  
  32. void Complex::real(double value)
  33. {
  34. mReal = value;
  35. }
  36.  
  37. void Complex::imag(double value)
  38. {
  39. mImag = value;
  40. }
  41. /*************************************功能函式************************************/
  42.  
  43. /************************************重載運算子***********************************/
  44. Complex Complex::operator + (const Complex& cpx)const
  45. {
  46. Complex cpOut;
  47. cpOut.real(mReal + cpx.real());
  48. cpOut.imag(mImag + cpx.imag());
  49. return cpOut;
  50. }
  51.  
  52. Complex Complex::operator - (const Complex& cpx)const
  53. {
  54. Complex cpOut;
  55. cpOut.real(mReal - cpx.real());
  56. cpOut.imag(mImag - cpx.imag());
  57. return cpOut;
  58. }
  59.  
  60. Complex Complex::operator * (const Complex& cpx)const
  61. {
  62. Complex cpOut;
  63. cpOut.real( mReal * cpx.real() - mImag * cpx.imag() );
  64. cpOut.imag( mReal * cpx.imag() + mImag * cpx.real() );
  65. return cpOut;
  66. }
  67.  
  68. VectorCpx Complex::operator * (const VectorCpx& vc)const //Complex*vector的自定義乘法,把每個vector裡的資料都再乘以Complex值。這段要自己寫
  69. {
  70. VectorCpx outVec;
  71.  
  72. for(unsigned int i = 0; i < vc.size(); i++)
  73. {
  74. Complex cpOut;
  75. cpOut.real( mReal * vc[i].real() - mImag * vc[i].imag() );
  76. cpOut.imag( mReal * vc[i].imag() + mImag * vc[i].real() );
  77. outVec.push_back(cpOut);
  78. }
  79.  
  80. return outVec;
  81. }
  82.  
  83. Complex Complex::operator / (const Complex& cpx)const
  84. {
  85. Complex cpOut;
  86. double rDiv = cpx.real() * cpx.real() + cpx.imag() * cpx.imag();
  87. if( rDiv < DBL_MIN) return cpOut;
  88. cpOut.real( (mReal * cpx.real() + mImag * cpx.imag()) / rDiv );
  89. cpOut.imag( (mImag * cpx.real() - mReal * cpx.imag()) / rDiv );
  90. return cpOut;
  91. }
  92. /************************************重載運算子***********************************/
  93.  
  94. /************************************自定義輸出***********************************/
  95. ostream& operator<<(ostream& ostr, const Complex& cp)
  96. {
  97. ostr << "R:" << cp.real() << ", I:" << cp.imag();
  98. return ostr;
  99. }
  100. /************************************自定義輸出***********************************/
  101.  
  102.  
  103. //////////////////////////////////////////////////////VectorCpx//////////////////////////////////////////////////////////////////////
  104.  
  105.  
  106. /***********************************constructor***********************************/
  107. VectorCpx::VectorCpx():pCpx(NULL),mSize(0),mCapacity(0) //default constructor,不給預設值的話會造成程式崩潰
  108. {
  109. //耶不用寫
  110. }
  111.  
  112. VectorCpx::VectorCpx(unsigned size, const Complex& cpx) //constructor
  113. {
  114. int capacity = 1;
  115. while(size > capacity) //一直乘到capacity比size大,因為capacity一定是2的次方因此乘以2
  116. capacity *= 2;
  117.  
  118. pCpx = new Complex[capacity]; //最後new出一個該大小的新陣列,把給定的Complex值填進去
  119. for(int i = 0; i < size; i++)
  120. pCpx[i] = cpx;
  121.  
  122. mSize = size;
  123. mCapacity = capacity;
  124. }
  125.  
  126. VectorCpx::VectorCpx(unsigned capacity) //constructor,因為實在很不爽一定要給資料數量和資料內容才能做vector,所以自己寫了一個只要給capatity就可以做出一個空vector
  127. {
  128. pCpx = new Complex[capacity];
  129. mSize = 0;
  130. mCapacity = capacity;
  131. }
  132.  
  133. VectorCpx::VectorCpx(const VectorCpx& vc) //copy constructor
  134. {
  135. mSize = vc.mSize;
  136. mCapacity = vc.mCapacity;
  137.  
  138. pCpx = new Complex[mCapacity];
  139.  
  140. for(unsigned int i = 0; i < mSize; i++)
  141. pCpx[i] = vc.pCpx[i];
  142. }
  143.  
  144. VectorCpx::~VectorCpx() //destructor
  145. {
  146. delete[] pCpx;
  147. }
  148. /***********************************constructor***********************************/
  149.  
  150. /*************************************功能函式************************************/
  151. VectorCpx& VectorCpx::push_back(const Complex& cpx) //這個函式是要把一個值存到vector裡
  152. {
  153. if(mSize == mCapacity) //如果原本的vector已經滿了,那就做一個新的vector,大小會是原本vector兩倍
  154. {
  155. VectorCpx newVec(mCapacity + 1,cpx); //這裡的mCapacity+1,事實上等於newVec的mSize。為了省事全部填入cpx
  156. for(unsigned int i = 0; i < mSize; i++) //然後除了位於位置mCapacity+1上的cpx,前面全部換回原本pCpx vector裡的所有值
  157. newVec.pCpx[i] = pCpx[i];
  158.  
  159. delete[] pCpx; //別忘記砍掉它,它已經沒有利用價值了
  160.  
  161. /********************************************************************************/
  162. /**/memcpy(this, &newVec , sizeof(VectorCpx)); /**/
  163. /**/newVec.pCpx = NULL; /**/
  164. /** **/
  165. /**因為原本我的程式碼在delete[] pCpx之後,pCpx指向的記憶體位置裡的資料仍然沒變 **/
  166. /**因此利用這段程式碼 **/
  167. /** memcpy(this, &newVec , sizeof(VectorCpx)); **/
  168. /** newVec.pCpx = NULL; **/
  169. /**來把newVec.pCpx指向非法位址,就可以把newVec.pCpx留在v1.pCpx **/
  170. /**以避免return時newVec被delete掉 **/
  171. /** **/
  172. /**delete只是告訴OS這個空間不再使用 並不會清掉空間裡的資料 **/
  173. /**memcpy幫你把newVec的資料複製到你目前的這個物件 **/
  174. /**把指標指向NULL只是讓你不小心存取到這個指標時看得出錯誤 **/
  175. /**提取NULL指標的內容會產生runtime error 讓你看得出錯誤 **/
  176. /**newVec是local variable所以離開function後就會消失 **/
  177. /**return一個local variable的reference不合法的 **/
  178. /********************************************************************************/
  179.  
  180. return newVec;
  181. }
  182. else
  183. {
  184. pCpx[mSize] = cpx; //沒滿的話就直接扔進去就好
  185. mSize++;
  186. //cout << this << endl;
  187. return *this;
  188. }
  189. }
  190.  
  191. VectorCpx& VectorCpx::resize(unsigned place, const Complex& cpx)
  192. {
  193. /*
  194. 這個函式會傳入一個整數place,可能還會有一個Complex cpx。
  195. 如果傳入的整數比vector的大小還大,那就把vector擴張到適合的大小,並且從原本的資料之後一直到place的位置都填入cpx,如果當初沒有傳入cpx則填0
  196. 如果傳入的整數比vector裡面資料個數還少,那vector大小不變,但原本的資料從尾開始砍到剩下符合的數量
  197. */
  198. if(place >= mSize)
  199. {
  200. VectorCpx newVecBig(place, cpx);
  201.  
  202. for(unsigned int i = 0; i < mSize; i++)
  203. newVecBig.pCpx[i] = pCpx[i];
  204.  
  205. delete[] pCpx;
  206.  
  207. memcpy(this, &newVecBig , sizeof(VectorCpx));
  208. newVecBig.pCpx = NULL;
  209.  
  210. return newVecBig;
  211. }
  212. else
  213. {
  214. VectorCpx newVecSmall(mCapacity);
  215.  
  216. for(unsigned int i = 0; i < place; i++)
  217. newVecSmall.pCpx[i] = pCpx[i];
  218.  
  219. delete[] pCpx;
  220. newVecSmall.mSize = place;
  221.  
  222. memcpy(this, &newVecSmall , sizeof(VectorCpx));
  223. newVecSmall.pCpx = NULL;
  224.  
  225. return newVecSmall;
  226. }
  227. }
  228.  
  229. unsigned VectorCpx::size() const //回傳size大小
  230. {
  231. return mSize;
  232. }
  233.  
  234. unsigned VectorCpx::capacity() const //回傳capacity大小
  235. {
  236. return mCapacity;
  237. }
  238. /*************************************功能函式************************************/
  239.  
  240. /************************************重載運算子***********************************/
  241. Complex VectorCpx::operator*(const VectorCpx& vc) const //vector*vector的自定義乘法,把每個香對應位置的Complex值乘起來之後全部加起來回傳,有多出來的不用管他
  242. {
  243. Complex result;
  244.  
  245. if(mSize >= vc.mSize)
  246. {
  247. for(unsigned int i = 0; i < vc.mSize; i++)
  248. result = result + pCpx[i] * vc.pCpx[i];
  249. }
  250. else
  251. {
  252. for(unsigned int i = 0; i < mSize; i++)
  253. result = result + pCpx[i] * vc.pCpx[i];
  254. }
  255.  
  256. return result;
  257. }
  258.  
  259. VectorCpx VectorCpx::operator*(const Complex& cpx) const //vector*Complex的自定義乘法,把每個vector裡的資料都再乘以Complex值
  260. {
  261. VectorCpx copyVec = *this; //這裡不能直接用pCpx[i] = pCpx[i] * cpx然後return *this的方法,因為會造成被乘vector的值改變
  262.  
  263. for(unsigned int i = 0; i < mSize; i++)
  264. copyVec[i] = pCpx[i] * cpx;
  265.  
  266. return copyVec;
  267. }
  268.  
  269. Complex& VectorCpx::operator[](const int& place) const //vector的自定義中括號,vc[i]即可得到位於vector vc中i位置的值
  270. {
  271. if(place < 0) //如果輸入位置小於0,則自動變成0
  272. return pCpx[0];
  273. else if(place >= mSize) //如果輸入位置超過資料數目,則扔出最後一筆
  274. return pCpx[mSize - 1];
  275. else
  276. return pCpx[place];
  277. }
  278.  
  279. VectorCpx VectorCpx::operator=(const VectorCpx& vc) //vector的自定義=符號
  280. {
  281. mSize = vc.mSize;
  282.  
  283. int capacity = 1;
  284. while(mSize > capacity) //一直乘到capacity比size大,因為capacity一定是2的次方因此乘以2
  285. capacity *= 2;
  286.  
  287. mCapacity = capacity;
  288.  
  289. delete[] pCpx; //先把原本的pCpx砍掉之後,再new一個新的pCpx出來存資料
  290.  
  291. pCpx = new Complex[mCapacity];
  292. for(unsigned int i = 0; i < mSize; i++)
  293. pCpx[i] = vc.pCpx[i];
  294.  
  295. return *this;
  296. }
  297. /************************************重載運算子***********************************/
  298.  
  299. /************************************自定義輸出***********************************/
  300. ostream& operator<<(ostream& ostr, const VectorCpx vc)
  301. {
  302. unsigned int size = vc.size();
  303.  
  304. if(size==0) //由於size和vc.size()都是unsigned型態,如果直接在下面的for迴圈0-1,會直接跳到最大值去,造成程式無法結束,因此要另外設一個size==0的if判斷式
  305. {
  306. ostr << endl;
  307. return ostr;
  308. }
  309.  
  310. for(unsigned int i = 0; i < size - 1; i++)
  311. ostr << vc[i] << "; ";
  312.  
  313. ostr << vc[size - 1] << endl;
  314.  
  315. return ostr;
  316. }
  317. /************************************自定義輸出***********************************/
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:1:23: fatal error: VectorCpx.h: No such file or directory
compilation terminated.
stdout
Standard output is empty