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

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

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

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

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

1743閲覧

編集距離の高速化の方法

grape_ll

総合スコア83

C

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

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2020/07/05 13:23

編集2020/07/12 13:35

質問内容

最初に文字列の個数が与えられて,その次の行から文字列を与えられて,それらの文字列の変種距離が10未満である組み合わせが何通りあるか答える問題なのですが,1000文字くらいの文字列が100個くらいのときに実行時間が3秒を超えてしまうのですがどのようにしたら処理を早くすることが出来ますか?
50個のケースのときには実行時間が間に合っていました.

コード

C

1#include<stdio.h> 2#include<string.h> 3#include<stdlib.h> 4#include<math.h> 5#define MN3(o,p,q)((o)<(p)?((o)<(q)?(o):(q)):((p)<(q)?(p):(q))) 6#pragma GCC optimize("O3") 7char str[100][1001]; 8int main(void){ 9 int n; 10 scanf("%d",&n); 11 int count=0; 12 int i,j,x,y,k,l; 13 int length[100]; 14 int dp[1001][1001]; 15 int cost; 16 int flag1=0,flag2=0;; 17 18 19 dp[0][0]=0; 20 21 for(i=0;i<n;i++) { 22 scanf("%s",str[i]); 23 length[i]=strlen(str[i]); 24 } 25 26 for(y=0;y<=1000;y++) dp[0][y]=y; 27 for(x=0;x<=1000;x++) dp[x][0]=x; 28 29 for(i=0;i<n-1;i++){ 30 31 for(j=i+1;j<n;j++){ 32 33 flag2=0; 34 35 if(abs(length[i]-length[j])<10){ 36 flag2++; //文字の長さの差が10以上ならOK 37 for(x=1;x<=length[j];x++){ 38 39 flag1=0; 40 41 for(y=1;y<=length[i];y++){ 42 if(str[i][y-1]!=str[j][x-1]) cost=1; 43 else cost=0; 44 dp[x][y]=MN3(dp[x-1][y]+1,dp[x][y-1]+1,dp[x-1][y-1]+cost); 45 if(dp[x][y]>9) flag1++; //下のifと合わせて使う幅の行成分が全部10以上ならOUTにする 46 } 47 48 if(flag1>=length[i]) break; 49 50 } 51 } 52 53 54 55 /* 56 for(k=0;k<=length2;k++){ 57 for(l=0;l<=length1;l++){ 58 printf("%d ",dp[k][l]); 59 } 60 printf("\n"); 61 } 62 */ 63 64 if(flag1<length[i] && flag2!=0) { 65 count++; 66 //printf("%d:",dp[length2][length1]); 67 } 68 } 69 } 70 printf("%d\n",count); 71 return 0; 72 73}

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

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

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

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

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

guest

回答1

0

ベストアンサー

実際にコードで試していないのでどれだけ早くなるかは未知数ですが・・・

2つの文字列S,Tの長さをlen_s,len_tとし、任意のi文字目(1 <= i <= len_s かつ len_t)までの文字列をSi,Tiとすると、SiTiのレーベンシュタイン距離が10-abs(len_s-len_t)未満であれば合格と考えることができます。
つまりdp[1][1],dp[2][2]...と調べていき、最初に閾値以上が出た時点で不合格とすれば良いです。
次に、例えばdp[2][2]を求めるためにはdp[1][1],dp[2][1],dp[1][2]が必要です。これらを求めるには添え字が0~2の9要素がわかっていれば求まります。
同様に、dp[3][3]を求めるには添え字が0~3の16要素がわかっていれば求まります。
すなわち、dp[i][i]を求めるなら添え字0~iまでの数値がわかっているだけで良く、0~len_sまで走査する必要はありません。

例えば閾値が3で"vintner"と"writers"を比較するような場合。
イメージ説明
レーベンシュタイン距離を実際に計算する範囲は黄色の領域で、質問のコードのようにforで回していた灰色の部分は計算しなくても済みます。

投稿2020/07/05 15:24

hope_mucci

総合スコア4447

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

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

grape_ll

2020/07/09 15:21

length1のfor文の上にsa=abs(length1-length2)を入れて if(dp[x][y]>9-sa) flag1++; としたら答えが一致しなくなってしまったので訂正の仕方が違うと思うのですが具体的にどのように改善すればいのか教えていただけませんか.
hope_mucci

2020/07/09 22:41

NGになる具体的なテストケースを教えていただければ検証します。お願いします。
grape_ll

2020/07/12 13:09

返信遅れてしまい申し訳ございません. いかにテストケースを貼りたいと思います.一つ目は,元のコードでも三秒以内に正解を出すことが出来ます. 二つ目は実行時間オーバーになってしまいます. また上述した私の訂正をすると,両社とも不正解になりそうです.(二つ目のほうは結果が表示されなかったのでわかりませんが,あっていた二つが不正解になってしまったのでおそらく不正解だと思います)
grape_ll

2020/07/12 13:10

文字数オーバーになってしまうので質問のところに記載します. よろしくお願いします.
grape_ll

2020/07/12 13:13

文字数が上限をオーバーしてしまって質問のほうにも張ることが出来ませんでした. どのように共有いたしましょう.
grape_ll

2020/07/12 13:50

今更の疑問で申し訳ないのですが,灰色の部分は結局どこの(i,i)で終わりにすればいいのか分からない状態では,dp行列の成分を全て埋めたうえで対角成分を見るしかないのではないかと思ったのですが,どうでしょうか. 理解が追い付いていないのかもしれません.よろしくお願いします.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問