質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

921閲覧

基本演算を備えた2次元配列を作る

Y.R.T

総合スコア42

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/08/17 02:19

構文内に
constexpr T& at(size_t const r, size_t const c)
{
return arr.at(r * C + c);
}

constexpr T const& at(size_t const r, size_t const c) const { return arr.at(r * C + c); }

の箇所の、(r * C + c)
は何を目的としてこのようなことをしているのですか?

#include <iostream> #include <vector> #include <algorithm> #include <iterator> template <class T, size_t R, size_t C> class array2d { typedef T value_type; typedef value_type* iterator; typedef value_type const* const_iterator; std::vector<T> arr; public: array2d() :arr(R* C) {} explicit array2d(std::initializer_list<T> l) :arr(l) {} constexpr T* data() noexcept { return arr.data(); } constexpr T const* data() const noexcept { return arr.data(); } constexpr T& at(size_t const r, size_t const c) { return arr.at(r * C + c); } constexpr T const& at(size_t const r, size_t const c) const { return arr.at(r * C + c); } constexpr T& operator() (size_t const r, size_t const c) { return arr[r * C + c]; } constexpr T const& operator() (size_t const r, size_t const c) const { return arr[r * C + c]; } constexpr bool empty() const noexcept { return R == 0 || C == 0; } constexpr size_t size(int const rank) const { if (rank == 1) return R; else if (rank == 2) return C; throw std::out_of_range("Rank is out of range!"); } void fill(T const& value) { std::fill(std::begin(arr), std::end(arr), value); } void swap(array2d& other) noexcept { arr.swap(other.arr); } const_iterator begin() const { return arr.data(); } const_iterator end() const { return arr.data() + arr.size(); } iterator begin() { return arr.data(); } iterator end() { return arr.data() + arr.size(); } }; template <class T, size_t R, size_t C> void print_array2d(array2d<T, R, C> const& arr) { for (int i = 0; i < R; ++i) { for (int j = 0; j < C; ++j) { std::cout << arr.at(i, j) << ' '; } std::cout << std::endl; } } int main() { { std::cout << "test fill" << std::endl; array2d<int, 2, 3> a; a.fill(1); print_array2d(a); } { std::cout << "test operator()" << std::endl; array2d<int, 2, 3> a; for (size_t i = 0; i < a.size(1); ++i) { for (size_t j = 0; j < a.size(2); ++j) { a(i, j) = 1 + i * 3 + j; } } print_array2d(a); } { std::cout << "test move semantics" << std::endl; array2d<int, 2, 3> a{ 10,20,30,40,50,60 }; print_array2d(a); array2d<int, 2, 3> b(std::move(a)); print_array2d(b); } { std::cout << "test swap" << std::endl; array2d<int, 2, 3> a{ 1,2,3,4,5,6 }; array2d<int, 2, 3> b{ 10,20,30,40,50,60 }; print_array2d(a); print_array2d(b); a.swap(b); print_array2d(a); print_array2d(b); } { std::cout << "test capacity" << std::endl; array2d<int, 2, 3> const a{ 1,2,3,4,5,6 }; for (size_t i = 0; i < a.size(1); ++i) { for (size_t j = 0; j < a.size(2); ++j) { std::cout << a(i, j) << ' '; } std::cout << std::endl; } } { std::cout << "test iterators" << std::endl; array2d<int, 2, 3> const a{ 1,2,3,4,5,6 }; for (auto const e : a) { std::cout << e << 'A'; } std::cout << std::endl; std::copy( std::begin(a), std::end(a), std::ostream_iterator<int>(std::cout, "B")); std::cout << std::endl; } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

arr自体はサイズがR(行)*C(列)の一次元配列のため、rc列目はr * C + cになります。

一次元配列を擬似的にR(行)*C(列)の二次元配列としてアクセスする場合の添字は
|行\列|0|…|c|…|C-1|
|:--|:--:|:--:|:--:|--:|
|0|0|…|c|…|C-1|
|1|C|…|C+c|…|2C-1|
|…||||||
|r|r
C||(質問はここ)r*C+c|||
|…||||||
|R-1|(R-1)C||||RC-1|

投稿2020/08/17 02:31

編集2020/08/17 03:36
SHOMI

総合スコア4079

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Y.R.T

2020/08/17 03:46

ありがとうございます。 理解できました。
guest

0

要素数 R*C の一次元配列 std::vector<T> arr; を
R行C列の行列(二次元配列)として扱いたいがためでしょうね。

投稿2020/08/17 02:28

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Y.R.T

2020/08/17 03:46

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問