close

老師說有人向他反映上次的作業太簡單汙辱智商,所以他這次出一點有挑戰性的要讓大家寫得開心一點。  

...哪個笨蛋這麼閒啊!(太太冷靜啊 

大略的想法是這樣→3x3矩陣用TextBox來讓使用者輸入數值,由於我嫌棄不加上表格的TextBox(喂)所以TextBox外面還有包<tr>、<td>等標籤,又因為懶得自己建所以就用迴圈動態產生。(PlaceHolder1是我拿來裝矩陣A的容器,PlaceHolder2就是我拿來裝矩陣B的容器了。)

 

版面



TextBox textBox = new TextBox(); textBox.ID = "TextBox" + i.ToString(); 

關鍵的程式碼就長得像上面那樣(?),因為用來跑迴圈計數的i是int型態,在命名的時候當然要改回string型態了。

所以跑完之後的頁面在PlaceHolder裡面會有9個TextBox,所有的id都是TextBox1~9。因為我懶得自己想名字了。

重點然後「(容器)控制項.Controls.Add(new LiteralControl("html標籤");」 真的很好用啊(深受感動)

 

接值


然後在陣列的部分,我用了兩個陣列分別去接A矩陣(PlaceHolder1)和B矩陣(PlaceHolder2)的值。

double[,] marA = new double[3, 3];
double[,] marB = new double[3, 3];
double[,] marC = new double[3, 3];

矩陣C則是拿來存放運算結果。

而因為迴圈內要再重新定義一次ID,所以要先找出那些要接值的TextBox控制項。

TextBox mybox = (TextBox)this.form1.FindControl("TextBox" + m.ToString());m一樣也只是計數器。this意指該..該頁面(?),然後找from1內的控制項,ID是TextBox1~9。

 for (int i = 0; i < 3; i++)
{
  for (int j = 0; j < 3; j++)
 {
  if (m == i * 3 + j + 1) { marA[i, j] = Convert.ToDouble(mybox.Text); }
 }
}

重點之所以m要=i*3+j+1是因為矩陣A[0,0]內存的是TextBox1的值,A[0,1]則是2,A[1,1]則可以推得為5,因此必須加上該限制條件,不然run完整個矩陣全部都存到的是TextBox9的值了。

聰明人大概不會覺得是重點吧,可是我卡了這個盲點卡了整整三小時啊! 


加減乘除運算


這次的加減乘除選擇我放在下拉式選單(ID=arith)內,用 switch (arith.SelectedItem.Value)判定。

加減很簡單,全部都是A[i,j]+B[i,j]或是A[i,j]-B[i,j]。

乘法的部分稍微卡了一下...

for (int i = 0; i < 3; i++) 
{
 for (int j = 0; j < 3; j++)
 {
  for (int m = 0; m < 3; m++)
  {
   marC[i, j] += marA[i, m] * marB[j, m];
  }
 }
}  

矩陣的乘法是被乘矩陣的列項*乘數矩陣的行項並一個一個加起來,也就是說c[0,0]=a[0,0]*b[0,0]+a[0,1]*b[1,0]+a[0,2]*b[2,0],所以

重點C矩陣的i,j項分別決定A、B矩陣的i項和j項,其餘是從0~2(因為是3x3矩陣)

除法的部分,則是A*B的反矩陣,我用行列式值的倒數*[餘因子矩陣的轉置矩陣]這個反矩陣定義去做。

寫了一個方法來傳回反矩陣。

public double[,] invert(double[,] marX)
    {
        double[,] cof = new double[3, 3];
        double[,] marinvert = new double[3, 3];
        double determinat = marX[0, 0] * marX[1, 1] * marX[2, 2] + marX[1, 0] * marX[2, 1] * marX[0, 2] + marX[2, 0] * marX[0, 1] * marX[1, 2] - marX[0, 2] * marX[1, 1] * marX[2, 0] - marX[1, 2] * marX[2, 1] * marX[0, 0] - marX[0, 1] * marX[1, 0] * marX[2, 2];

        cof[0, 0] = (marX[1, 1] * marX[2, 2] - marX[1, 2] * marX[2, 1]);
        cof[0, 1] = (marX[1, 0] * marX[2, 2] - marX[1, 2] * marX[2, 0]) * -1;
        cof[0, 2] = (marX[1, 0] * marX[2, 1] - marX[1, 1] * marX[2, 0]);
        cof[1, 0] = (marX[0, 1] * marX[2, 2] - marX[0, 2] * marX[2, 1]) * -1;
        cof[1, 1] = (marX[0, 0] * marX[2, 2] - marX[0, 2] * marX[2, 0]);
        cof[1, 2] = (marX[0, 0] * marX[2, 1] - marX[0, 1] * marX[2, 0]) * -1;
        cof[2, 0] = (marX[0, 1] * marX[1, 2] - marX[0, 2] * marX[1, 1]);
        cof[2, 1] = (marX[0, 0] * marX[1, 2] - marX[0, 2] * marX[1, 0]) * -1;
        cof[2, 2] = (marX[0, 0] * marX[1, 1] - marX[0, 1] * marX[1, 0]);

 cof矩陣是餘因子矩陣,determinat則是行列式值。用marinvert[j, i] = cof[i, j] / determinat 運算完之後傳回marinvert這個矩陣。

呼叫這個方法傳回反矩陣之後,就跟做乘法一樣了。

for (int i = 0; i < 3; i++) 
{
 for (int j = 0; j < 3; j++)
 {
  for (int m = 0; m < 3; m++)
  {
   marC[i, j] += marA[i, m] * invert(marB)[j, m];
  }
 }
}  

 

 


 


arrow
arrow
    全站熱搜

    赭 發表在 痞客邦 留言(0) 人氣()