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

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

新規登録して質問してみよう
ただいま回答率
85.48%
多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

コピー

元のオブジェクトを破壊することなく、オブジェクトの複製を生成することをコピーと呼びます。

配列

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

Q&A

解決済

1回答

1016閲覧

Javaにおいて多次元配列のfor文より高速なdeepコピーの方法を教えてください

lotoka

総合スコア1

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

コピー

元のオブジェクトを破壊することなく、オブジェクトの複製を生成することをコピーと呼びます。

配列

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

0グッド

0クリップ

投稿2021/07/03 05:23

編集2021/07/03 06:06

現在,AtCoderでABC204-Cを解いています。
以下のようなコードを用いた結果、TLEとなりました。

Java

1import java.util.Scanner; 2 3public class Main { 4 public static void main(String[] args) { 5 Scanner scanner = new Scanner(System.in); 6 7 int N = scanner.nextInt(); 8 boolean[][] can = new boolean[N][N]; 9 boolean[][] befor = new boolean[N][N]; 10 int M = scanner.nextInt(); 11 int ans = 0; 12 13 for (int i = 0; i < N; i++) { 14 for (int j = 0; j < N; j++) { 15 befor[i][j] = true; 16 } 17 } 18 19 for (int i = 0; i < N; i++) { 20 can[i][i] = true; 21 } 22 23 for (int i = 0; i < M; i++) { 24 int from = scanner.nextInt(); 25 int to = scanner.nextInt(); 26 27 can[from - 1][to - 1] = true; 28 } 29 30 while (can != befor) { 31 for (int i = 0; i < N; i++) { 32 for (int j = 0; j < N; j++) { 33 befor[i][j] = can[i][j]; 34 } 35 } 36 37 for (int i = 0; i < N; i++) { 38 for (int j = 0; j < N; j++) { 39 if (can[i][j]) { 40 for (int k = 0; k < N; k++) { 41 can[i][k] |= can[j][k]; 42 } 43 } 44 } 45 } 46 } 47 48 for (int i = 0; i < N; i++) { 49 for (int j = 0; j < N; j++) { 50 if (can[i][j]) { 51 ans++; 52 } 53 } 54 } 55 56 System.out.println(ans); 57 } 58}

元々はwhile内の

Java

1for (int i = 0; i < N; i++) { 2 for (int j = 0; j < N; j++) { 3 befor[i][j] = can[i][j]; 4 } 5}

Java

1befor = can;

としていたため実行スピードに問題はなかったのですが、前述の通り変更した事により、実行時間が非常に伸びてしまいました。

多次元配列のdeepコピーの方法を検索してみましたが、for文を用いたものしか見当たらず、より高速な方法がないものかと思い質問いたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

問題となっているのはコピーの速度ではないと思われます。
実際に「入力例1」で実行してみると、計算が終わらないことが分かります。

計算が終わらない理由は、以下のwhileループを抜けられないためです。

java

1while (can != befor) {

ここでは中身まで含めて比較したかったのではないかと想われますが、実際には参照が同じであるかを判定していることになります。以下、参考までに、サンプルコードを挙げておきます。

java

1import java.util.Arrays; 2 3public class Main { 4 public static void main(String[] args) { 5 Boolean[] a = new Boolean[10]; 6 Boolean[] b = new Boolean[10]; 7 Boolean[] c; 8 c = a; 9 System.out.println(a == b); 10 System.out.println(a == c); 11 System.out.println(Arrays.deepEquals(a, b)); 12 System.out.println(Arrays.deepEquals(a, c)); 13 } 14}

投稿2021/07/03 06:23

kawakami-o3

総合スコア9

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

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

lotoka

2021/07/03 06:55

回答して頂き有難うございます。比較の際も注意が必要というのは盲点でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問