Деян Йосифов

 Personal Website & Blog

Дефиниране на клас Матрица – C# – Част 2 – Задача 6 – Multidimensional Arrays

Written By: Деян - Feb• 16•13

Условието на задачата е:
6.* Write a class Matrix, to holds a matrix of integers. Overload the operators for adding, subtracting and multiplying of matrices, indexer for accessing the matrix content and ToString().

Тази задача лично на мен ми беше изключително полезна и интересна, тъй като за първи път се сблъсках с дефинирането на клас до детайли като дефиниране на оператор (+, – и т.н.), както и дефиниране на индексатор. За да се имплементира коректно поведението на матриците според установените в математиката дефиниции, е необходимо да се подходи с внимание към проверките при различните оператори, свързани с размерностите на самите матрици, a също така е важна и капсулацията на полетата. Към операциите събиране, изваждане и умножение съм направил проверка за размерностите на матриците и хвърлям изключение ако има проблем с размерите (при събиране и изваждане дименсиите на двете матрици трябва да са равни, а при умножението броя колони на първата матрица трябва да е равен на броя редове на втората). Полетата на класа matrix, rows, columns са private, за да може да са достъпни единствено през публичното свойство Value, което съответно се ползва и от конструкторите и операторите. По този начин си гарантирам че няма да стане някаква грешка и някой да промени информацията за броя на редовете примерно без реално да е променил броя на редовете на самата матрица. В Main метода съм направил няколко теста за различните оператори и случаи.

Ето и примерната имплементация:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
using System;
using System.Text;
 
class Matrix
{
    private int[,] matrix;
    private int rows;
    private int columns;
 
    public int[,] Value
    {
        get
        {
            return this.matrix;
        }
        set
        {
            this.matrix = value;
            this.rows = value.GetLength(0);
            this.columns = value.GetLength(1);
        }
    }
 
    public int Rows
    {
        get
        {
            return this.rows;
        }
    }
 
    public int Columns
    {
        get
        {
            return this.columns;
        }
    }
 
    public Matrix(int[,] matrix)
    {
        this.Value = (int[,])matrix.Clone();
    }
 
    public Matrix(int rows, int cols) : this(new int[rows, cols]) { }
 
    public static Matrix operator +(Matrix a, Matrix b)
    {
        if (a.Rows != b.Rows || a.Columns != b.Columns)
        {
            throw new FormatException("Matrixes must have same dimensions!");
        }
        else
        {
            Matrix result = new Matrix(a.Rows, a.Columns);
            for (int i = 0; i < a.Rows; i++)
            {
                for (int j = 0; j < a.Columns; j++)
                {
                    result[i, j] = a[i, j] + b[i, j];
                }
            }
            return result;
        }
    }
 
    public static Matrix operator -(Matrix a, Matrix b)
    {
        if (a.Rows != b.Rows || a.Columns != b.Columns)
        {
            throw new FormatException("Matrixes must have same dimensions!");
        }
        else
        {
            Matrix result = new Matrix(a.Rows, a.Columns);
            for (int i = 0; i < a.Rows; i++)
            {
                for (int j = 0; j < a.Columns; j++)
                {
                    result[i, j] = a[i, j] - b[i, j];
                }
            }
            return result;
        }
    }
 
    public static Matrix operator *(Matrix a, Matrix b)
    {
        if (a.Columns != b.Rows)
        {
            throw new FormatException("First matrix columns number must be equal to second matrix rows number!");
        }
        else
        {
            Matrix result = new Matrix(a.Rows, b.Columns);
            for (int i = 0; i < a.Rows; i++)
            {
                for (int j = 0; j < b.Columns; j++)
                {
                    for (int k = 0; k < a.Columns; k++)
                    {
                        result[i, j] += a[i, k] * b[k, j];
                    }
                }
            }
            return result;
        }
    }
 
    public int this[int i, int j]
    {
        get
        {
            return this.Value[i, j];
        }
        set
        {
            this.Value[i, j] = value;
        }
    }
 
    public override string ToString()
    {
        StringBuilder result = new StringBuilder();
        result.Append(this[0, 0]);
        for (int j = 1; j < this.Columns; j++)
        {
            result.AppendFormat(" {0}", this[0, j]);
        }
        for (int i = 1; i < this.Rows; i++)
        {
            result.AppendFormat("\n{0}", this[i, 0]);
            for (int j = 1; j < this.Columns; j++)
            {
                result.AppendFormat(" {0}", this[i, j]);
            }
        }
        return result.ToString();
    }
 
    static void Main()
    {
        Matrix a = new Matrix(3, 4);
        a.Value[1, 1] = 5;
        Matrix b = new Matrix(3, 4);
        b.Value[1, 1] = 3;
        Matrix c = new Matrix(4, 2);
        c.Value[1, 1] = 3;
 
        Console.WriteLine("a.Rows: {0}; a.Columns: {1}", a.Rows, a.Columns);
        Console.WriteLine(a);
        Console.WriteLine();
 
        Console.WriteLine("b.Rows: {0}; b.Columns: {1}", b.Rows, b.Columns);
        Console.WriteLine(b);
        Console.WriteLine();
 
        Console.WriteLine("c.Rows: {0}; c.Columns: {1}", c.Rows, c.Columns);
        Console.WriteLine(c);
        Console.WriteLine();
 
        Console.WriteLine("\na+b=\n{0}", a + b);
        Console.WriteLine("\na-b=\n{0}", a - b);
        Console.WriteLine("\na*c=\n{0}", a * c);
 
        Console.WriteLine("\na+c=");
        try
        {
            Console.WriteLine("\na+c=\n{0}", a + c);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
 
        Console.WriteLine("\nb-c=");
        try
        {
            Console.WriteLine("\nb-c=\n{0}", b - c);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
 
        Console.WriteLine("\na*b=");
        try
        {
            Console.WriteLine("\na*b=\n{0}", a * b);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
 
        int [,] v0 = {{4, 8, 15, 16, 23, 42}};
        Matrix v = new Matrix(v0);
        int[,] t0 = { { 1 }, { 1 }, { 1 }, { 1 }, { 1 }, { 1 } };
        Matrix t = new Matrix(t0);
 
        Console.WriteLine();
        Console.WriteLine("v.Rows: {0}; v.Columns: {1}", v.Rows, v.Columns);
        Console.WriteLine(v);
        Console.WriteLine();
 
        Console.WriteLine("t.Rows: {0}; t.Columns: {1}", t.Rows, t.Columns);
        Console.WriteLine(t);
        Console.WriteLine();
 
        Console.WriteLine("\nv*t=\n{0}", v * t);
 
        Console.WriteLine();
        int i = 0;
        int j = 0;
        Console.WriteLine("(v*t)[{1},{2}]={0}", (v * t)[i, j], i, j);
    }
}

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

One Comment

  1. prestissimo says:

    Great site you have here.. It’s difficult to find quality writing like yours these days.
    I really appreciate individuals like you! Take care!!

Leave a Reply to prestissimo Cancel reply

Your email address will not be published. Required fields are marked *