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

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

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

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

アルゴリズム

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

Q&A

解決済

1回答

1219閲覧

JJavaでコパレータで互いに等しいとみなすことのできる線形リストの全ノードを削除するメソッドをつくったのですが、上手く動きません。

DAISUKE0549

総合スコア12

Java

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

アルゴリズム

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

0グッド

0クリップ

投稿2017/08/13 06:39

編集2017/08/13 06:46

学習中のJavaテキストで線形リストについての章があり、その中で
「コパレータcによって互いに等しいとみなすことのできる全ノードを削除する以下のメソッドを作成せよ。
void purge(Comparator<? super E> c)」
という課題がありました。自分でメソッドを作成したのですが、上手く動かないので原因を教えてください。

Java

10. //purgeメソッド以外はテキストに載っていた線形リストを表すクラスです。 21.//purgeメソッドが自分で作ったクラス、purge2メソッドが模範解答です。 32.//ノード 43.class Node<E> { 54. private E data; // データ 65. private Node<E> next; // 後続ポインタ(後続ノードへの参照) 76. 87. // コンストラクタ 98. Node(E data, Node<E> next) { 109. this.data = data; 1110. this.next = next; 1211. } 1312. } 1413.//線形リストクラス 1514.public class LinkedList<E> { 1615. private Node<E> head; // 先頭ノード 1716. private Node<E> crnt; // 着目ノード 1817. 1918. // コンストラクタ 2019. public LinkedList() { 2120. head = crnt = null; 2221. } 2322.//先頭にノードを挿入 2423.public void addFirst(E obj) { 2524. Node<E> ptr = head; // 挿入前の先頭ノード 2625. head = crnt = new Node<E>(obj, ptr); // ノードのデータはobj,後続ポインタの参照先は挿入前の先頭ノード 2726. } 2827.//先頭ノードを削除 2928.public void removeFirst() { 3029. if (head != null) { // リストが空でなければ 3130. head = crnt = head.next; 3231. } 3332. } 3433.//ノードpを削除 3534.public void remove(Node<E> p) { 3635. if (head != null) { 3736. if (p == head) // pが先頭ノードであれば 3837. removeFirst(); // 先頭ノードを削除 3938. } else { 4039. Node<E> ptr = head; 4140. 4241. while (ptr.next != p) { 4342. ptr = ptr.next; 4443. if (ptr == null) { 4544. return; // pはリスト上に存在しない 4645. } 4746. } 4847. ptr.next = p.next; 4948. crnt = ptr; // 削除したノードの先行ノードを参照先とする 5049. } 5150. } 5251.// コンパレータcによって互いに等しいとみなすことのできる全ノードを削除する 5352.public void purge(Comparator<? super E> c) { 5453. Node<E> ptr1 = head; // 比較対象1 5554. Node<E> ptr2; // 比較対象2 5655. Node<E> temp; // 5756. int counter = 0; 5857. 5958. while (ptr1.next != null) { 6059. ptr2 = ptr1.next; 6160. while (ptr2 != null) { 6261. if (c.compare(ptr1.data, ptr2.data) == 0) { 6362. counter++; 6463. temp = ptr2.next; 6564. remove(ptr2); //ここでptr2が削除されない 6665. ptr2 = temp; 6766. } else if (ptr2 != null) { 6867. ptr2 = ptr2.next; 6968. } 7069. } 7170. temp = ptr1.next; 7271. if (counter >= 1) { 7372. remove(ptr1); //ptr1が削除されるときとされない時がある。 7473. } 7574. ptr1 = temp; 7675. counter = 0; 7776. } 7877. //模範解答 7978.public void purge2(Comparator<? super E> c) { 8079. Node<E> ptr = head; // 比較用1 8180. while (ptr != null) { 8281. int count = 0; 8382. Node<E> ptr2 = ptr; // 比較用2 8483. Node<E> pre = ptr; 8584. 8685. while (pre.next != null) { 8786. ptr2 = pre.next; 8887. if (c.compare(ptr.data, ptr2.data) == 0) { 8988. pre.next = ptr2.next;// ptr2はどこからも参照されなくなり削除される 9089. count++; 9190. } else { 9291. pre = ptr2; 9392. } 9493. } 9594. if (count == 0) { 9695. ptr = ptr.next; 9796. } else { 9897. Node<E> temp = ptr; 9998. remove(ptr); 10099. ptr = temp.next; 101100. } 102101. } 103102. crnt = head; 104103. } 105104. // 末尾にノードを挿入 106105. public void addLast(E obj) { 107106. if (head == null) { // リストが空であれば 108107. addFirst(obj); // 先頭に挿入 109108. } else { 110109. Node<E> ptr = head; 111110. // 末尾ノードを見つける処理 112111. while (ptr.next != null) { 113112. ptr = ptr.next; 114113. } 115114. ptr.next = crnt = new Node<E>(obj, null); 116115. } 117116. } 118117.// 全ノードを表示 119118. public void dump() { 120119. Node<E> ptr = head; 121120. while (ptr != null) { 122121. System.out.println(ptr.data); 123122. ptr = ptr.next; 124123. } 125124. } 126125. 127130. public static void main(String[] args) { 128131. LinkedList<Data> list = new LinkedList<Data>(); 129132. Data d1 = new Data(1, "sayama"); 130133. Data d2 = new Data(2, "aki"); 131134. Data d3 = new Data(3, "sayama"); 132135. Data d4 = new Data(4, "akagi"); 133136. Data d5 = new Data(5, "sayama"); 134137. list.addFirst(d1); 135138. list.addLast(d2); 136139. list.addLast(d3); 137140. list.addLast(d4); 138141. list.addLast(d5); 139142. System.out.println(Data.NAME_ORDER.compare(d1, d3)); 140143. list.dump(); 141144. System.out.println("名前でパージします"); 142145. list.purge(Data.NAME_ORDER); 143146. System.out.println(); 144147. list.dump(); 145148. } 146149. } 147

上手く動かない原因は、64行目と72行目のremoveメソッドで削除したいノードを削除できていないからと思っています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

java

133.//ノードpを削除 234.public void remove(Node<E> p) { 335. if (head != null) { 436. if (p == head) // pが先頭ノードであれば 537. removeFirst(); // 先頭ノードを削除 638. } else { 739. Node<E> ptr = head; 840. 941. while (ptr.next != p) { 1042. ptr = ptr.next; 1143. if (ptr == null) { 1244. return; // pはリスト上に存在しない 1345. } 1446. } 1547. ptr.next = p.next; 1648. crnt = ptr; // 削除したノードの先行ノードを参照先とする 1749. } 1850. }

この38行目のelseは、if (head != null)に対するもの、つまりheadがnullの時に入るブロックになります。
対してif (head != null)のブロック中では先頭ノードしか比較していないため、それ以外に対象ノードがあった場合に削除できません。
それ以外にも「等しい」ことを==で比較していたり、突っ込みどころが多すぎます。

投稿2017/08/13 06:52

swordone

総合スコア20651

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

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

DAISUKE0549

2017/08/13 07:18

ご回答ありがとうございました。自分がテキストに載っていたremoveメソッドを書きか間違えていたことがわかりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問