เป็นไปได้หรือไม่ที่จะเขียนฟังก์ชั่นย้อนกลับของสตริงทั่วไปที่เหมาะกับการแปลท้องถิ่นและประเภทสตริงทั้งหมด?


16

ฉันแค่ดูการนำเสนอJon Skeet (กับ Tony the Pony) จาก Dev-Days

ถึงแม้ว่า "ฟังก์ชั่นเขียนกลับสตริง" กำลังเขียนรหัสสัมภาษณ์ 101 - ฉันไม่แน่ใจว่าจริง ๆ แล้วมันเป็นไปได้ที่จะเขียนฟังก์ชั่นย้อนกลับของสตริงทั่วไปแน่นอนไม่ได้หนึ่งที่ทำงานในท้องถิ่นทั้งหมดและทุกประเภทสตริง

นอกเหนือจากการตรวจสอบว่าสตริงอินพุตคือ ascii, UTF8, UTF16 (ความยาวคงที่และผันแปร) เป็นต้น
มี 'ใช้การเน้นเสียงกับอักขระถัดไป' (U + 0301) รหัสที่จอนเน้นไว้ จากนั้นจะมีลิ้นที่อาจแสดงหรือไม่แสดงหรือเข้ารหัสเป็นอักขระคู่

ดูเหมือนว่า "การย้อนกลับสตริง" เป็นหนึ่งในงานด้านวิทยาศาสตร์คอมพิวเตอร์ที่ยากขึ้น!


ไม่ลองใช้ปัญหาการหยุดพักเพื่อสิ่งที่ยากขึ้น แต่ก็ง่ายที่จะอธิบายให้ผู้คนฟัง
JB King

เป็นคำถามทางเทคนิคที่ไม่น่าสงสัยเลยฉันอยากจะบอกว่านี่จะเหมาะกับ StackOverflow มากขึ้น (โปรดอย่าโพสต์ใหม่ตรงนั้นแม้ว่ามันจะเป็นแบบอัตโนมัติถ้ามีคนลงคะแนนพอที่จะปิดที่นี่)
PéterTörök

1
ขึ้นอยู่กับภาษาการเขียนโปรแกรม ตัวอย่างเช่นใน Ruby เป็นเรื่องง่ายเหมือน"stressed".reverse: p
Marcelo

คำถามเชิงปรัชญาที่ยอดเยี่ยม FWIW, Java ของ StringBuilder รับอุ้มท้องขวา แต่ไม่ combiners
kdgregory

2
"ย้อนกลับสายอักขระนี้โดยใช้ Java" เป็นคำถามหลอกลวงที่ดี :)
Scott C Wilson

คำตอบ:


5

ใช่. หากเราได้รับสตริงเราสามารถย้อนกลับอักขระแต่ละตัวได้อย่างแน่นอน

ปัญหาที่จอนชี้ให้เห็นก็คือการกลับรายการนั้นสมเหตุสมผลและสอดคล้องกับภาษาและกฎทางวัฒนธรรมตัวละครและการเข้ารหัส น้ำจะมืดมนยิ่งคุณเข้าไป

หากคุณกำลังจัดการสตริงชนิดใด ๆ ใน C # ให้ใช้วัฒนธรรม Invariant ในขณะที่เขียนและอ่านวิธีนี้คุณจะสามารถจัดการได้อย่างปลอดภัย มิฉะนั้นเตรียมความพร้อมสำหรับการโทรสนับสนุนตุรกีที่ล้มเหลว

ToUpper () ดูไร้เดียงสา แต่มันเป็นมหากาพย์ความล้มเหลวที่จะเกิดขึ้น


2
คำถามอื่น ๆ คือ - ทุกคนที่เคยใช้สตริงกลับสำหรับ (นอกเหนือจากการสัมภาษณ์ Q)? ฉันเคยต้องการมันสำหรับการจัดการบัฟเฟอร์ระดับต่ำของพอร์ต I / O - และถึงแม้จะแทบไม่เคยใช้สายเลยก็ตาม
Martin Beckett

@Martin - เห็นด้วย อาจเป็นโปรแกรมภาษาอังกฤษในการค้นหา palidromes? ฉันไม่คิดว่าฉันใช้มันนอกเหนือไปจากการตอบคำถามแบบทดสอบ
Jon Raynor

@ มาร์ตินจริง ฉันคิดว่ามันทำได้แค่แดกดัน :)
Scott C Wilson

2

โดยทั่วไปเมื่อคำถามนี้ถูกถามก็จะสมมติว่า US-ASCII ประเด็นก็คือไม่มากนักที่จะทดสอบความรู้ของ Unicode (แม้ว่าจะเป็นสิ่งที่น่าสนใจในการติดตาม) เพื่อดูว่าพวกเขาเข้าใจวิธีการทำงานของพอยน์เตอร์หรือไม่ ผู้คนจำนวนมากไม่สามารถทำการคำนวณทางคณิตศาสตร์ชนิดนี้ได้


2
"สิ่งนี้จะล้มเหลวด้วย unicode ได้อย่างไร" เป็นคำถามที่ติดตามดี
มาร์ติน Beckett

ดี แต่อาจค่อนข้างขั้นสูง - หลังจากทั้งหมด "ย้อนกลับสตริงนี้ในสถานที่" เป็นคำถามสัมภาษณ์ระดับเริ่มต้น คุณอาจจะไม่ถามคนที่มีประสบการณ์ในแบบนี้เว้นแต่ว่าพวกเขาอาจเขินอายมากและคุณพยายามทำให้ร่างกายอบอุ่นขึ้น
Scott C Wilson

1

ในฐานะที่เป็นคำถามสัมภาษณ์มักถามเกี่ยวกับบิตทางเทคนิคของการทำสลับแบบในรายการ 8 บิตเพื่อสลับลำดับ (โดยไม่คำนึงถึงตัวละครที่พวกเขาอาจเป็นตัวแทนจริง ๆ )

ในเวลาเดียวกันโดยเฉพาะอย่างยิ่งถ้าคุณสัมภาษณ์คนที่ค่อนข้างอาวุโสคุณอย่างน้อยก็หวังว่าจะได้ยินคำถามเกี่ยวกับสเปคและรูปแบบที่แน่นอนของอินพุต แม้ว่าคุณจะนำพวกเขากลับไปที่กรณีง่าย ๆ เพียงแค่แลกเปลี่ยนไอเท็ม 8 บิตโดยรู้ว่าพวกเขาคิดในแง่ที่กว้างกว่านั้นอาจมีประโยชน์หรือไม่

หากคุณต้องจัดการกับอินพุตที่หลากหลายคุณต้องคิดในแง่ของ "สแต็ก" ซึ่งเป็นเหมือนสแต็กเครือข่าย คุณต้องสร้างซอฟต์แวร์ของคุณในหลายเลเยอร์ซึ่งแต่ละชุดจะใช้การแปลงที่ค่อนข้างเฉพาะเจาะจงตามลำดับเฉพาะ สิ่งนี้ช่วยให้คุณทำให้การเปลี่ยนแปลงแต่ละส่วนนั้นง่ายพอที่คุณจะสามารถควบคุมมันได้และมีโอกาสพอสมควรที่จะทำให้มันเป็นไปตามข้อกำหนดของมัน

ฉันจะร่างหนึ่งความเป็นไปได้ที่ฉันพบว่าอย่างน้อยค่อนข้างใช้การได้ ฉันเป็นคนแรกที่ยอมรับว่าอาจมีคนอื่นที่มีแนวคิดที่ดีกว่า อย่างน้อยสำหรับฉันนี่ดูเหมือนจะเป็นงานวิศวกรรมที่โหดเหี้ยม แต่มีความสง่างามที่แท้จริงเพียงเล็กน้อย

ตามปกติคุณต้องการเริ่มต้นด้วยการแปลงการนำเสนออื่นเป็น UCS-4 (aka UTF-32) สำหรับสิ่งนี้คุณมักต้องการพึ่งพาข้อมูลจากผู้ใช้มากกว่าที่จะพยายามคิดออกเอง ในบางกรณีคุณสามารถมั่นใจได้ว่าลำดับของอ็อตเท็ตบางตัวไม่เป็นไปตามกฎของรูปแบบการเข้ารหัสเฉพาะ แต่คุณแทบจะไม่สามารถ (ถ้าเคย) แน่ใจได้ว่ามันเป็นไปตามรูปแบบการเข้ารหัสเฉพาะ

ขั้นตอนต่อไปเป็นทางเลือก คุณสามารถทำให้ปกติอินพุตเป็นหนึ่งในสี่แบบฟอร์มการทำให้เป็นมาตรฐาน Unicode ในกรณีนี้คุณอาจต้องการใช้การแปลง "NFKC": การสลายตัวของความเข้ากันได้ตามด้วยองค์ประกอบที่เป็นที่ยอมรับ สิ่งนี้ (หากเป็นไปได้) แปลงการรวมรูปแบบการออกเสียง (เช่น U + 301 ที่จอนพูดถึง) เป็นรหัสจุดเดียว (เช่น "A" กับ "U + 301" จะถูกแปลงเป็น "ละตินทุน A กับเฉียบพลัน" , U + 00C1)

จากนั้นคุณเดินผ่านตัวละครทุกตัวตั้งแต่ต้นจนจบแบ่งสตริงเป็นตัวอักษรจริง - และถ้ามี (ยัง) รวมเครื่องหมายกำกับเสียงให้พวกเขาด้วยตัวละครที่พวกเขาปรับเปลี่ยน ผลลัพธ์ของสิ่งนี้มักจะเป็นดัชนีของตัวละครจริงในสตริงเช่นตำแหน่งและความยาวของแต่ละตัว

คุณย้อนกลับลำดับของอักขระที่สมบูรณ์เหล่านั้นโดยทั่วไปแล้วโดยใช้ดัชนีที่คุณสร้างขึ้นในขั้นตอนก่อนหน้า

จากนั้นคุณ (อีกทางเลือก) ใช้กระบวนการ Unicode Normalization อื่นเช่น NFD (การสลายตัวตามมาตรฐาน) สิ่งนี้จะเปลี่ยน "Latin A ด้วยเฉียบพลัน" ดังกล่าวกลับเป็นสองจุดรหัส - "ละตินทุน A" และ "การรวม Acute" หากอินพุตของคุณมี U + 00C1 เริ่มต้นอย่างไรก็ตามมันจะแปลงค่านั้นให้เป็นจุดโค้ดสองจุดเช่นกัน

จากนั้นคุณเข้ารหัสลำดับของจุดโค้ด UCS-4 เป็นการเข้ารหัสที่ต้องการ (UTF-8, UTF-16, ฯลฯ )

โปรดทราบว่าขั้นตอนการนอร์มัลไลซ์เซชั่น Unicode สามารถ / จะเปลี่ยนจำนวนจุดรหัสที่จำเป็นในการจัดเก็บสตริงดังนั้นถ้าคุณรวมเหล่านั้นคุณไม่สามารถวางแผนเกี่ยวกับผลสตริงที่เหมาะสมในการจัดเก็บเดิม เห็นได้ชัดว่าเพียงพอจุดรหัสผลลัพธ์อาจไม่ตรงกับจุดรหัสอินพุตโดยตรง


ฉันไม่ได้เจอ U + 301 ก่อนที่จอนจะนำมันมา ฉันไม่สามารถเห็นได้ว่าทำไมจึงจำเป็นต้องใช้ unicode กับ glyphs สำหรับอักขระที่เน้นเสียงทั้งหมด - ฉันจินตนาการว่ามันเข้ากันได้ย้อนหลัง
Martin Beckett

@ มาร์ติน: จริง ๆ แล้วมีการรวมจำนวนกำกับ (ทั้งช่วงจาก U + 0300 ถึง U + 036F แม้ว่าจาก U + 0363 ถึง U + 036F จะล้าสมัยที่สุด) อักขระที่มีการจัดเตรียมไว้ล่วงหน้านั้นมีให้สำหรับความเป็นไปได้ที่พบได้บ่อยที่สุด
Jerry Coffin

หน่วยความจำเสริมปกติและการแปลงมากเกินไป เพียงทำซ้ำตัวอักษรและย้อนกลับลำดับของหน่วยรหัสส่วนประกอบในสถานที่ จากนั้นสลับลำดับของหน่วยรหัสทั้งหมดในสถานที่
Deduplicator
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.