teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

修正後のコードを追加

2020/06/20 17:44

投稿

shake9
shake9

スコア19

title CHANGED
File without changes
body CHANGED
@@ -60,4 +60,71 @@
60
60
 
61
61
  A→B→Cの順を固定することで、AとBがくっつくようになり探索する幅が狭くなるかと考えました。
62
62
  ただ、A→C→Bの順となる可能性もあるので、その両方を比較する方法を試しました。
63
- しかし実行速度はほとんど同じでした。
63
+ しかし実行速度はほとんど同じでした。
64
+
65
+ ### 修正後のコード
66
+ ```Python
67
+ a = input()
68
+ b = input()
69
+ c = input()
70
+
71
+ aa = len(a)
72
+ bb = len(b)
73
+ cc = len(c)
74
+
75
+ lensum = aa + bb + cc # 文字列の長さの最大値
76
+ ab = [0]*(lensum+cc+1) # 相対的位置に対して合わさるかどうかを記録
77
+ ac = [0]*(lensum+bb+1)
78
+ bc = [0]*(lensum+aa+1)
79
+
80
+ def match(v,w): # 2つの文字を合わせられるかどうかを調べる
81
+ if(v != '?' and w != '?' and v != w):
82
+ return 0
83
+ else:
84
+ return 1
85
+
86
+ def match2(A,B,k): # 2つの文字列とその相対的位置に対して合わさるかチェック
87
+ AA = len(A)
88
+ BB = len(B)
89
+ if(k>=AA):
90
+ return 1
91
+ elif(k<-BB):
92
+ return 1
93
+ else:
94
+ flg = 1
95
+ st = max(0,k)
96
+ la = min(AA,BB+k)
97
+ for i in range(st,la):
98
+ if(match(A[i],B[i-k])==0):
99
+ flg = 0
100
+ break
101
+ return flg
102
+
103
+ #ab,ac,bcに対して計算する
104
+ for i in range(lensum+cc+1):
105
+ ab[i] = match2(a,b,i-bb-cc)
106
+ for i in range(lensum+bb+1):
107
+ ac[i] = match2(a,c,i-bb-cc)
108
+ for i in range(lensum+aa+1):
109
+ bc[i] = match2(b,c,i-aa-cc)
110
+
111
+ def milen(a,b,c):
112
+ minlen = lensum # 文字列の長さの最大値
113
+ for i in range(-bb-cc,aa+cc+1): # iが文字列Bの開始位置
114
+ for j in range(-bb-cc,aa+bb+1): # jが文字列Cの開始位置
115
+ if(ab[i+bb+cc] == 0):
116
+ continue
117
+ elif(ac[j+bb+cc] == 0):
118
+ continue
119
+ elif(j-i+aa+cc < 0 or j-i+aa+cc >= lensum+aa+1): #BとCが離れすぎている場合を除く
120
+ continue
121
+ elif(bc[j-i+aa+cc] == 0):
122
+ continue
123
+ else:
124
+ sta = min(0,i,j) #文字列の中で一番左にある開始位置
125
+ en = max(aa,i+bb,j+cc) #文字列の中で一番右にある終了位置
126
+ minlen = min(minlen,en-sta) #更新
127
+ return minlen
128
+
129
+ print(milen(a,b,c))
130
+ ```