iOS 문자열 반전 에 대해 자세히 이야기 합 니 다.
문자열 반전 은 알고리즘 문제 로 서 더 이상 기초 할 수 없 는 문제 입 니 다.역순 으로 옮 겨 다 니 고 두 바늘 로 옮 겨 다 니 며 재 귀 하 는 것 뿐만 아니 라 코드 도 분 단위 로 쓸 수 있 습 니 다.
void strrev(char *str) {
size_t start = 0;
size_t end = start + strlen(str) - 1;
while (start < end) {
char ch = str[start];
str[start++] = str[end];
str[end--] = ch;
}
}
OK,위의 코드 를 LeetCode 에 올 리 면 AC 가 되 는데 실제 상황 에서 AC 가 되 나 요?답 은 안 될 거 야!믿 을 만 한 문자열 반전 알고리즘 문 제 를 LeetCode 에 올 리 는 것 은 최소한 Medium 의 난이도 입 니 다.먼저 우 리 는 문자열 에 인 코딩 규칙 이 있다 는 것 을 알 고 있 습 니 다.예 를 들 어 우리 가 자주 사용 하 는 UTF-8,Windows 초기 에 사용 한 UTF-16(함수 명 W 접미사 가 있 는 API 는 이런 인 코딩 을 사용 합 니 다)등...영문 자모 등 ASCII 문자 의 경우 UTF-8 과 ASCII 인 코딩 은 모두 하나의 바이트 이기 때문에 상기 방법 은 큰 문제 가 없습니다.그러나 중국어 가 있 는 경우 중국어 문자 하나 가 UTF-8 에서 3 자 를 차지 해 단순히 바이트 로 뒤 집 으 면 난 장 판이 발생 한다.
그럼 어떻게 해결 하지?
가장 쉬 운 방법 은 mbstowcs 함수 로 char*형식의 문자열 을 wchar 로 변환 하 는 것 입 니 다.t 형식의 넓 은 문자열,wchart 이 유형 은 Linux,UNIX 시스템 에서 4 개의 바이트,Windows 에서 2 개의 바이트 를 차지한다.4 개의 바이트 란 문자 가 한자 든 이모 티 콘 이 든 저장 할 수 있 도록 UTF-32 로 인 코딩 된다 는 뜻 이다.그러나 2 개의 바이트,즉 UTF-16 에 대해 한 자 는 표시 할 수 있 지만 이모 지 와 같은 보조 평면 코드 위치 에 있 는 문 자 는 두 개의 메타 로 표시 해 야 하기 때문에 본 고의 방법 은 잠시 적용 되 지 않 는 다.
우선 개선 판 의 문자열 반전 을 살 펴 보 겠 습 니 다.
static void strrev2(char *str) {
setlocale(LC_CTYPE, "UTF-8");
size_t len = mbstowcs(NULL, str, 0);
wchar_t *wcs = (wchar_t *) calloc(len + 1, sizeof(wchar_t));
mbstowcs(wcs, str, len + 1);
size_t start = 0;
size_t end = start + len - 1;
while (start < end) {
wchar_t wc = wcs[start];
wcs[start++] = wcs[end];
wcs[end--] = wc;
}
wcstombs(str, wcs, wcstombs(NULL, wcs, 0));
free(wcs);
}
mbstowcs 와 같은 변환 함 수 를 사용 하려 면 먼저 문자열 의 시스템 인 코딩 을 설정 해 야 합 니 다.그렇지 않 으 면 함수 가 들 어 오 는 char*가 무엇 인지 확인 할 수 없습니다.본 고 는 소스 코드 든 시스템 환경의 std I/O 든 UTF-8 인 코딩 을 사용 합 니 다.다음 에 우 리 는 mbstowcs 를 호출 하여 목표 주소 와 문자 길 이 를 입력 하지 않 습 니 다.이것 은 함수 가 필요 한 wchar 를 직접 계산 할 수 있 습 니 다.우리 가 메모 리 를 신청 할 수 있 도록 t 개 수 를 되 돌려 줍 니 다.
그리고 wchart 의 일반적인 문자열 이 뒤 집 혔 습 니 다.마지막 으로 변환 하 는 것 을 잊 지 마 세 요.메모 리 를 풀 면 됩 니 다.
Bonus:코코아 개발 문자열 뒤 집기
iOS 개발 자로 서 OC 의 해결 방법 도 당연히 고려 해 야 한다.
프로젝트 1:
API 를 통 해 하위 문자열 을 옮 겨 다 니 고 새로운 NSMutableString 에 앞으로 삽입 합 니 다.
- (NSString *)my_stringByReversing {
NSMutableString *reversed = [NSMutableString stringWithCapacity:self.length];
NSRange range = NSMakeRange(0, self.length);
[self enumerateSubstringsInRange:range
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString * _Nullable substring, NSRange substringRange,
NSRange enclosingRange, BOOL * _Nonnull stop) {
[reversed insertString:substring atIndex:0];
}];
return [reversed copy];
}
이 방법 은 효과 가 가장 좋다.Composed Emoji(예 를 들 어👨👩👧👧)이러한 이모 지 는 여러 유 니 코드 문자 로 조합 되 어 있 기 때문에 4 바이트 의 wchar 라 도 추출 할 수 있 습 니 다.t 도 용납 할 수 없다.그러나 이런 방법의 단점 은 비용 이 너무 많이 드 는 것 이다.잠시 후에 우리 가 비교 해 보 자.프로젝트 2:
API 를 통 해 C String 을 가 져 온 다음 글 첫머리 에 기술 한 방법 으로 처리 한 다음 처 리 된 C String 구조 NSString 을 다시 사용 합 니 다.
- (NSString *)my_stringByReversing2 {
NSUInteger length = [self lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
char *buf = calloc(length + 1, 1);
[self getCString:buf maxLength:length + 1 encoding:NSUTF8StringEncoding];
strrev2(buf);
NSString *reversed = [NSString stringWithCString:buf encoding:NSUTF8StringEncoding];
free(buf);
return reversed;
}
이런 방법의 장점 은 바로 효율 성 이다.테스트 를 통 해 옮 겨 다 니 는 방법 에 비해 100 배 이상 성능 이 향상 되 었 지만 문 제 는 복잡 한 이모 지 를 처리 할 수 없다 는 것 이다.두 가지 방법 은 사용 중 에 잘 평가 해 야 한다.
프로젝트 3:
Swift。Swift 의 String 의 기본 단 위 는 Character 입 니 다.유 니 코드 스칼라 의 집합 으로 Composed Emoji 를 포함 하여 렌 더 링 가능 한 문 자 를 표시 합 니 다.또한 String 은 Bidirectional Collection 을 실현 하고 reversed 방법 을 가지 고 있어 문자열 반전 을 쉽게 실현 할 수 있 습 니 다.또한 Swift 의 String 은 Character 를 기반 으로 하기 때문에 특정한 문 자 를 가 져 오 는 작업 에 있어 서 이전의 Index 를 재 활용 할 수 있 으 면 재 활용 할 수 있 습 니 다.저 는 많은 사람들 이 즐겨 쓰 는 것 을 본 적 이 있 습 니 다.
str.index(str.startIndex, offsetBy: i)
이것 은 매우 비용 이 드 는 성능 입 니 다.Index 의 이동 작업 은 출발점 에서 계산 해 야 하기 때문에 이런 방법 으로 문자열 의 복잡 도 는 O(n!)와 비슷 합 니 다.관심 있 으 시 면 Swift 의 성능 을 시험 해 보 세 요.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Swift의 패스트 패스Objective-C를 대체하기 위해 만들어졌지만 Xcode는 Objective-C 런타임 라이브러리를 사용하기 때문에 Swift와 함께 C, C++ 및 Objective-C를 컴파일할 수 있습니다. Xcode는 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.