ระยะห่างของการแก้ไข (หรือ Levenshtein)ระหว่างสองสายคือจำนวนที่น้อยที่สุดของการแทรกอักขระเดียวการลบและการแทนที่ที่จำเป็นในการแปลงสตริงหนึ่งเป็นอีกสตริงหนึ่ง หากทั้งสองสตริงมีความยาว n แต่ละตัวเป็นที่ทราบกันดีว่าสิ่งนี้สามารถทำได้ในเวลา O (n ^ 2) โดยการโปรแกรมแบบไดนามิก รหัสงูใหญ่ต่อไปดำเนินการคำนวณนี้สำหรับสองสายและs1
s2
def edit_distance(s1, s2):
l1 = len(s1)
l2 = len(s2)
matrix = [range(l1 + 1)] * (l2 + 1)
for zz in range(l2 + 1):
matrix[zz] = range(zz,zz + l1 + 1)
for zz in range(0,l2):
for sz in range(0,l1):
if s1[sz] == s2[zz]:
matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz])
else:
matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz] + 1)
return matrix[l2][l1]
ในภารกิจนี้คุณต้องเข้าใกล้มากที่สุดเท่าที่จะทำได้เพื่อคำนวณระยะทางแก้ไข แต่ด้วยการ จำกัด หน่วยความจำอย่างรุนแรง รหัสของคุณได้รับอนุญาตให้กำหนดหนึ่งอาร์เรย์ที่มีจำนวนเต็ม 1,000 32- บิต 32 บิตและนี่จะเป็นที่เก็บข้อมูลชั่วคราวเพียงอย่างเดียวที่คุณใช้ในการคำนวณของคุณ ตัวแปรและโครงสร้างข้อมูลทั้งหมดจะต้องมีอยู่ในอาร์เรย์นี้ โดยเฉพาะอย่างยิ่งคุณจะไม่สามารถใช้อัลกอริทึมด้านบนสำหรับสตริงที่มีความยาว 1,000 ซึ่งจะทำให้คุณต้องเก็บอย่างน้อย 1,000,000 หมายเลข ในกรณีที่ภาษาของคุณไม่มีจำนวนเต็ม 32 บิต (เช่น Python) ตามธรรมชาติคุณต้องตรวจสอบให้แน่ใจว่าคุณไม่เคยเก็บตัวเลขที่มีขนาดใหญ่กว่า 2 ^ 32-1 ไว้ในอาร์เรย์
คุณสามารถอ่านข้อมูลโดยใช้ไลบรารีมาตรฐานที่คุณเลือกโดยไม่ต้องกังวลเกี่ยวกับข้อ จำกัด ของหน่วยความจำในส่วนนั้น เพื่อให้การแข่งขันมีความยุติธรรมสำหรับส่วนหลักของรหัสของคุณคุณสามารถใช้การดำเนินการที่เทียบเท่ากับการทำงานในภาษาการเขียนโปรแกรม C และไม่สามารถใช้ไลบรารีภายนอกใด ๆ
เพื่อความชัดเจนเป็นพิเศษหน่วยความจำสำหรับจัดเก็บข้อมูลอินพุตหรือใช้โดยล่ามภาษา JVM ของคุณเป็นต้นไม่นับรวมถึงขีด จำกัด ของคุณและคุณไม่สามารถเขียนอะไรลงดิสก์ คุณต้องถือว่าข้อมูลอินพุตเป็นแบบอ่านอย่างเดียวเมื่ออยู่ในหน่วยความจำดังนั้นคุณจึงไม่สามารถนำข้อมูลนั้นกลับมาใช้เพื่อให้มีพื้นที่ทำงานมากขึ้น
ฉันต้องใช้อะไรบ้าง
รหัสของคุณควรอ่านเป็นไฟล์ในรูปแบบต่อไปนี้ มันจะมีสามบรรทัด บรรทัดแรกคือระยะแก้ไขที่แท้จริง ประการที่สองคือสตริงที่ 1 และที่สามคือสตริง 2. ฉันจะทดสอบกับข้อมูลตัวอย่างที่https://bpaste.net/show/6905001d52e8ที่สายมีความยาว 10,000 แต่มันไม่ควรจะพิเศษสำหรับข้อมูลนี้ มันควรจะส่งออกระยะแก้ไขที่เล็กที่สุดที่สามารถหาได้ระหว่างสองสาย
คุณจะต้องพิสูจน์ระยะทางในการแก้ไขของคุณจริง ๆ แล้วมาจากชุดการแก้ไขที่ถูกต้อง รหัสของคุณควรมีสวิตช์ซึ่งเปลี่ยนเป็นโหมดที่อาจใช้หน่วยความจำมากขึ้น (เท่าที่คุณต้องการ) และส่งออกการดำเนินการแก้ไขที่ให้ระยะทางแก้ไขของคุณ
คะแนน
(optimal edit distance/divided by the edit distance you find) * 100
คะแนนของคุณจะเป็น ในการเริ่มต้นสิ่งต่าง ๆ สังเกตว่าคุณสามารถรับคะแนนได้โดยนับจำนวนการจับคู่ที่ไม่ตรงกันระหว่างสองสาย
คุณสามารถใช้ภาษาใดก็ได้ที่คุณชอบซึ่งสามารถใช้งานได้อย่างอิสระและติดตั้งง่ายใน Linux
เน็คไททำลาย
ในกรณีที่ไทเบรคฉันจะรันโค้ดของคุณบนเครื่อง Linux และรหัสที่เร็วที่สุดจะเป็นผู้ชนะ
{ uint32_t foo[1000]; for (foo[0] = 0; foo[0] < 5; ++foo[0]) printf("%d ", foo[0]); }
นี้คือสมมติอาร์เรย์ของคุณ 32 foo
จำนวนเต็มบิตจะถูกเรียกว่า
for(int i=0;i<=5;i++)
อนุญาตให้ใช้เพราะเก็บข้อมูลไว้i
หรือไม่