[알고리즘] Swift 평균 구하기

이유진·2024년 3월 4일
0

알고리즘

목록 보기
12/32

문제 설명

정수를 담고 있는 배열 arr의 평균값을 return하는 함수, solution을 완성해보세요.


제한사항

  • arr은 길이 1 이상, 100 이하인 배열입니다.
  • arr의 원소는 -10,000 이상 10,000 이하인 정수입니다.

입출력 예

arrreturn
[1,2,3,4]2.5
[5,5]5

풀이 과정

이번에도 평균 구하기!
지난번 배열의 평균값 문제랑 같더라.
그래서 해결은 금방 했지만, 다른 풀이 방식을 더 공부해보기로 했다.

“평균값 = 모든 수를 더한 총합을 총 개수로 나눈 값” 이므로
1. for ~ in 구문 사용해 arr 배열의 원소의 합을 구하고,
2. count를 사용해 배열의 길이(배열 내 원소의 개수)를 구해
1에서 2를 나눠주었다.


Solution

func solution(_ arr:[Int]) -> Double {
    var sum = 0

    for i in arr {
    sum += i    
    }

    return Double(sum) / Double(arr.count)
}

Another Solution

합을 구하는 문제를 풀 때 마다 보았던 풀이 방식들 중 하나가
Swift의 고차함수인 reduce를 사용하는 것이었다.

일단 고차함수 개념부터 알아보자

고차함수
다른 함수를 전달이자로 받거나, 함수의 실행 결과를 함수로 반환하는 함수
대표적인 고차함수에는 map, filter, reduce 가 있다.

📎 Map

특정 컨테이너의 데이터를 변형해서 새로운 배열로 만들어서 리턴해주는 메소드.
새로운 컨테이너를 만들기 때문에 기존 데이터는 변형되지 않는다.

//example
let numbers = [1, 2, 3, 4, 5]
var plusOne = []

//클로저 생략하지 않고 표현
plusOne = numbers.map({ (number : Int) -> Int in
		return number + 1
})

//생략 표현을 해주면 $ 사인 활용해 인자 인덱스 표현(아래 클로저 단축인자 개념 참고)
let numbersPlusOne = numbers.map({ $0 + 1 })

📎 Filter

콜렉션 내부에서 조건에 맞는 데이터들만 골라 새로운 콜렉션을 생성한다.
filter 메소드는 클로저를 인자로 받고, 이 클로저 내부에 어떤 데이터를 포함시킬 지 그 조건을 정의한다.

//example
let numbers: [Int] = [1, 2, 3, 4, 5, 6]
var isEven: [Int] = []

//클로저 생략하지 않고 표현
isEven = numbers.filter({ (number: Int) -> Int in
    return number % 2 == 0 //짝수

//생략 표현
var isEven = numbers.filter { $0 % 2 == 0 } //[2, 4, 6]

📎 Reduce

콜렉션 내부의 데이터들을 하나로 통합시킨다.
두 개의 인자를 받는다. 첫 번째 인자는 통합할 데이터의 초기값, 두 번째 인자는 클로저이다.
이 클로저에서는 값을 어떻게 통합할 것인지 정의한다. 두 개의 파라미터가 사용되는데, 첫 번째는 바로 이전 값에 대한 통합된 데이터, 두 번째는 새로 통합할 데이터를 의미한다.
간단하게 말하자면 인자들을 차례로 돌면서 연산을 전부 해서 하나의 값을 리턴한다고 생각하면 된다.

//example
let sum : Int = numbers.reduce(0, { (first: Int, second: Int) -> Int in
		print("\(first) + \(second)")
    return first + second
})


//example2
let minus: Int = numbers.reduce(100) { $0 - $1
}

print(sum)
// 0 + 1
// 1 + 2
// 3 + 3
// 6 + 4
// 10 + 5
// return 15

Print(minus)
//85
👉 추가 개념 공부 **Closure 클로저** 함수와 함수가 선언된 어휘적 환경의 조합, 일정 기능을 하는 코드를 하나의 블록으로 모아놓은 것으로 Named Closure 와 Unnamed Closure 두 종류가 있다. 보통 Unnamed Closure(익명함수)를 지칭하는 경우가 많다.
//Name Closure
func doSomething() {
    print("Something")
}

//Unnamed Closure
let closure = { print("Something") }

//Unnamed Closure 표현식
{ (Parameters//(Closure Head)) -> return type in
		실행구문//(Closure Body)

클로저의 단축인자 이름
첫 번째 전달인자부터 $0, $1, $2…를 이용해 생략 가능하고,
키워드 ‘in’도 생략 가능하다(매개변수/반환타입을 실행코드와 구분하기 위해 사용하는 것이기 때문에)

아래는 Reduce 와 클로저 개념을 이해하고 이번 문제에 적용한 풀이.

func solution(_ arr:[Int]) -> Double {
	return Double (arr.reduce(0, { $0 + $1 })) / Double(arr.count)

//
func solution(_ arr:[Int]) -> Double {
	return Double (arr.reduce((통합될데이터의초기값), { $0 + $1 })) / Double(arr.count)

참고 자료

https://ios-developer-storage.tistory.com/entry/Swift-고차함수-map-filter-reduce를-완전-쉽게-알아보자

https://babbab2.tistory.com/81

https://weekoding.tistory.com/4

0개의 댓글