Préambule: je tiens tout d'abord à préciser que je ne suis pas spécialement un développeur C++ (question concepts, idiomes, etc.) De plus comme ce n'est pas mon activité principale ; je n'ai pas d'IDE "spécialisé" C++ à disposition et donc le code présenté ci-après à été réalisé via un éditeur disponible sur navigateur (du type Ideone pour ceux qui connaissent) et donc je n'ai pas le contrôle sur l'environnement (options de compilation par exemple) ni la possibilité de séparer le code dans plusieurs fichiers (même si j'ai tenté de coder de manière que chaque élément n'est que ce qu'il a besoin dans sa portée) ; je vous prie donc de tenir compte de ces éléments
Suite à une question posée sur le chat de développez où il était question de faire la somme des diagonales d'une matrice carrée (dans un sens puis dans l'autre) ; j'ai expérimenté dans plusieurs langages avec une approche basée sur le code Matlab suivant
Je pense que le code reste compréhensible même sans connaître Matlab
Code Matlab : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 M = [ 1 2 3 10 20 30 100 200 300]; N = size(M,1)-1; diags = arrayfun(@(k) sum(diag(M ,k)), -N:N) antidiags = arrayfun(@(k) sum(diag(flipud(M),k)), -N:N)
Pour C++, afin de m'exercer j'ai voulu tenter une approche template (que je suis loin de maitriser) et en suis arrivé à ceci (attention risque de piquer les yeux )
Tout fonctionne à priori correctement (j'avoue ne pas avoir poussé les tests très loin ; arriver à avoir un code qui compile et donne le bon résultat sur mon petit cas d'essai est déjà gratifiant en soi pour moi).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 #include <array> // std::array #include <cstdlib> // std::size_t, std::abs, std::min namespace sehn { template <typename T, std::size_t N> using matrix = std::array<std::array<T, N>, N>; template <typename T, std::size_t N> matrix<T, N> flipud (matrix<T, N> const &); template <typename T, std::size_t N> using all_diags = std::array<T, 2 * N - 1>; } template <typename T, std::size_t N> sehn::all_diags<int, N> sum_diags (sehn::matrix<T, N> const &); template <typename T, std::size_t N> void print_array (std::array<T, N> const &); template <typename T, std::size_t N> void print_matrix (sehn::matrix<T, N> const &); int main () { std::size_t const size (3); sehn::matrix<int, size> matrix { { 1, 2, 3, 10, 20, 30, 100, 200, 300 } }; print_matrix (matrix); print_array (sum_diags (matrix)); auto flipped (sehn::flipud (matrix)); print_matrix (flipped); print_array (sum_diags (flipped)); return 0; } #include <iostream> // std::cout, std::endl template <typename T, std::size_t N> void print_array (std::array<T, N> const &array) { for (auto const &item : array) std::cout << item << '\t'; std::cout << std::endl; } template <typename T, std::size_t N> void print_matrix (sehn::matrix<T, N> const &matrix) { for (auto const &row : matrix) print_array (row); std::cout << std::endl; } #include <type_traits> // std::enable_if template <std::size_t N, int K> using K_before_N = typename std::enable_if<K < static_cast<int> (N) - 1>::type; template <typename T, std::size_t N, int K> K_before_N<N, K> sum_diags_impl (sehn::matrix<T, N> const &, sehn::all_diags<int, N> &); template <std::size_t N, int K> using K_at_N = typename std::enable_if<K == static_cast<int> (N) - 1>::type; template <typename T, std::size_t N, int K> K_at_N<N, K> sum_diags_impl (sehn::matrix<T, N> const &, sehn::all_diags<int, N> &); template <typename T, std::size_t N> sehn::all_diags<int, N> sum_diags (sehn::matrix<T, N> const &matrix) { sehn::all_diags<int, N> sums; sum_diags_impl<T, N, -static_cast<int> (N) + 1> (matrix, sums); return sums; } namespace sehn { template <typename T, std::size_t N, int K> using diagonal = std::array<T, N - std::abs (K)>; template <typename T, std::size_t N, int K> diagonal<T, N, K> diag (matrix<T, N> const &); } #include <iterator> // std::begin, std::end #include <numeric> // std::accumulate template <typename T, std::size_t N, int K> K_before_N<N, K> sum_diags_impl (sehn::matrix<T, N> const &matrix, sehn::all_diags<int, N> &sums) { auto diag = sehn::diag<T, N, K> (matrix); sums[N - 1 + K] = std::accumulate (std::begin (diag), std::end (diag), T{}); sum_diags_impl<T, N, K + 1> (matrix, sums); } template <typename T, std::size_t N, int K> K_at_N<N, K> sum_diags_impl (sehn::matrix<T, N> const &matrix, sehn::all_diags<int, N> &sums) { auto diag = sehn::diag<T, N, K> (matrix); sums[N - 1 + K] = std::accumulate (std::begin (diag), std::end (diag), T{}); } #include <algorithm> // std::reverse_copy namespace sehn { template <typename T, std::size_t N> matrix<T, N> flipud (matrix<T, N> const &source) { matrix<T, N> flipped; std::reverse_copy (std::begin (source), std::end (source), std::begin (flipped)); return flipped; } template <typename T, std::size_t N, int K> diagonal<T, N, K> diag (matrix<T, N> const &matrix) { diagonal<T, N, K> diag; for (std::size_t row (0); row < N; ++row) { std::size_t const col (row + K); diag[std::min (row, col)] = matrix[row][col]; } return diag; } }
Mon "souci" se pose en fait sur l'include d'algorithm ; e l'état ça fonctionne ; mais si je ne fais pas l'alias diagonal (ligne 82) je me fait insulter copieusement ; sauf si je déplace l'include avant ce bloc namespace ; ci-joint le type de message que je reçois.
Du coup je me tourne vers vous pour essayer de comprendre le phénomène (et tant qu'à faire si vous avez des remarques sur le code [pas forcément sur l'algo étant donné que j'ai pris le parti de reproduire celui du code matlab] )
Code Text : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 /tmp/cc5OQUfq.o: In function `_Z14sum_diags_implIiLm3ELin2EENSt9enable_ifIXltT1_misciT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE': prog.cpp:(.text._Z14sum_diags_implIiLm3ELin2EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE[_Z14sum_diags_implIiLm3ELin2EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE]+0x1d): undefined reference to `std::array<int, (3ul)-(abs(-2))> sehn::diag<int, 3ul, -2>(std::array<std::array<int, 3ul>, 3ul> const&)' /tmp/cc5OQUfq.o: In function `_Z14sum_diags_implIiLm3ELin1EENSt9enable_ifIXltT1_misciT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE': prog.cpp:(.text._Z14sum_diags_implIiLm3ELin1EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE[_Z14sum_diags_implIiLm3ELin1EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE]+0x1d): undefined reference to `std::array<int, (3ul)-(abs(-1))> sehn::diag<int, 3ul, -1>(std::array<std::array<int, 3ul>, 3ul> const&)' /tmp/cc5OQUfq.o: In function `_Z14sum_diags_implIiLm3ELi0EENSt9enable_ifIXltT1_misciT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE': prog.cpp:(.text._Z14sum_diags_implIiLm3ELi0EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE[_Z14sum_diags_implIiLm3ELi0EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE]+0x1d): undefined reference to `std::array<int, (3ul)-(abs(0))> sehn::diag<int, 3ul, 0>(std::array<std::array<int, 3ul>, 3ul> const&)' /tmp/cc5OQUfq.o: In function `_Z14sum_diags_implIiLm3ELi1EENSt9enable_ifIXltT1_misciT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE': prog.cpp:(.text._Z14sum_diags_implIiLm3ELi1EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE[_Z14sum_diags_implIiLm3ELi1EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE]+0x1d): undefined reference to `std::array<int, (3ul)-(abs(1))> sehn::diag<int, 3ul, 1>(std::array<std::array<int, 3ul>, 3ul> const&)' /tmp/cc5OQUfq.o: In function `_Z14sum_diags_implIiLm3ELi2EENSt9enable_ifIXeqT1_misciT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE': prog.cpp:(.text._Z14sum_diags_implIiLm3ELi2EENSt9enable_ifIXeqT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE[_Z14sum_diags_implIiLm3ELi2EENSt9enable_ifIXeqT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE]+0x1d): undefined reference to `std::array<int, (3ul)-(abs(2))> sehn::diag<int, 3ul, 2>(std::array<std::array<int, 3ul>, 3ul> const&)' collect2: error: ld returned 1 exit status
Cordialement !
Partager