공부/Swift

Swift : ASCII 코드 변환 방법

beeem 2021. 5. 17. 00:44

www.acmicpc.net/problem/2224

 

2224번: 명제 증명

첫째 줄에 출력할 명제의 개수 X개를 출력한다. 다음 X개의 줄에 증명될 수 있는 명제를 한 줄에 하나씩 출력한다. 명제를 출력할 때에는 전건 순으로 정렬하고, 전건이 같은 경우에는 후건 순으

www.acmicpc.net

이 문제를 풀다가 아스키코드 변환이 생각보다 불편해서 정리해야겠다는 생각이 들었다..
파이썬이나 C++은 정말 편하게 했는데...

let str = "abcde"

print("Test 1 :\n")
for ch in str {
  // asciiVaule: UInt8?
  let a = ch.asciiValue!
  
  print(a, type(of: a), separator: " is ")
  print(a, UnicodeScalar(a), type(of: UnicodeScalar(a)), separator: " -> ")
}

print("=============\n")
print("Test 2 :\n")

for ch in str {
  let u = ch.unicodeScalars.first!.value
  
  print(u, type(of: u), separator: " is ")
  print(u, UnicodeScalar(u), type(of: UnicodeScalar(u)), separator: " -> ")
}

print("\n----OR----\n")

for ch in str.unicodeScalars {
  print(ch.value, type(of: ch.value), separator: " is ")
}

print("=============\n")
print("Test 3 :\n")

for ch in str.utf16 {
  print(ch, type(of: ch), separator: " is ")
}

print("=============\n")
print("Test 4 :\n")

for ch in str {
  let u = (UnicodeScalar(String(ch))!.value)
  
  print(u, type(of: u), separator: " is ")
  print(u, UnicodeScalar(u), type(of: UnicodeScalar(u)), separator: " -> ")
}
Test 1 :

97 is UInt8
97 -> a -> Scalar
98 is UInt8
98 -> b -> Scalar
99 is UInt8
99 -> c -> Scalar
100 is UInt8
100 -> d -> Scalar
101 is UInt8
101 -> e -> Scalar
=============

Test 2 :

97 is UInt32
97 -> Optional("a") -> Optional<Scalar>
98 is UInt32
98 -> Optional("b") -> Optional<Scalar>
99 is UInt32
99 -> Optional("c") -> Optional<Scalar>
100 is UInt32
100 -> Optional("d") -> Optional<Scalar>
101 is UInt32
101 -> Optional("e") -> Optional<Scalar>

----OR----

97 is UInt32
98 is UInt32
99 is UInt32
100 is UInt32
101 is UInt32
=============

Test 3 :

97 is UInt16
98 is UInt16
99 is UInt16
100 is UInt16
101 is UInt16
=============

Test 4 :

97 is UInt32
97 -> Optional("a") -> Optional<Scalar>
98 is UInt32
98 -> Optional("b") -> Optional<Scalar>
99 is UInt32
99 -> Optional("c") -> Optional<Scalar>
100 is UInt32
100 -> Optional("d") -> Optional<Scalar>
101 is UInt32
101 -> Optional("e") -> Optional<Scalar>

 

1. asciiValue

우선 Test 1에 있는 asciiValue부터 보자.

  • Character Type에 사용할 수 있다.
  • 해당 문자의 아스키코드 값을 UInt8?로 반환하므로 옵셔널을 벗기고 Int 타입으로 변환하면 된다.

출처

 

Apple Developer Documentation

 

developer.apple.com

2. unicodeScalars

두 번째 방법은 Test 2에 있는 unicodeScalars이다.

??????????

문자열이 UnicodeScalarView라는 구조로 되어 있고 그 값을 접근하려면 unicodeScalars를 통해서 하면 된다는 것 같은데..
Swift의 String 세계는 너무 복잡한 것 같다... 원문 링크는 이곳에...

 

Apple Developer Documentation

 

developer.apple.com

Test 2에서 두 가지 방법을 사용했는데 첫 번째 방법은 이 분의 블로그에서 참고했다.

차이점은 문자열(String)이 아닌 문자(Character)unicodeScalars 프로퍼티를 적용했다는 점이다.
왜 그런지 한참 고민하다가 찾아보니 Character.UnicodeScalarView가 있었다. 진작 찾아볼걸

두 번째 방법은 문서 링크에 있는 예제처럼 문자열unicodeScalars 프로퍼티를 통해 아스키코드 값을 출력한다.
반환된 값의 타입은 UInt32이다.

 

3. utf16

세 번째 방법은 UTF16 View이다.

문자열을 UTF-16 포맷으로 보여주는 속성이다. (UTF-8도 있다)

UTF16 View 또는 UTF8 View로 변경하면 해당 코드 포맷의 컬렉션이 된 것이기 때문에 요소에 접근해야 한다.
즉 UTF16 View 타입에서 Unit을 가져와야 한다.

first나 last 또는 startIndes 사용

예시를 통해 보자면

A를 문자열로 입력받아 utf16 포맷으로 변환하고 나니 UTF16 View 타입이 된 것을 볼 수 있고,
first 프로퍼티를 통해 가져온 Unit의 타입은 UInt16? 인 것을 확인할 수 있다.

4. UnicodeScalar

Unicode.Scalar ???

네 번째 방법은 Unicode.Scalar의 typealias인 UnicodeScalar이다.

초기화 방법이 다음과 같기 때문에 Character를 String으로 변환하여 value프로퍼티를 이용하면 유니코드 값을 얻을 수 있다.

UInt8은 옵셔널이 아니네??

 

Unicode scalar를 UInt32로 표현한다.

이렇게 번거롭게 변환하는 것보단 1번 방법을 자주 사용할 것 같다.

어려웠지만 다른 방법을 이리저리 찾아보는 과정이 꽤 재밌었다.

 

잘못된 부분 또는 부족한 점 지적해주시면 감사하겠습니다!