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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

解決済

双方向リストを作ったが、deleteした後にリストの中身を表示させると実行時間超過で中断されてしまう

aoa
sawaawa

総合スコア4

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

4回答

0グッド

0クリップ

512閲覧

投稿2022/11/15 15:32

編集2022/11/16 01:28

概要

2つの頭(ダミー)がある双方向循環リストにおいて
(1)入力順と同じ順番にリストを作成する
(2)1つ目のリストは要素が奇数、2つ目のリストは要素が偶数のものを消去する
(3)1つめのリストの末尾に2つ目のリストを繋げ、2つ目のリストの末尾に1つ目のリストの先頭ダミーにつなぐ。尚、2つ目の先頭のダミーは消去する。

というものをプログラムをしたいのですが、2つ目のリスト内の要素が偶数のものを消去を行なった後にリストを出力するときに時間超過で中断されてしまいます。複雑なことは行っていないはずなのに、何がいけないにでしょうか?

実行例

>1 >2 >3 [1][2][3]{3}{2}{1} [1][2][3]{3}{2}{1} [2]{2} [1][3]{3}{1} [2][1][3]{3}{1}{2}

発生している問題・エラーメッセージ

>1 >2 >3 [1][2][3]{3}{2}{1} [1][2][3]{3}{2}{1} この先が行われない

該当のソースコード

C

1#include<stdio.h> 2#include<stdlib.h> 3 4typedef int elementtype; 5 6struct dlnode { 7 elementtype element; 8 struct dlnode *prev, *next; 9}; 10 11typedef struct dlnode* dllist; 12 13void print_dllist(dllist d) {/*d の指しているダミーの節点から、next を順にたどって自分自身に戻るまで element を [と] で挟ん 14で標準出力に出力し続けたのち、prev を順にたどって自分自身に戻るまで element を{と}で挟んで標 15準出力に出力し続ける関数 (最後に改行)。 */ 16 dllist n; 17 n = d->next; 18 while(n != d) { 19 printf("[%d]", n->element); 20 n = n->next; 21 } 22 n = n->prev; 23 while(n != d) { 24 printf("{%d}", n->element); 25 n = n->prev; 26 } 27 printf("\n"); 28 29} 30 31void insert(dllist p, elementtype e) { /*p の指している節点の prev に、element として e を含む節点を挿入する関数。 */ 32 dllist n; 33 n = (struct dlnode *) malloc (sizeof (struct dlnode)); 34 n->element = e; 35 36 if(p->next == NULL && p->prev == NULL) { 37 p->prev = n; 38 n->next = p; 39 n->prev = p; 40 p->next = n; 41 } else { 42 n->next = p; 43 n->prev = p->prev; 44 p->prev->next = n; 45 p->prev = n; 46 } 47} 48 49void delete(dllist p) { /*p の指している節点のみを削除する関数 (p の前後のポインタを繋ぎ変えて、free 関数により削除した 50節点のメモリを解放する)。*/ 51struct dlnode *next, *prev; 52 prev = p->prev; 53 next= p->next; 54 if (prev != NULL) 55 prev->next = next; 56 if (next != NULL) 57 next ->prev = prev; 58 free(p); 59} 60void append_dllist(dllist d1, dllist d2) {/*d1、d2 の指している節点をダミーの節点とする 2 つの双方向リストを連結する関数 (d1 から next をた 61どっていくと、1 つめの双方向リストの要素に続いて 2 つめの双方向リストの要素が現れ、d1 に戻っ 62てくるように定義し、2 つめのダミーの節点 d2 のメモリは free 関数によって解放する)*/ 63 dllist n; 64 n = d1; 65 while(n->next != d1) { 66 n = n->next; 67 } 68 n->next = d2; 69 70 while(n->next != d2) { 71 n = n->next; 72 } 73 n->next = d1; 74 free(d2); 75} 76 77int main(void) { 78 int i; 79 char buf[128]; 80 dllist d1, d2, p; 81 82 d1 = (struct dlnode *)malloc(sizeof(struct dlnode)); 83 d1->prev = NULL; 84 d1->next = NULL; 85 86 d2 = (struct dlnode *)malloc(sizeof(struct dlnode)); 87 d2->prev = NULL; 88 d2->next = NULL; 89 90 91 while(fgets(buf,sizeof(buf),stdin) != NULL) { 92 sscanf(buf,"%d", &i); 93 insert(d1, i); 94 insert(d2, i); 95 } 96 print_dllist(d1); 97 print_dllist(d2); 98 99 p = d1; 100 do { 101 if(p->element % 2) { 102 p = p->next; 103 delete(p->prev); 104 105 } 106 p = p->next; 107 }while(p!=d1||p->next!=d1); 108 109 p = d2; 110 do{ 111 if(!(p->element % 2)){ 112 p = p->next; 113 delete(p->prev); 114 115 } 116 p = p->next; 117 }while(p!=d2||p->next!=d2); 118 119 print_dllist(d1); 120 print_dllist(d2); 121 122 append_dllist(d1, d2); 123 print_dllist(d1); 124 return 0; 125}

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

jimbe

2022/11/15 15:50 編集

時間超過ということはどこかで無限ループしているのでしょう。 コードの一行毎に printf で何かマークを出すようにし、どこでループしているかを調べては如何でしょうか。 また、コードをコピペしてもコンパイルエラーになっています。 teratail への貼り付けはソースファイルの中身そのままにするようにしてください。
aoa

2022/11/15 15:59

申し訳ありません。 訂正前のものを添付していました。
kazuma-s

2022/11/15 17:57

「頭(ダミー)がある双方向循環リスト」の頭の prev と next は NULL ではなく、 最初は 頭のアドレスを入れます。
dodox86

2022/11/16 02:51

タグの「リストボックス」は、GUIの要素の種類のひとつであって、今回は関係無いと思います。

回答4

1

https://pythontutor.com/c.html を利用し、コードの流れを可視化する。

投稿2022/11/15 16:13

atcoderyellow

総合スコア481

退会済みユーザー👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

2022/11/16 13:09

こちらの回答が複数のユーザーから「質問に対する回答となっていない投稿」という指摘を受けました。

0

ベストアンサー

質問のコードは全角スペースが入っていたり、do文の最後にセミコロンがないなど
コンパイル不可能なものです。
また、append_dllist も間違っています。

リストのヘッドの初期化を insert の中で行っているようですが、
ヘッドを作った時に初期化するほうが良いと思います。

C

1#include <stdio.h> 2#include <stdlib.h> 3 4typedef int elementtype; 5 6struct dlnode { 7 elementtype element; 8 struct dlnode *prev, *next; 9}; 10 11typedef struct dlnode *dllist; 12 13void print_dllist(dllist d) 14{ 15 for (dllist n = d->next; n != d; n = n->next) 16 printf("[%d]", n->element); 17 for (dllist n = d->prev; n != d; n = n->prev) 18 printf("{%d}", n->element); 19 printf("\n"); 20} 21 22void insert(dllist p, elementtype e) 23{ 24 dllist n = malloc(sizeof(struct dlnode)); 25 n->element = e; 26 n->next = p; 27 n->prev = p->prev; 28 p->prev->next = n; 29 p->prev = n; 30} 31 32void delete(dllist p) 33{ 34 p->prev->next = p->next; 35 p->next->prev = p->prev; 36 free(p); 37} 38 39void append_dllist(dllist d1, dllist d2) 40{ 41 d1->prev->next = d2->next; 42 d2->next->prev = d1->prev; 43 d1->prev = d2->prev; 44 d2->prev->next = d1; 45 free(d2); 46} 47 48int main(void) 49{ 50 dllist d1, d2, p, q; 51 d1 = malloc(sizeof(struct dlnode)); 52 d1->prev = d1->next = d1; 53 d2 = malloc(sizeof(struct dlnode)); 54 d2->prev = d2->next = d2; 55 56 char buf[128]; 57 while (fgets(buf, sizeof buf, stdin)) { 58 int i; 59 sscanf(buf, "%d", &i); 60 insert(d1, i); 61 insert(d2, i); 62 } 63 print_dllist(d1); 64 print_dllist(d2); 65 66 for (p = d1->next; p != d1; p = q) { 67 q = p->next; 68 if (p->element % 2 == 1) delete(p); 69 } 70 for (p = d2->next; p != d2; p = q) { 71 q = p->next; 72 if (p->element % 2 == 0) delete(p); 73 } 74 print_dllist(d1); 75 print_dllist(d2); 76 77 append_dllist(d1, d2); 78 print_dllist(d1); 79 return 0; 80}

append_dllist の中で free(d2); の代わりに d2->prev = d2->next = d2; としておいて
main で d2 のリストの free を行ったほうがいいとは思うのですが。

このコードが理解できたかどうかコメントをお願いします。

投稿2022/11/16 01:32

編集2022/11/16 01:51
kazuma-s

総合スコア8080

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

aoa

2022/11/16 05:13

初期化の部分が参考になります。 訂正前のコードを添付してすみませんでした。 ありがとうございました。

0

コードをよく読んだ訳では無いので処理は確認していませんが、 do while() のセミコロンを付け忘れているのでは無いでしょうか

投稿2022/11/16 00:44

編集2022/11/16 00:46
eipi-1-0

総合スコア8

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

0

まずはデバッグできる環境を整えてはどうでしょうか。
Windowsなら、VisualStudioやEclipseなどがあります

ブレークポイントを設定して実行を止め、変数の中身を見ることができます。
また、1行づつ実行して、どう動作するかを見れます。

これで、どこがおかしいのかわからない、ってことはなくなりますよ

投稿2022/11/16 00:13

編集2022/11/16 00:20
y_waiwai

総合スコア86013

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

2022/11/25 06:42

こちらの回答が他のユーザーから「質問に対する回答となっていない投稿」という指摘を受けました。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。