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

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

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

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

Q&A

解決済

2回答

616閲覧

segmentation faultというエラーを直して、力まかせ法を実装したい。

sho888

総合スコア14

C

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

0グッド

0クリップ

投稿2023/04/27 20:33

実現したいこと

力まかせ法による文字列検索を行いたいです。

前提

実行結果がsegmentation faultというエラーが発生します。

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

segmentation fault

該当のソースコード

#include <stdio.h>
#include <string.h>
#include <limits.h>

char *km_match(char *pat, char *txt)
{
char *pt; char *pp;
int skip[1024];
skip[*pt]=0;
while(pat[*pt] != '\n'){
if(pat[*pt]==pat[*pp])
skip[++*pt] = ++*pp;
else if(*pp==0)
skip[++*pt]=*pp;
else *pp=skip[*pp];
}
*pt=*pp=0;
while(txt[*pt] != '\n' && pat[*pp] != '\n'){
if(txt[*pt]==pat[*pp]){
*pt++;
*pp++;
}else if(*pp==0)
*pt++;
else
*pp=skip[*pp];
}
if(pat[*pp]=='\n')
return(txt +*pt-*pp);
return(NULL);
}

### 試したこと ここに問題に対して試したことを記載してください。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

バグあったら指摘よろしくです。

C

1#include <stddef.h> 2 3/* 4 txt から pat を探し、その位置を返す。 5 見つからないときは NULL を返す。 6 */ 7char* search(const char* pat, char* txt) { 8 if ( !pat || !txt ) return NULL; 9 while ( *txt != '0' ) { 10 // (0文字目から一致しない比較をするのはムダなので) 11 // 最初の文字と一致する位置まで進んで 12 while ( !*txt && *txt != *pat ) ++txt; 13 if ( !*txt ) return NULL; 14 15 // そこから pat と txt が一致するか調べる 16 const char* p = pat; 17 const char* t = txt; 18 while ( *p && *t ) { 19 if ( *p != *t ) break; 20 ++p; 21 ++t; 22 } 23 if ( !*p ) return txt; // 一致した! 24 ++txt; 25 } 26 return NULL; 27} 28 29// おためし 30 31#include <stdio.h> 32#include <string.h> 33#include <stdlib.h> 34 35int main() { 36 const char* pat = "abc"; 37 const char* txts[] = { "ab", "ababab", "abc", "xabc", "xabcd", "abababc", NULL }; 38 39 for ( const char** p = txts; *p != NULL; ++p ) { 40 char* txt = _strdup(*p); 41 char* result = search(pat, txt); 42 if ( result ) 43 printf("match(\"%s\", \"%s\")\t= %s + %lld\n", pat, txt, txt, result - txt); 44 else 45 printf("match(\"%s\", \"%s\") = NULL\n", pat, txt); 46 free(txt); 47 } 48}

投稿2023/04/28 03:37

episteme

総合スコア16614

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

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

sho888

2023/04/29 00:48

ありがとうございます。すみません。もう1つあり、この関数の引数はそのままでKMP法を実施する場合はどのように変えればよいですか?教えてください。
guest

0

C/C++ ではビルドするときの警告レベルを最大にして、まずは警告なしでビルドできるようにするのがお勧めです。また、segmentation falult などでクラッシュする場合は、デバッグビルドして、デバッガ上で実行して問題箇所を見つけましょう。gcc なら gcc -Wall -g ソースファイル名.c などです。

c

1char *pt; char *pp; 2int skip[1024]; 3skip[*pt]=0;

pt が初期化されていないので、skip[*pt] で高確率でクラッシュします。

int pt = 0; ... skip[pt] = 0; とかじゃないですかね。pp も同様。

投稿2023/04/27 21:29

編集2023/04/28 00:11
int32_t

総合スコア20850

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

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

sho888

2023/04/27 21:33

課題でchar *pt; char *pp;を使ってkm_matchの関数の引数を変えないという指示で 力まかせ法を実装できるプログラムを作成したいです。
int32_t

2023/04/27 21:48

では、 char* pt = txt; char* pp = pat; にして、それ以降は pat txt を使わないように実装するのが出題意図かもしれません。
int32_t

2023/04/27 22:01 編集

あと、「力まかせ法による文字列検索」と言っているのにコードは KMP 法をやろうとしているように見えます。力まかせ法で skip とか不要ですよね。
sho888

2023/04/29 00:39

ありがとうございます。 解決しました。助かりました。
sho888

2023/04/29 00:45

すみません。KMP法でした。 KMP法で分かる方教えてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問