배열에 있는 값이 전부 같은지 확인하는 방법은 뭐 원리는 간단합니다.

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을 하니 역시나 런타임 에러가 발생하게 됩니다.

이 점만 참고해주시면 됩니다

반응형