สมมติว่าเรามีสตริงเช่น "word" และมีตัวย่อต่อไปนี้:["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"] นอกจากนี้เรายังมีสตริงเป้าหมายและชุดของสตริงในพจนานุกรม เราต้องหาตัวย่อของสตริงเป้าหมายนี้ที่มีความยาวน้อยที่สุดเท่าที่จะเป็นไปได้ เพื่อไม่ให้ขัดแย้งกับตัวย่อของสตริงในพจนานุกรม ในที่นี้ ตัวเลขหรือตัวอักษรแต่ละตัวในตัวย่อจะถือเป็นความยาว =1 ตัวอย่างเช่น ตัวย่อ "a32bc" มีความยาว =4
ดังนั้น หากอินพุตเป็นเหมือน "apple" และพจนานุกรมคือ ["blade"] เอาต์พุตจะเป็น "a4"
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนด dict อาร์เรย์
-
กำหนดฟังก์ชัน abbrLen() ซึ่งจะเป็นการปิดบัง
-
ret :=n
-
สำหรับการเริ่มต้น b :=3 เมื่อ b
-
ถ้า (mask AND b) เท่ากับ 0 แล้ว −
-
(ลดหย่อน 1)
-
-
-
รีเทิร์น
-
กำหนดฟังก์ชัน dfs() ซึ่งจะใช้เวลาบิต มาสก์
-
len :=abbrLen(หน้ากาก)
-
ถ้า len>=minLen แล้ว −
-
กลับ
-
-
ตรงกัน :=จริง
-
สำหรับแต่ละ d ใน dict ทำ -
-
ถ้า (mask AND d) เท่ากับ 0 แล้ว −
-
ตรงกัน :=เท็จ
-
ออกจากวง
-
-
-
หากการจับคู่ไม่เป็นศูนย์ −
-
minLen :=เลน
-
มินาบ :=หน้ากาก
-
-
มิฉะนั้น −
-
สำหรับการเริ่มต้น b :=บิตเมื่อ b
-
ถ้า (แคน AND b) ไม่เท่ากับ 0 แล้ว −
-
dfs(b*2, mask OR b)
-
-
-
-
จากวิธีหลัก ให้ทำดังต่อไปนี้ −
-
ret :=สตริงว่าง
-
n :=ขนาดของเป้าหมาย
-
bn :=2^n
-
แคน :=0
-
minLen :=inf
-
สำหรับแต่ละ s ในพจนานุกรม -
-
ถ้าขนาดของ s ไม่เท่ากับ n แล้ว −
-
ละเว้นส่วนต่อไปนี้ ข้ามไปยังการทำซ้ำถัดไป
-
-
คำ :=0
-
สำหรับการเริ่มต้น i :=0 เมื่อ i
-
ถ้า s[i] ไม่เท่ากับเป้าหมาย[i] ดังนั้น −
-
word :=คำ OR (2^i)
-
-
-
ใส่คำต่อท้าย dict
-
cand :=cand OR word
-
-
dfs(1, 0)
-
สำหรับการเริ่มต้น i :=0 เมื่อฉัน
-
ถ้า (minab AND 2^i) ไม่เท่ากับ 0 แล้ว −
-
ret :=ret + เป้าหมาย[i]
-
(เพิ่ม i ขึ้น 1)
-
-
มิฉะนั้น
-
เจ :=ฉัน
-
ในขณะที่ (i
-
(เพิ่ม i ขึ้น 1)
-
-
ret :=ret concatenate (i - j)
-
-
-
รีเทิร์น
ตัวอย่าง
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
#include <bits/stdc++.h> using namespace std; class Solution { public: int n, cand, bn, minLen, minab; vector<int> dict; int abbrLen(int mask) { int ret = n; for (int b = 3; b < bn; b <<= 1) { if ((mask & b) == 0) ret--; } return ret; } void dfs(int bit, int mask) { int len = abbrLen(mask); if (len >= minLen) return; bool match = true; for (int d : dict) { if ((mask & d) == 0) { match = false; break; } } if (match) { minLen = len; minab = mask; } else { for (int b = bit; b < bn; b <<= 1) { if ((cand & b) != 0) dfs(b << 1, mask | b); } } } string minAbbreviation(string target, vector<string> &dictionary) { string ret = ""; n = target.size(); bn = 1 << n; cand = 0; minLen = INT_MAX; for (string &s : dictionary) { if (s.size() != n) continue; int word = 0; for (int i = 0; i < s.size(); i++) { if (s[i] != target[i]) word |= (1 << i); } dict.push_back(word); cand |= word; } dfs(1, 0); for (int i = 0; i < n;) { if ((minab & (1 << i)) != 0) { ret += target[i]; i++; } else { int j = i; while (i < n && (minab & (1 << i)) == 0) i++; ret += to_string(i - j); } } return ret; } }; main() { Solution ob; vector<string> v = {"blade"}; cout << (ob.minAbbreviation("apple",v)); }
อินพุต
"apple",{"blade"}
ผลลัพธ์
a4