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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

974閲覧

n元配列へのアクセスはO(n) ? それともO(1) ?

QueueuQ

総合スコア15

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/08/08 09:33

疑問

例えば3次元配列Aがあるとして、A[i][j][k]へのアクセスはO(3)?それともo(1)?

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

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

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

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

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

BeatStar

2021/08/08 09:45

普通に考えてみればいいのでは?
QueueuQ

2021/08/08 09:54

普通に考えると、「3次元配列Aのi番目の配列の中のj番目の配列の中のk番目」でO(1 * 3)で、実際一次元の配列のアクセスより遅いことが確認できているのですが、このテーマについて言及されているソースや記事がぱっと見で見つからなかったので、詳しい説明ができる人がいないかと思い投稿してみました。
otn

2021/08/08 10:00

現状ではO(n)表記の理解が間違っているので、O(n)表記を使って質問したいのなら、正しく理解しましょう。 O(n)表記を使わないで知りたいことを質問できるなら、そちらの方が良いと思います。
quickquip

2021/08/08 10:48 編集

タイトルで > n元配列へのアクセスはO(n) ? という問いをしているので Aが3次元配列の時の A[0][0][0] Aが4次元配列の時の A[0][0][0][0] Aが5次元配列の時の A[0][0][0][0][0] : : Aがn次元配列の時の A[0][0][0][0][0]……[0] : となった時の必要な計算時間の話をしていることになるのですが、それで合っているんでしょうか??
quickquip

2021/08/08 10:53

もし、 n元配列へのアクセスはO(n) なのであれば、3次元配列ならO(3)なんでしょうか? というのが質問の主旨なのだとしたら、otn さんが"O(n)表記の理解が間違っている"と指摘したのが合ってますね。
ppaul

2021/08/08 10:53

メモリアクセスについてランダウの記法による計算量を考えることには意味がありません。
guest

回答3

0

そもそも論として、O(3)O(1)同じ意味です(通常O(1)と書きます)。

定数倍の差は、ランダウ記号では無視されます。

投稿2021/08/10 12:53

編集2021/08/10 12:54
maisumakun

総合スコア146018

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

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

0

単純に次元ごとに順に並んだメモリ配置を考えるなら、O(n)でしょうね。
次元が増えるごとに比例してメモリ番地を求めるための乗算・加算の回数が増えます。
A[i] : i
A[i][j] : i*width+j
A[i][j][k] : i*(width*height)+j*width+k
と言った具合に。


改めて考えてみると、質問の解釈の仕方が2通りあると思いました。

  1. nを変数として「n元配列へのアクセス」という1つの対象に対してのオーダーを質問している。

「例えば3次元配列Aがあるとして~」は、質問を分かりやすくするための解説。(オーダーの理解は間違っている)
2. nを固定した複数の「○元配列」についてそれぞれのオーダーを質問している。
「例えば3次元配列Aがあるとして~」は、質問の対象のうち1つを抜き出したもの。

自分は前者の解釈でO(n)と言っていましたが、後者の解釈では「どの定数nについても、O(1)」が答えとなります。

投稿2021/08/08 14:11

編集2021/08/11 04:41
ikadzuchi

総合スコア3047

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

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

takezoux2

2021/08/10 03:12

解説が間違っています。 三次元配列の際の i*(width*height)+j*width+k の計算もO(1)となるため、何次元配列だとしても時間計算量はO(1)です。
ikadzuchi

2021/08/10 12:50

n=3などとnを固定するならそれは当然O(1)になります。 n=100でもn=10000でもO(1)です。 O(n)とは変数nに比例して計算量が増えることを意味します。 変数と定数の区別をつけてください。
ikadzuchi

2021/08/11 04:47

解釈の違いではないかと思えてきました。本文に追記しました。
guest

0

ベストアンサー

趣味でやっているので間違っている可能性もありますが、それでもいいなら。


恐らく今回はオーダー記法で書くとO(1)だと思います。

そもそも計算量には二種類あり、
時間計算量と空間計算量があります。

オーダー記法で表現されるのは時間計算量の方っぽいです。

この時間計算量は極端なことをいえば『最悪かかる時間』です。

配列の要素数がNあって、O(N)であれば、最悪時にはN回は計算することになります。

ですが、厳密には『かかる時間』ではなく、『データ量が増えるとどのぐらい処理時間がかかるか』だったはずです。

二次関数の方だっかな? あるいは比例・反比例の関係とかですね。

もしO(N)で、N = 10`, N = 20, N = 30 … と考えると、比例していますね。

O(N^2) であれば…とかんがえてみてください。

ヒント:参考

そう考えると、二次元配列だろうと三次元配列だろうと、for文を使っての探索とかでなくランダムアクセス(直接アクセスする方法)であれば、変動なしなのでO(1)になるのではないかと思いますが。

投稿2021/08/08 10:29

BeatStar

総合スコア4962

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

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

QueueuQ

2021/08/08 11:27

曖昧な質問に対し的確な解答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問