모든 지역화 및 문자열 유형에 작동하는 일반화 된 문자열 반전 함수를 작성할 수 있습니까?


16

방금 Dev-DaysJon Skeet (Tony the Pony) 프레젠테이션을 보고있었습니다 .

"문자열 역전 함수 작성"이 인터뷰 101을 코딩하고 있지만 실제로 모든 지역화 및 모든 문자열 유형에서 작동하지 않는 일반적인 문자열 역기능을 작성할 수 있는지 확실하지 않습니다.

입력 문자열이 ASCII, UTF8, UTF16 (고정 및 가변 길이)인지 여부를 감지하는 것 외에도
Jon이 강조한 '다음 문자에 적용 적용'(U + 0301) 코드가 있습니다. 그런 다음 표시되거나 표시되지 않을 수있는 합자가 있습니다. 또는 이중 문자로 인코딩됩니다.

"줄을 뒤집는 것"은 실제로 어려운 컴퓨터 과학 과제 중 하나 인 것 같습니다!


아냐, 어려움을 겪고 있지만 사람들에게 설명하기가 더 쉬운 것에 대한 중지 문제를 시도하십시오.
JB King

비 주관적이고 기술적 인 질문이므로 StackOverflow에 더 적합하다고 말하고 싶습니다 (다시 게시하지 마십시오. 충분한 사람들이 투표를 마치면 자동 마이그레이션됩니다).
Péter Török

1
프로그래밍 언어에 따라 다릅니다. 예를 들어 Ruby에서는 "stressed".reverse: p
Marcelo

훌륭한 철학적 질문. FWIW, Java의 StringBuilder는 대리자가 옳지 만 결합
자는

2
"자바를 사용하여이 문자열을 반대로 바꾸는 것"은 좋은 속임수입니다. :)
Scott C Wilson

답변:


5

예. 문자열을 얻으면 각 문자를 확실히 뒤집을 수 있습니다.

Jon이 지적한 문제는 반전이 의미가 있고 언어 및 문화적 규칙, 문자 및 인코딩을 준수한다는 것입니다. 더 깊이 갈수록 물이 흐릿 해집니다.

C #에서 모든 유형의 문자열 조작을 수행하는 경우 쓰기 및 읽을 때 변형 문화를 사용하면 안전하게 조작 할 수 있습니다. 그렇지 않으면 터키어 지원 전화 실패에 대비하십시오.

ToUpper ()는 너무 결백 해 보이지만 서사시 실패를 기다리고 있습니다.


2
다른 질문은-인터뷰 Q를 제외하고 문자열 역을 사용하는 사람은 무엇입니까? 나는 단지 I / O 포트의 낮은 수준의 버퍼 조작을 위해서만 필요했다 – 심지어는 실제로는 거의 문자열이 없다
Martin Beckett

@Martin-동의합니다. 어쩌면 영어 프로그램이 회문을 찾을 수 있을까요? 퀴즈 문제를 해결하는 것 외에는 사용하지 않았다고 생각합니다.
Jon Raynor

@ 마틴은 사실이다. 아이러니하게 만 된 것 같아요. :)
Scott C Wilson

2

일반적으로이 질문은 US-ASCII라고 가정합니다. 요점은 포인터의 작동 방식을 이해하는지 확인하기 위해 유니 코드에 대한 개인의 지식을 테스트하기에는 그리 중요하지 않습니다 (이것은 흥미로운 후속 조치이지만). 놀랍게도 많은 사람들이 이런 종류의 포인터 산술을 할 수 없습니다.


2
"유니 코드로 어떻게 실패할까요?" 좋은 후속 질문입니다
Martin Beckett

훌륭하지만 어쩌면 다소 발전했습니다-결국 "이 문자열을 제자리로 되 돌리십시오"는 초급 인터뷰 질문입니다. 당신은 아마 그들이 매우 부끄러워하고 당신이 그들을 따뜻하게하려고하지 않는 한, 노련한 사람 에게이 간단한 것을 묻지 않을 것입니다.
Scott C Wilson

1

인터뷰 질문으로, 일반적으로 8 비트 항목의 인플레 이스 스왑을 수행하여 순서를 반대로하는 기술적 인 부분에 대해서만 묻습니다 (실제로 어떤 문자를 나타내는 지에 관계없이).

동시에, 특히 상대적으로 노인을 인터뷰하는 경우에는 사양과 정확한 입력 형식에 대한 질문을 듣길 바랍니다. 단순히 8 비트 항목을 바꾸는 단순한 사례로 다시 보내더라도 그보다 더 넓은 의미로 생각하는지 여부를 알 수 있습니다.

광범위한 입력을 처리해야한다면 네트워크 스택과 같은 "스택"이라는 관점에서 생각하면됩니다. 여러 계층으로 소프트웨어를 빌드해야하며 각 계층은 특정 순서로 상당히 특정한 변환 세트를 적용합니다. 이를 통해 변환의 각 부분을 제어 할 수있을 정도로 단순하게 유지하고 요구 사항을 충족시킬 수있는 합리적인 기회를 가질 수 있습니다.

나는 적어도 어느 정도 실행 가능한 것을 발견 한 한 가지 가능성을 간략하게 설명합니다. 나는 더 좋은 아이디어를 가진 다른 사람들이있을 수 있음을 인정한 첫 번째 사람입니다. 적어도 나에게 이것은 실제 우아함이 거의없는 무차별 대인 공학과 비슷합니다.

일반적으로 다른 표현을 UCS-4 (일명 UTF-32)로 변환하여 시작하려고합니다. 이를 위해 일반적으로 사용자가 직접 입력하는 것보다 사용자의 입력에 의존하는 것이 좋습니다. 경우에 따라 특정 옥텟 시퀀스가 특정 인코딩 체계의 규칙을 따르지 않을 수도 있지만 특정 인코딩 체계를 따르는 지 거의 확신 할 수 없습니다.

다음 단계는 선택 사항입니다. 네 가지 유니 코드 정규화 형식 중 하나로 입력을 정규화 할 수 있습니다. 이 경우에, 당신은 것입니다 아마 정규 합성 한 다음 호환성 분해 다음 "NFKC"변환을 적용 할. 이것은 (가능한 경우) 발음 구별 부호 양식 (예 : Jon이 언급 한 U + 301)을 단일 코드 포인트로 변환합니다 (예 : "U + 301"을 가진 "A"는 "급성 인 라틴 대문자 A"로 변환 됨) , U + 00C1).

그런 다음 모든 문자를 처음부터 끝까지 살펴보고 문자열을 실제 문자로 나누고 분음 부호가 결합되어 있으면 수정 된 문자와 함께 유지합니다. 이것의 결과는 일반적으로 각각의 위치와 길이와 같은 문자열의 실제 문자 색인입니다.

일반적으로 이전 단계에서 작성한 색인을 사용하여 완전한 문자의 순서를 반대로 바꿉니다.

그런 다음 NFD (정식 분해)와 같은 다른 유니 코드 정규화 프로세스를 적용합니다 (선택 사항). 이렇게하면 앞에서 언급 한 "급성있는 라틴어 A"가 "라틴 대문자 A"와 "결합 된 급성"이라는 두 개의 코드 포인트로 다시 전환됩니다. 귀하의 의견은 그러나,로 시작하는 U + 00C1를 포함 할 일이 있다면, 그것은 또한 변환 할 것을 두 개의 코드 포인트로뿐만 아니라.

그런 다음 UCS-4 코드 포인트 시퀀스를 원하는 인코딩 (UTF-8, UTF-16 등)으로 인코딩합니다.

유니 코드 정규화 단계는 문자열을 저장하는 데 필요한 코드 포인트 수를 변경 / 변경할 수 있으므로 해당 코드 포인트를 포함하면 더 이상 원래 스토리지에 결과 문자열 피팅을 계획 할 수 없습니다. 분명히 결과 코드 포인트는 입력 코드 포인트와 직접 일치하지 않을 수도 있습니다.


Jon이 가져 오기 전에 U + 301을 보지 못했습니다. 이 모든 악센트 부호가있는 문자 그림 문자와 유니 코드에 필요한 이유를 볼 수 없습니다 - 나는 그것의 이전 버전과의 호환성을 상상
마틴 베켓

@Martin : 실제로 많은 분음 부호가 있습니다 (U + 0363에서 U + 036F까지는 완전히 사용되지 않지만 U + 0300에서 U + 036F까지의 전체 범위). 가장 일반적인 가능성 중 일부를 위해 미리 작성된 문자가 제공되며 필요한 다른 부분에 분음 부호를 결합합니다.
Jerry Coffin

추가 스토리지, 정규화 및 변환이 너무 많습니다. 문자를 반복하고 그 자리에 구성 코드 단위의 순서를 바꾸십시오. 그런 다음 모든 코드 단위의 순서를 정 위치로 바꿉니다.
중복 제거기
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.