2013年9月5日 星期四

Action! Round 1

問題:寫一個程式,提示使用者輸入兩個向量,計算它們的內積(inner product)。例如,
    [1, 0] * [1, 1] = 1
    [1, 1, 0] * [0, 1, 1] = 1
    [1,0] 與 [1,1,0] 提示無法計算內積
提示使用者可重複執行或結束程式。

這個問題相當單純,並不需要拆解成子問題。以下實施第一輪How to solve it 四個步驟解題。

1. U:如題目中的例子,問題的輸入為兩個向量,維度未必相同;問題的輸出則如下:當輸入向量維度相同時,輸出向量的內積,否則提示無法計算。

2. D:列出解決該問題所需做的所有程式待辦工作及其驗證方法。初步列出的工作如下:

T1. 撰寫函數,使其能讀入向量。
T2. 撰寫函數,接受兩個向量,計算內積,或傳回錯誤訊息。
T3. 撰寫主程式,使其能讀入兩個向量、進行內積計算、呈現結果。

每個工作的設計表示我們對實施的方有了某種決定。工作T1表示,我們決定要「讀入一個向量,並以適當的方式表達所讀入的向量。

如何驗證T1?我們先以輸出向量的方式,自行目視驗證;因此增加T4

T4. 撰寫函數,接受一個向量,並加以輸出。

我們暫時以{T1,T2,T3,T4}為待辦工作。這四個工作並無特定的先後順序;理論上,你可以將這四個工作交給四個人同時去做。

3. C:在這個步驟裡,你須完成{T1,T2,T3,T4}這四樣待辦工作。雖然你可自由挑選,但我建議你一次選一個工作加以完成並驗證。

以這個題目而言,我們將先挑看似最簡單的工作T4先加以完成。問題來了,我們需要一個協助驗證T4的手段。一個直接可行的方法即是在主程式呼叫它,在此先借用main。程式在Dev C++ 5.4.2 下完成。

#include <iostream>

using namespace std;

/* T4 Writing [0,1] */
void outputVector(double v[], int dim){
cout << "[";
for (int i=0; i<dim-1; ++i)
cout << v[i] << ",";
cout << v[dim-1] << "]" << endl;
return;
}

int main(int argc, char** argv) {


 /* scratch main: help to code up the tasks */

double a[2]={0,0};
outputVector(a,2);
    
    return 0;
}
程式中除了cin 與 cout為C++提供輸入、輸出的物件之外,只使用C language features。函式 outputVector (double v[], int dim) 以array v表示題目中的數學向量,dim為其維度。編譯、執行上述程式即可判斷T4是否初步完成。我說初步完成的原因是後續做其他工作時,可能需要修改其他初步程式。

接下來完成T1、T2與T3,程式如下:

#include <iostream>
#include <stdlib.h>

using namespace std;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

/* T4 Writing [0,1] */
void outputVector(double v[], int dim){
    cout << "[";
    for (int i=0; i<dim-1; ++i)
cout << v[i] << ",";
cout << v[dim-1] << "]" << endl;
return;
}

/*T1 Reading [0,1]*/
void inputVector(double v[], int dim){
cout << "input a vector of dimension " << dim <<" :";
char s;
cin >> s;
for (int i=0; i<dim-1; ++i)
cin >> v[i] >> s;
cin >> v[dim-1] >> s;

return;
}

/* T2 inner product */
double innerProduct(double u[], int dim_u, double v[], int dim_v){
double p=0;
if (dim_u != dim_v){
cout << "Dimension error!" << endl;
exit(EXIT_FAILURE);
}
else {
for (int i=0; i < dim_u; ++i){
p += u[i]*v[i];
}
return p;  
}
}

/* T3: main */
int main(int argc, char** argv) {

/* scratch main: help to code up the tasks
double a[2]={0,0};
outputVector(a,2);

double b[2];
inputVector(b,2);
outputVector(b,2);

cout << "inner product is " << innerProduct(a,2,b,2) << endl;

double c[3];
inputVector(c,3);
outputVector(c,3);
cout << "inner product is " << innerProduct(b,2,c,3) << endl;
*/
cout <<"This is vector inner product program.\n"; 

char ch = 'c';
while (ch == 'c'){
int dim_u, dim_v;
double *u, *v;
cout <<"Input dimension of first vector:";
cin >> dim_u;
u = new double[dim_u];
inputVector(u,dim_u);
outputVector(u,dim_u);

cout <<"Now input dimension of second vector:";
cin >> dim_v;
v = new double[dim_v];
inputVector(v,dim_v);
outputVector(v,dim_v);

cout << "inner product is " << innerProduct(u,dim_u,v,dim_v) << endl;

delete [] u;
delete [] v;

cout << "Type c to continue, anything else to quit:";
cin >> ch;
cout << endl;
}
cout << "bye..." << endl;
return 0;
}


執行程式畫面如下:
















4. L:程式執行畫面看起來似乎有達到要求?就算有,程式有無可改善之處下回待續。

© Y C Cheng, 2013. All rights reserved.

沒有留言:

張貼留言