배열에 있는 값이 전부 같은지 확인하는 방법은 뭐 원리는 간단합니다.
0번 원소를 따로 빼서 1,2,3,... n-1번째 원소까지 비교해보고 중간에 다른 게 나오면 false입니다.
#include <bits/stdc++.h>
using namespace std;
bool my_equal(const vector<int>& v) {
const auto& first = v[0];
for (const auto& c : v)
if (first != c)
return false;
return true;
}
int main()
{
vector<int> v1{ 1,1,1,1,1 };
vector<int> v2{ 1,2,3,4,5 };
cout << boolalpha;
cout << my_equal(v1) << '\n'; // true
cout << my_equal(v2) << '\n'; // false
return 0;
}
std::vector
만 쓴 버전입니다.
#include <bits/stdc++.h>
using namespace std;
// parameter 1개 이상 필요
template <typename A0, typename... Args>
constexpr bool my_equal(A0 const& a0, Args const&... args) {
return ((args==a0) && ...);
}
int main()
{
cout << boolalpha;
// cout << my_equal() << '\n'; // compile error
cout << my_equal(1) << '\n'; // true
cout << my_equal(0, 0, 0) << '\n'; // true
cout << my_equal(1, 1, 1, 1, 1) << '\n'; // true
cout << my_equal(1, 2, 3, 4, 5) << '\n'; // ffalse
return 0;
}
variadic parameter를 쓴 함수입니다. fold expression을 썼기 때문에 C++17 이상만 됩니다 (아마도?)
굳이 이렇게 짤 필요는 없죠. 그냥 연습할 겸 짜봤습니다.
이거 올리려고 굳이 글 쓴건 아닙니다. 바로 std::equal
을 쓰는 방법이 있어서 그렇습니다. 매번 이 함수들 구현하기 번거롭잖아요? STL을 적극 활용합시다
다른 방법도 뭐 많지만 이 글에서는 std::equal
만 써보겠습니다.
// 기본형
template< class InputIt1, class InputIt2 >
constexpr bool equal( InputIt1 first1, InputIt1 last1,
InputIt2 first2 );
// 모든 파라미터가 들어있는 버전
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class BinaryPredicate >
bool equal( ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,
BinaryPredicate p );
std::equal
은 <algorithm>
헤더에 들어있습니다.
파라미터 별 정보는 아래와 같습니다.
- first1, last1 : 비교할 첫 번째 element의 범위를 나타냄 [first1, last1)
- first2, last2 : 비교할 두 번째 element의 범위를 나타냄 [first2, last2)
- policy: execution policy 라고 하는데... 레퍼런스를 봐주세요. (잘 모르겠음)
- p: binary predicate.
bool pred(const T1 &a, const T2 &b) 형태를 만족해야 함
first1, last1, first2, last2는 iterator입니다. policy를 사용한다면 Forward Iterator의 조건을 만족해야되고, 아니라면 Input Iterator의 조건을 만족해야 합니다.
여기서 필수적인건 first1, last1, first2입니다. 나머지는 옵션입니다.
구현방식은 심플합니다. first1, first2 iterator를 계속 ++시켜서 해당 element들이 모두 같은지 체크합니다. 중간에 하나라도 다르다면 false를 반환합니다. 당연히 iterator 범위 체크를 잘 해줘야겠죠?
이번 게시물에서는 그냥 std::equal
을 사용해서 배열 하나가 전부 같은 값을 가지는지 확인하는 방법만 써보겠습니다. 이것저것 쓰려다보니 글이 너무 길어졌네요.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v1{ 1, 1, 1, 1, 1 };
vector<int> v2{ 1, 2, 3, 4, 5 };
vector<int> v3{};
cout << boolalpha;
cout << std::equal(v1.begin()+1, v1.end(), v1.begin()) << '\n'; // true
//cout << std::equal(v1.begin(), v1.end(), v1.begin()+1) << '\n'; // run-time error!
cout << std::equal(v2.begin()+1, v2.end(), v2.begin()) << '\n'; // false
// cout << std::equal(v3.begin()+1, v3.end(), v3.begin()) << '\n'; // run-time error!
return 0;
}
iterator를 begin, begin+1에 하나씩 만들어서 비교를 합니다. 즉 인접한 원소끼리 비교를 해나가겠죠?
주의할 점은 2번처럼 first2에 begin()+1을 쓰면 안됩니다. iterator가 end()를 넘어가도 ++first2를 수행하기 때문에 런타임 에러가 납니다.
빈 배열에 사용해도 런타임 에러가 납니다. 빈 배열이면 begin() == end()인데 여기에 +1을 하니 역시나 런타임 에러가 발생하게 됩니다.
이 점만 참고해주시면 됩니다
'프로그래밍 > C++' 카테고리의 다른 글
C++ std::unique_ptr 2차원 배열 만들기 (0) | 2020.07.17 |
---|---|
C++11 implicit narrowing conversion (축소 변환) 방지하는 법 (0) | 2020.06.23 |
intrinsic popcount, clz, ctz (gcc, msvc) (2) | 2020.06.09 |
C++ memset으로 배열 초기화 시 주의점 (0) | 2020.05.22 |
C++ regex syntax_option_type (0) | 2020.05.08 |