๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“– C๋ž‘ C++

C++ ๋Œ€๋ฌธ์ž/์†Œ๋ฌธ์ž ๋ณ€ํ™˜

๋„ˆ๋ฌด ๋ฐ”๋น ์„œ ๊ธด ํฌ์ŠคํŒ… ๊ธ€์˜ ๋งˆ๋ฌด๋ฆฌ๋ฅผ ๋ชปํ•˜๊ณ  ์žˆ๋‹ค..

์ผ๋‹จ ๊ฐ€๋ฒผ์šด๊ฑฐ๋ผ๋„ ์˜ฌ๋ ค์•ผ ๋“ค ์–ต์šธํ•  ๊ฒƒ ๊ฐ™๋‹ค

 

1. std::transform ์‚ฌ์šฉ

2. std::toupper & std::tolower ์‚ฌ์šฉ

3. boost::to_upper ์™€ to_lower ์‚ฌ์šฉ

 

 


1. std::transform

๊ตฌ๊ธ€์— "C++ ๋Œ€์†Œ๋ฌธ์ž ๋ณ€ํ™˜" ์ด๋ผ๊ณ  ๊ฒ€์ƒ‰ํ•˜๋ฉด 

์•„๋งˆ ๊ฐ€์žฅ ๋จผ์ € ๋ณด์ด๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด์ง€ ์•Š์„๊นŒ ์‹ถ๋‹ค

์‚ฌ์šฉ ๋ฐฉ๋ฒ•์„ ๋ณด๊ธฐ์ „์— cppreference์— ์žˆ๋Š” ํ•จ์ˆ˜ ํ˜•ํƒœ๋ฅผ ๋จผ์ € ๋ณด๊ฒ ๋‹ค

 

* ํ—ค๋”

#include <algorithm>

ํ—ค๋”๋Š” ์š”๋ ‡๊ณ ,,

 

* ํ•จ์ˆ˜ ์›ํ˜•(?)

template< class InputIt, class OutputIt, class UnaryOperation >
OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first,
                    UnaryOperation unary_op );

..? ๋ณต์žกํ•˜๊ฒŒ ์ƒ๊ฒผ์ง€๋งŒ, transform ๋œป ์ž์ฒด๊ฐ€ "๋ณ€ํ™˜"์ด์ง€ ์•Š์€๊ฐ€

Input ์„ ํ•œ ๋ฌด์–ธ๊ฐ€๋ฅผ ์›ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ Output ์œผ๋กœ ๋ฐ”๊พธ๊ฒ ๋‹ค ์š”๋Ÿฐ ๋œป์ด๋ผ๊ณ  ์˜ˆ์ƒ์ด ๋œ๋‹ค

์›ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์šฐ๋ฆฌ๋Š” ๋Œ€/์†Œ๋ฌธ์ž ๋ณ€ํ™˜์ผํ…Œ๊ณ  ใ…‹

 

transform ํ•จ์ˆ˜๋ฅผ ์ข€๋” ์‰ฌ์šด ๋ชจ์–‘์œผ๋กœ ๋ณด์ž๋ฉด,

Output transform(
/*1*/ ์ž…๋ ฅํ•œ ๋ณ€์ˆ˜์˜ first ์œ„์น˜, 
/*2*/ ์ž…๋ ฅํ•œ ๋ณ€์ˆ˜์˜ last ์œ„์น˜๊นŒ์ง€, 
/*3*/ ์ €์žฅํ•  ๋ณ€์ˆ˜์˜ first ์œ„์น˜, 
/*4*/ ๋ณ€ํ™˜ํ•  ๋ฐฉ๋ฒ•์ด ์žˆ๋Š” ํ•จ์ˆ˜
); 

์ด๋ ‡๊ฒŒ ์–˜๊ธฐํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹น

์˜ˆ๋ฅผ ๋“ค์–ด์„œ, "tistory"๋ผ๋Š” ๊ธ€์ž๋ฅผ ๋Œ€๋ฌธ์ž๋กœ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด?

 

#include <algorithm>
#include <string>

using namespace std;
int main(int argc, char **argv)
{
    string str = "Tistory";
    transform(str.begin(), str.end(), str.begin(), ::toupper);
    
    cout << str << endl; /* Return: TISTORY */
    
    return 0;
}

 

cf) std::toupper & std::tolower

transform ํ•จ์ˆ˜ ๋งˆ์ง€๋ง‰ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ std::toupper๋Š” std::transfrom() ์ฒ˜๋Ÿผ std์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค

 

- std::toupper : ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜

- std::tolower : ์†Œ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜

 

์ž‘์„ฑํ•˜๋ ค๊ณ  ๋ณด๋‹ˆ toupper์™€ tolower๋„ ์ถ”๊ฐ€ํ•ด์•ผ๊ฒ ์Œ (์•„๋ž˜ ์ฐธ๊ณ )

 

std::์—์„œ ์ œ๊ณตํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์ƒˆ๋กœ ์ •์˜ํ•œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค

์˜ˆ๋ฅผ ๋“ค์–ด, vector ์•ˆ์— ์žˆ๋Š” ์š”์†Œ์— 1์”ฉ ๋”ํ•˜๋ ค๋ฉด, 1์”ฉ ๋”ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ฒจ์ฃผ๋ฉด ๋œ๋‹ค

 

* ์˜ˆ์‹œ

#include <algorithm>
#include <string>

using namespace std;

int plusFunc(int num)
{
    return num + 1;
}

void printVec(vector<int> vec)
{
    for( int i=0; i < (int)vec.size(); i++)
        cout << i << ": "<< vec[i] << endl;
    return;
}

int main(int argc, char **argv)
{
    vector<int> input {1, 2, 3};
    vector<int> output(3);

    printVec(input); 
    transform(input.begin(), input.end(), output.begin(), plusFunc);
    printVec(output);

    return 0;
}

 

* iterator ์‚ฌ์šฉ

transform()์„ ์กฐ๊ธˆ๋งŒ ๊ตฌ๊ธ€๋งํ•˜๋ฉด ๋‚˜์˜ค๋Š” ์˜ˆ์‹œ๋Š” ๋ณดํ†ต string/vector ์ผ ๊ฒƒ์ด๋‹ค

Iterator๋ฅผ ๊ฐ€์ง€๋Š” input๊ณผ output์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•ด๋‘์ž

 

2. std::toupper & std::tolower ์‚ฌ์šฉ

(1) std::toupper 

 

๋ฌธ๋“ transform()์— toupper()๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค๊ฐ€ ๋“  ์ƒ๊ฐ์ด,

toupper()๋Š” ์ž˜ ๋ชฐ๋ผ์„œ ์—ฅ ๊ทธ๋ƒฅ ๋ฐ”๋กœ toupper๋ฅผ ์“ฐ๋ฉด ๋˜๋Š”๊ฑฐ ์•„๋‹Œ๊ฐ€? ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค

์ด์œ ๋Š” → ํ•œ ๊ธ€์ž๋งŒ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ ใ…‹ ๊ทธ๋ž˜์„œ ๋ฌธ์ž์—ด์„ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด

transform์ด๋ž‘ ์จ์•ผํ•˜๋Š”๊ฑฐ์˜€์Œ ใ…‹ ์•„ ใ…‹

 

* ํ•จ์ˆ˜ ์›ํ˜•

#include <cctype>
int toupper ( int ch ) ;

- parameter: ๋ณดํ†ต unsigned char ํƒ€์ž…์˜ ๋ฌธ์ž์—ด์„ ๋งŽ์ด ์”๋‹ˆ๋‹ค

- return value: ๋Œ€๋ฌธ์ž๋กœ ๋ฐ”๋€ ๊ฒฐ๊ณผ ๊ฐ’

 

* ์˜ˆ์‹œ

using namespace std;
int main(int argc, char **argv)
{
	unsigned char c = 't';
	auto ret = std::toupper(c);
    cout << static_cast<char>(ret) << endl; /* Return: T */
    
    return 0;
}

 

(2) std::tolower

toupper์™€ ๋ฐ˜๋Œ€๋กœ ์†Œ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค

์„ค๋ช…์€ ํŒจ์“ฐํ•˜๊ณ  ํ•จ์ˆ˜ ์›ํ˜•๋งŒ ์˜ˆ์‹œ๋งŒ ๋‹ค๋ฃจ๊ฒ ๋‹ค

 

* ํ•จ์ˆ˜ ์›ํ˜•

#include <cctype>
int tolower( int ch )

* ์˜ˆ์‹œ

using namespace std;
int main(int argc, char **argv)
{
	unsigned char c = 'B';
	auto ret = std::toupper(c);
    cout << static_cast<char>(ret) << endl; /* Return: b */
    
    return 0;
}

 

3. boost::to_upper ์™€ to_lower ์‚ฌ์šฉ (+ boost::to_upper_copy)

boost์—์„œ๋„ std::transform + std::toupper ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค

๋‚˜๋Š” ๋ถ€์ŠคํŠธ๋ฅผ ์ข‹์•„ํ•˜๋‹ˆ๊นŒ,, ์•ž์œผ๋กœ ์ด๊ฑธ ๋งŽ์ด ์“ฐ๋ ค๊ณ  ํ•œ๋‹ค

 

* ํ•จ์ˆ˜ ์›ํ˜•

#include <boost/algorithm/string.hpp>

template<typename WritableRangeT> 
  void to_upper(WritableRangeT & Input, 
                const std::locale & Loc = std::locale());

 

๋‚ด๊ฐ€ boost::to_upper๋ฅผ ์„ ํ˜ธํ•˜๋Š” ์ด์œ ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ๋•Œ๋ฌธ์ด๋‹ค

์˜ˆ์‹œ๋กœ ๋ฐ”๋กœ ์„ค๋ช…ํ•˜์ž๋ฉด,

 

* ใ…‡ใ……

int
main(int argc, char **argv)
{
    string str = "tistory_mutpp";
    string str2 = "tistory_mutpp";
    string str3 = "tistory_mutpp";
    string ret;

    transform(str.begin(), str.end(), str.begin(), (int(*)(int))toupper);
    cout << str << endl; /* Return: TISTORY_MUTPP */

    transform(str2.begin(), str2.end(), str2.begin(), ::toupper);
    cout << str2 << endl; /* Return: TISTORY_MUTPP */

    boost::to_upper(str3);
    cout << str3 << endl; /* Return: TISTORY_MUTPP */
    
    return 0;
}

 

boost::to_upper(๋ฐ”๊ฟ€ ๋ฌธ์ž์—ด);

 

๋ฐ”๊พธ๊ณ  ์‹ถ์€ ๋ฌธ์ž์—ด์„ ๋„ฃ๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๋Š”๊ฑฐ๋‹ค ใ…‹

๊ทผ๋ฐ ๋ฐ”๊ฟ€ ๋ฌธ์ž์—ด์„ ๊ฐ™์€ ๋ณ€์ˆ˜์— ๋ฐ”๊ฟ”์„œ ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›ํ˜•์ด ๋ฐ”๋€๋‹ค

(return type ๋˜ํ•œ void)

 

์นœ์ ˆํ•œ ๋ถ€์ŠคํŠธ์”จ๋Š” ๊ทธ๋ž˜์„œ ๊ฒฐ๊ณผ๋ฅผ ๋ณต์‚ฌํ•ด์„œ ์ฃผ๋Š” ํ•จ์ˆ˜๋„ ์ œ๊ณตํ•ด์ค€๋‹ค → boost::to_upper_copy

 

* boost::to_upper_copy

template<typename OutputIteratorT, typename RangeT> 
  OutputIteratorT 
  to_upper_copy(OutputIteratorT Output, const RangeT & Input, 
                const std::locale & Loc = std::locale());
template<typename SequenceT> 
  SequenceT to_upper_copy(const SequenceT & Input, 
                          const std::locale & Loc = std::locale());
๋ถ€์ŠคํŠธ์”จ: Each element of the input sequence is converted to upper case. The result is a copy of the input converted to upper case. It is returned as a sequence or copied to the output iterator

์˜ˆ์‹œ๋งŒ ๋“ค์–ด์„œ ์„ค๋ช…์„ ๋๋‚ด๊ฒ ๋‹ค

int
main(int argc, char **argv)
{
    string str = "tistory_mutpp";
    
    cout << str << endl; /* Return: tistory_mutpp */
    
    string ret = boost::to_upper_copy(str);
    
    cout << str << endl; /* Return: tistory_mutpp */
    cout << ret << endl; /* Return: TISTORY_MUTPP */
    
    return 0;
}

 


* cppreference

en.cppreference.com/w/cpp/algorithm/transform

 

std::transform - cppreference.com

(1) template< class InputIt, class OutputIt, class UnaryOperation > OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first,                     UnaryOperation unary_op ); (until C++20) template< class InputIt, class OutputIt, class U

en.cppreference.com

* boost 

www.boost.org/doc/libs/1_41_0/doc/html/boost/algorithm/to_upper.html

 

Function template to_upper - 1.41.0

Function template to_upper boost::algorithm::to_upper — Convert to upper case. Synopsis // In header: template void to_upper(WritableRangeT & Input, const std::locale & Loc = std::locale()); Description Each element of the input sequence is converted to

www.boost.org

* boost to_upper_copy

www.boost.org/doc/libs/1_54_0/doc/html/boost/algorithm/to_upper_copy.html

 

Function to_upper_copy - 1.54.0

Function to_upper_copy boost::algorithm::to_upper_copy — Convert to upper case. Synopsis template OutputIteratorT to_upper_copy(OutputIteratorT Output, const RangeT & Input, const std::locale & Loc = std::locale()); template SequenceT to_upper_copy(const

www.boost.org