-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMatrix.cpp
231 lines (200 loc) · 6.56 KB
/
Matrix.cpp
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#include <cassert>
#include "Matrix.h"
// REQUIRES: mat points to a Matrix
// 0 < width && width <= MAX_MATRIX_WIDTH
// 0 < height && height <= MAX_MATRIX_HEIGHT
// MODIFIES: *mat
// EFFECTS: Initializes *mat as a Matrix with the given width and height.
// NOTE: Do NOT use new or delete here.
void Matrix_init(Matrix* mat, int width, int height)
{
//assert(false);
(*mat).width = width;
(*mat).height = height;
}
// REQUIRES: mat points to a valid Matrix
// MODIFIES: os
// EFFECTS: First, prints the width and height for the Matrix to os:
// WIDTH [space] HEIGHT [newline]
// Then prints the rows of the Matrix to os with one row per line.
// Each element is followed by a space and each row is followed
// by a newline. This means there will be an "extra" space at
// the end of each line.
void Matrix_print(const Matrix* mat, std::ostream& os)
{
//assert(false);
os << (*mat).width << " " << (*mat).height << "\n";
const int *ptr = (*mat).data;
while(ptr < (*mat).data + (*mat).width * (*mat).height)
{
if((ptr - (*mat).data) % (*mat).width == (*mat).width - 1)
{
os << *ptr << " " << "\n";
}
else
{
os << *ptr << " ";
}
++ptr;
}
}
// REQUIRES: mat points to an valid Matrix
// EFFECTS: Returns the width of the Matrix.
int Matrix_width(const Matrix* mat)
{
//assert(false);
return (*mat).width;
}
// REQUIRES: mat points to a valid Matrix
// EFFECTS: Returns the height of the Matrix.
int Matrix_height(const Matrix* mat)
{
//assert(false);
return (*mat).height;
}
// REQUIRES: mat points to a valid Matrix
// ptr points to an element in the Matrix
// EFFECTS: Returns the row of the element pointed to by ptr.
int Matrix_row(const Matrix* mat, const int* ptr)
{
//assert(false);
int row = (ptr - (*mat).data) / (*mat).width;
return row;
}
// REQUIRES: mat points to a valid Matrix
// ptr point to an element in the Matrix
// EFFECTS: Returns the column of the element pointed to by ptr.
int Matrix_column(const Matrix* mat, const int* ptr)
{
//assert(false);
int col = (ptr - (*mat).data) % (*mat).width;
return col;
}
// REQUIRES: mat points to a valid Matrix
// 0 <= row && row < Matrix_height(mat)
// 0 <= column && column < Matrix_width(mat)
//
// MODIFIES: (The returned pointer may be used to modify an
// element in the Matrix.)
// EFFECTS: Returns a pointer to the element in the Matrix
// at the given row and column.
int* Matrix_at(Matrix* mat, int row, int column)
{
// assert(false);
int index = (row * (*mat).width) + column;
int *address = &(*mat).data[index];
return address;
}
// REQUIRES: mat points to a valid Matrix
// 0 <= row && row < Matrix_height(mat)
// 0 <= column && column < Matrix_width(mat)
//
// EFFECTS: Returns a pointer-to-const to the element in
// the Matrix at the given row and column.
const int* Matrix_at(const Matrix* mat, int row, int column)
{
// assert(false);
const int index = (row * (*mat).width) + column;
const int *ptr = (*mat).data;
const int *address = (ptr + index);
return address;
}
// REQUIRES: mat points to a valid Matrix
// MODIFIES: *mat
// EFFECTS: Sets each element of the Matrix to the given value.
void Matrix_fill(Matrix* mat, int value)
{
// assert(false);
int *fill = (*mat).data;
while(fill < (*mat).data + (*mat).width * (*mat).height)
{
*fill = value;
++fill;
}
}
// REQUIRES: mat points to a valid Matrix
// MODIFIES: *mat
// EFFECTS: Sets each element on the border of the Matrix to
// the given value. These are all elements in the first/last
// row or the first/last column.
void Matrix_fill_border(Matrix* mat, int value)
{
//assert(false);
int *ptr = (*mat).data;
//int index = ptr - (*mat).data;
int totalsize = (*mat).width * (*mat).height;
while(ptr < (*mat).data + (*mat).width * (*mat).height)
{
if(Matrix_column(mat, ptr) == (*mat).width - 1 || Matrix_column(mat, ptr) == 0 || ptr > ((*mat).data + totalsize - (*mat).width - 1) || ptr < (*mat).data + (*mat).width)
{
*ptr = value;
}
++ptr;
}
}
// REQUIRES: mat points to a valid Matrix
// EFFECTS: Returns the value of the maximum element in the Matrix
int Matrix_max(const Matrix* mat)
{
//assert(false);
const int *ptr = (*mat).data;
int max = *ptr;
while(ptr < (*mat).data + (*mat).width * (*mat).height)
{
if(*ptr > max)
{
max = *ptr;
}
++ptr;
}
return max;
}
// REQUIRES: mat points to a valid Matrix
// 0 <= row && row < Matrix_height(mat)
// 0 <= column_start && column_end <= Matrix_width(mat)
// column_start < column_end
// EFFECTS: Returns the column of the element with the minimal value
// in a particular region. The region is defined as elements
// in the given row and between column_start (inclusive) and
// column_end (exclusive).
// If multiple elements are minimal, returns the column of
// the leftmost one.
int Matrix_column_of_min_value_in_row(const Matrix* mat, int row, int column_start, int column_end)
{
// assert(false);
int min = Matrix_max(mat);
const int *ptr = (*mat).data;
int col;
ptr = Matrix_at(mat, row, column_start);
while(ptr < Matrix_at(mat, row, column_end + 1))
{
if(*ptr < min){
min = *ptr;
col = Matrix_column(mat,ptr);
}
++ptr;
}
return col;
}
// REQUIRES: mat points to a valid Matrix
// 0 <= row && row < Matrix_height(mat)
// 0 <= column_start && column_end <= Matrix_width(mat)
// column_start < column_end
// EFFECTS: Returns the minimal value in a particular region. The region
// is defined as elements in the given row and between
// column_start (inclusive) and column_end (exclusive).
int Matrix_min_value_in_row(const Matrix* mat, int row, int column_start, int column_end)
{
//assert(false);
// int min = Matrix_max(mat);
// const int *ptr = (*mat).data;
// ptr = Matrix_at(mat, row, column_start);
// while(ptr < Matrix_at(mat, row, column_end + 1))
// {
// if(*ptr < min){
// min = *ptr;
// }
// ++ptr;
// }
return *Matrix_at(mat, row , Matrix_column_of_min_value_in_row(mat, row, column_start, column_end));
}