드디어 기본 연산자 마지막 편이다.

범위연산자가 이전에 한번 잠깐 다룬적이 있다.

 

Closed Range Operator( 폐쇄 범위 연산자)

범위연산자는 말그대로 범위를 정의하는 연산이다

이전에 for 문을 적을때 아래와같은 형태로 적었는데

 

for i in 0 ... 10 {

}

 

0 ... 10 이 부분이 범위 연사자를 사용한 부분이다.

0이상 10이하를 지정한것인데 for 문은 이러한 범위에서 순서대로 0, 1, 2 가져오며 반복한다는 의미이다.

 

0 ... 10 이러한 범위 연산자를 폐쇄 범위 연사자라 하며

양 끝이 정해져있다 하여 폐쇄 이다.

그럼 양끝이 정해져있지 않은것도 있다.

 

 

Half-Open Range Operator

한글로 뭐라고 번역해야 할지 모르겠다.

위의 폐쇄 범위 연산자와 유사한데 

맨 뒤 끝 이전까지 범위를 지정한 것을 일컫는다.

 0 ..< 10 이렇게하면 0이상 10미만이다. 점이 이번엔 두개다 중요한 부분이다.

 

 

 

One-sided Ranges( 단측 범위 연산자 )

이번엔 양 끝중 한쪽만 범위를 지정한 것이다.

이미 있는 배열에 대해 범위를 지정할때 이미 양끝이 정해져 있기에 한쪽만 지정해줘서 편하게 사용한다.

위의 폐쇄, 하프오픈 범위 연산자랑 비슷하다.

 

ex1)

    let alphabet = ["A","B","C","D","E"]
    for c in alphabet[...2] {
      print(c)
    }
    
    print()
    
    for c in alphabet[..<2] {
      print(c)
    }
    
    print()
    
    for c in alphabet[2...] {
      print(c)
    }
    
    print()

결과:

A

B

C

 

A

B

 

C

D

E

 

첫번째 for문은 alphabet 배열의 처음부터 인덱스2, 그러니까 처음부터 세번째까지 범위를 지정하여 

print문에서 A B C가 출력된것이다.

 

두번째 for문은 alphabet 배열의 처음부터 인덱스2이전까지, 그러니까 처음부터 두번째까지 범위를 지정하여

print문에서 A B가 출력된다.

 

세번째 for문은 인덱스 2 부터(세번째 부터) 끝까지  범위를 지정하여 

print문에서 C D E가 출력되었다

 

단 2초과에 해당하는 <.. 은 없다

스위프트에는 사용자가 직접 연산자를 지정할 수 있는데 만약 필요하다면 지정해서 사용하면 된다.

 

 

이것 외에도 따로 range를 생성해서 지정해줄수 있다.

해당 부분에 대해 알고 싶다면 Range, NSRange에 대해 검색해봄이 좋을듯하다.

난 따로 생성해서 지정할땐 String의 부분을 추출하거나 부분 속성을 변경해줄때만 사용해보고 그외엔 없다.

 

단어를 찾기전에 잠시 인덱스에 대해 이야기를 해보자

 

스위프트의 문자열 내부는 인덱스로 찾는다

아래 10글자의 문자열이 담긴 text변수는

let text = "가나다라마바사아자차"

기본적으로 startIndex와 endIndex라는 속성을 가지고있다.

 

그래서 내부 인덱스를 검색해서 문자열 안에서 문자열을 빼내려면 인덱스범위를 포함하고있는

Range라는 녀석을 만들어서 배열에서 인덱스로 뽑아내듯 문자열 옆에 붙여주면 뽑아진다.

 

그래서 아래와 같이 처음과 끝을 지정해서 뽑아주면 처음 문자열과 같은 내용이 출력된다.

 

 

조금 특이한게 끝의 인덱스를 포함을 안시켜야 나온다.

 

이제 다시 원래 하려던 문자열 내부의 단어를 찾아라라는 주제로 돌아오면

 

문자열 내부에 어떠한 단어가 있는지만을 판단하기에는 매우 좋은 함수가있다

String 클래스에는 contains()라는 함수가 있는데

 

이를 이용하면 

let isContains = text.contains("다라")

위 코드는 text에 만약 "다라"가 포함되어있다면 true를 아니라면 false를 반환해준다.

 

단어가 있는지는 검사할 수 있으나 이 방법으론 단어가 어디에 있는지도 찾지 못한다.

위에서 문자열 내부에 값을 뽑아내려면 인덱스로 찾는다고했다.

 

그리고 그 인덱스는 range로 만들어내야 한다. 

 

그리고 String 클래스는 인덱스를 만들어주는 함수중 range() 라는게 있다

 

let range0 = text.range(of: "다라")

 

이렇게 하면 text 내부에 "다라" 라고 적힌 녀석중 가장 처음녀석의 위치(인덱스)를 반환하게 된다.

위치일뿐이지 아직 단어 자체는 없다.

 

이 범위, range는 다양하게 쓸 수 있으나 여기서는 별 의미없이 해당 단어 위치만을 뽑아와 서브로 만들어줄꺼다.

총 세개의 범위에서 뽑아낼건데

 

1. 단어 시작전까지 : w0

2.단어 : w1

3.단어 이후 부터 끝까지 : w2

 

 

해당 소스를 돌리면

 

가나

다라

마바사아자차

 

라고 출력이 된다 

위부터 w0 ~ w2 순이다.

 

위 소스들을 좀 정리하자면 

 

 

guard로 "다라"가 없으면 nil을 있다면 해당 세부분을 String으로 변환해서 반환하는 함수로 만들었다.

참고로 문자열에서 Range를써서 뽑은 값은 SubString으로 String으로 변환해줘야 편하게 쓸 수 있다.

 

 

 

 

그냥 문자열을 쪼개는건 split이 편하다.

 

String.range는 아래와 같이 조건을 줘서

검색범위(range), 검색조건(아래소스는 뒤에서부터 검색), NSLocal.... 어느때 사용하는지를 모르겠다.

let range = text.range(of: "다라", options: .backwards, range: text.startIndex ..< text.endIndex, locale: nil)

 

위 코드처럼 조건을 줘서 위치검색이 가능하다.

 

 

 

1038 : [기초-산술연산] 정수 두 개 입력받아 합 출력하기1 with Swift

35. 콘솔에서 두 개의 정수를 입력받아 합을 출력하라.

입력 : 한 줄에 공백으로 두개의 정수가 구분되어 입력된다. 입력되는 정수의 범위는 다음과 같다.

입력 범위 : -1073741824 ~ 1073741824

입력 예시

123 -123

출력 예시

0

JAVA

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int value0 = scan.nextInt();
		int value1 = scan.nextInt();
		scan.close();
		System.out.println(value0 + value1);
	}
}

 

 

Swift 4.2

import Foundation

let line = readLine()
if line != nil {
    let valueArray = line!.split(separator: " ")
    if valueArray.count == 2 {
        if let value0 = Int(valueArray[0]), let value1 = Int(valueArray[1]) {
            print((value0 + value1))
        }
    }
}

 

 

 

이번문제는 읽자마자 아! 많이 하는 실수인 계산시의 중간값이 범위를 오버하는걸 방지하는 문제이구나!

라고 생각했는데 밑의 단 범위는 이것이다 라고 바로 부정당했네요.

잠깐 이야기하자면

int 의 범위내의 입력값과

int의 범위 내의 출력값이 나온다고해도

그 중간값이 int의 범위내에 있다고 생각 할 수 없습니다.

중간식이 단순 연산이라면 금방 눈치를 채겠지만 막 복잡한 식이 들어가면 어느순간에 범위를 넘어서 버릴수도 있습니다.

물론 이러한 문제는 금방 디버깅시에 발견가능하지만 중간값을 생각안하면 디버깅툴에서 알려주는 라인의 오류를 이해를 못할 수 도 있기에

잠깐 이야기 해봤습니다.

https://codeup.kr/problem.php?id=1038

 

[기초-산술연산] 정수 두 개 입력받아 합 출력하기1

정수 2개를 입력받아 합을 출력하는 프로그램을 작성해보자. (단, 입력되는 정수는 -1073741824 ~ 1073741824 이다.)

codeup.kr

 

 

 

 

 

 

 

 

1039 : [기초-산술연산] 정수 두 개 입력받아 합 출력하기2 with Swift

36.콘솔에서 정수 두 개를 입력받아 합을 출력하라. 단 입력 되는 정수의 범위는 다음과 같다.

입력 범위 : −2147483648 ∼ 2147483647

입력: 두 개의 정수가 공백으로 구분되어 한 줄에 입력된다.

입력 예시

2147483647 2147483647

출력 예시

4294967294

JAVA

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		long longValue = 0;
		for (int i = 0; i < 2; i++) {
			longValue += scan.nextInt();
		}
		scan.close();
		System.out.println(longValue);
	}
}

 

 

 

Swift 4.2

import Foundation

let line = readLine()
if line != nil {
    let valueArray = line!.split(separator: " ")
    if valueArray.count == 2 {
        if let value0 = Int(valueArray[0]), let value1 = Int(valueArray[1]) {
            print( value0 + value1 )
        }
    }
}

 

 

 

스위프트가 이전 모든 값이 int범위였을때랑 같은 소스다! 잘못한거 아니냐! 라고 말할수 있겠으나

사실 스위프트의 기본 Int 범위는 상당히 넓다.

Swift 4.2 값 범위 - 소스

print("Int       : \(Int.min) ~ \(Int.max)")
print("Int8      : \(Int8.min) ~ \(Int8.max)")
print("Int16     : \(Int16.min) ~ \(Int16.max)")
print("Int32     : \(Int32.min) ~ \(Int32.max)")
print("Int64     : \(Int64.min) ~ \(Int64.max)")
print("UInt      : \(UInt.min) ~ \(UInt.max)")
print("UInt8     : \(UInt8.min) ~ \(UInt8.max)")
print("UInt16    : \(UInt16.min) ~ \(UInt16.max)")
print("UInt32    : \(UInt32.min) ~ \(UInt32.max)")
print("UInt64    : \(UInt64.min) ~ \(UInt64.max)")
print("CLong     : \(CLong.min) ~ \(CLong.max)")
print("CLongLong : \(CLongLong.min) ~ \(CLongLong.max)")
print("ULONG     : \(ULONG.min) ~ \(ULONG.max)")

 

 

Swift 4.2 값 범위 - 결과

Int : -9223372036854775808 ~ 9223372036854775807

Int8 : -128 ~ 127

Int16 : -32768 ~ 32767

Int32 : -2147483648 ~ 2147483647

Int64 : -9223372036854775808 ~ 9223372036854775807

UInt : 0 ~ 18446744073709551615

UInt8 : 0 ~ 255

UInt16 : 0 ~ 65535

UInt32 : 0 ~ 4294967295

UInt64 : 0 ~ 18446744073709551615

CLong : -9223372036854775808 ~ 9223372036854775807

CLongLong : -9223372036854775808 ~ 9223372036854775807

ULONG : 0 ~ 4294967295

대부분 보면 결국 Int32 아니면 Int64 범위입니다.

Swift 4.2에선 기본Int 범위가 Int64범위라 이번 문제에선 결국 중간값에대한 형을 변환안해줘되 되요

https://codeup.kr/problem.php?id=1039

 

[기초-산술연산] 정수 두 개 입력받아 합 출력하기2

+ 연산자를 사용하면 된다. 단, 계산된 결과가 int 데이터형의 표현 범위를 넘어가기 때문에 다른 데이터형을 사용해야 한다. [주의] int 데이터형은 %d로 입출력하고, long long int 데이터형은 %lld로 입출력한다.

codeup.kr

 

 

1040 : [기초-산술연산] 정수 한 개 입력받아 부호 바꿔 출력하기 with Swift

37. 콘솔에서 한 개의 정수를 입력받고 부호를 바꿔 출력 하라.

입력 범위: -2147483647 ~ 2147483647

입력 예시:

-1

출력 예시:

1

JAVA

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int value = scan.nextInt();
		scan.close();
		System.out.println(-value);
	}
}

 

 

Swift 4.2

import Foundation

let line = readLine()
if line != nil {
    if let value = Int(line!) {
        print(-value)
    }
}

 

 

https://codeup.kr/problem.php?id=1040

 

[기초-산술연산] 정수 한 개 입력받아 부호 바꿔 출력하기

단항 연산자인 -(negative)를 변수 앞에 붙이면 부호가 반대로 바뀌어 계산된다. [예시] int a; scanf("%d", &a); printf("%d", -a);

codeup.kr

 

+ Recent posts