-
Notifications
You must be signed in to change notification settings - Fork 0
/
vektori.h
141 lines (99 loc) · 3.07 KB
/
vektori.h
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
#ifndef VEKTORI_H
#define VEKTORI_H
#include <iostream>
#include <cmath>
#include <sstream>
#include "poikkeukset.h"
using namespace otecpp_poikkeukset;
namespace otecpp_vektori {
/* toteutus samassa tiedostossa */
/*
stream s;
stream s = stream();
*/
// size_t koko on tässä ERIKOISTAMINEN (specialization), eli
// tätä geneeristä luokkaa käytetään silloin kun alustus Vektori<...>
// on muotoa T ja size_t
// Esim Vektori<Double, "kissa"> EI käyttäisi tätä pohjaa
template<typename T, size_t koko> class Vektori {
private:
T* arvot;
public:
static const size_t n = koko; // eli n = <koko>
Vektori() {
this->arvot = new T[koko];
}
// Kuormitetut operaattorit, ks. kalvot s.99
T& operator [](unsigned int i) throw(LaitonIndeksi) {
if(i >= this->n) {
std::stringstream ss;
ss << i;
throw LaitonIndeksi(ss.str());
}
return this->arvot[i];
}
const T& operator [](unsigned int i) const throw(LaitonIndeksi) {
if(i >= this->n) {
std::stringstream ss;
ss << i;
throw LaitonIndeksi(ss.str());
}
return this->arvot[i];
}
double pituus() const {
double sum = 0.0;
for(unsigned int vi=0; vi<this->n; ++vi) {
sum += std::pow( (*this)[vi], 2);
}
return std::sqrt(sum);
}
/*
Kertoo kunkin kahden indeksin arvot keskenään. esim. A[i] * B[i] ...
Paluuarvo on näiden arvojen summa, double.
*/
template<typename U> double pisteTulo(const Vektori<U, koko> &b) const {
double tulojensumma = 0.0;
for(unsigned int vi=0; vi<koko; ++vi) {
tulojensumma += (*this)[vi] * b[vi];
}
return tulojensumma;
}
/*
Saa parametrikseen vakioviitteen Vektori<U, koko>-olioon, missä taustalla
on oletus, että vaikka U ei välttämättä ole sama kuin T,
voidaan U- ja T-arvoja laskea yhteen.
*/
template<typename U> Vektori operator+(const Vektori<U, koko> &b) const {
Vektori<T, koko> uusi;
for(unsigned int vi=0; vi<koko; ++vi) {
uusi[vi] = b[vi] + (*this)[vi];
}
return uusi;
}
template<typename U> Vektori operator-(const Vektori<U, koko> &b) const {
Vektori<T, koko> uusi;
for(unsigned int vi=0; vi<b.n; ++vi) {
uusi[vi] = (*this)[vi] - b[vi];
}
return uusi;
}
};
// Luokan ulkopuolelle
/*
Tulostaa vektorin v arvot muodossa "[v[0], ..., v[n-1]]"
eli hakasulkeiden sisällä toisistaan pilkuilla ja välilyönneillä eroteltuina.
Esim: [2, 4, 1]
*/
template<typename T, size_t koko> std::ostream& operator<<(std::ostream& out, const Vektori<T, koko>& v) {
out << "[";
for(unsigned int i=0; i<v.n; ++i) {
out << v[i];
if(i != v.n-1) {
out << ", ";
}
}
out << "]";
return out;
}
}
#endif