C++14에서 생겨난 구분자

 

보통 자리수가 많아지면 보기가 힘들어져서 우리는 , 로 구분한다.

ex) 10,000 원 // 10,000,000원 ....

 

이는 변수에 값을 넣을때도 마찬가지다.

//한눈에 보기 어려움
int a = 100000000;

그래서 작은따옴표로 구분을 할 수 있게 해주었다.

//보다 쉬움
int a = 100'000'000;

//위치는 어느 곳에 넣던지 상관없다.
int b = 1'000'0'000'0;
int c = 1'000000'00;

//모두 같은 값
a = b = c

//소수도 가능하다.
double d = 10'00.324;

 

숫자형 상수를 좀 더 가독성 있게 사용 할 수 있겠다.

 

 

https://mypark.tistory.com/entry/C14-%EC%88%AB%EC%9E%90-%EA%B5%AC%EB%B6%84%EC%9E%90Digit-separators

 

C++14 : 숫자 구분자(Digit separators)

C++14에서 작은따옴표 문자(')는 정수 리터럴과 부동 소수점 리터럴 모두 숫자 리터럴에서 숫자 구분 기호로 임의로 사용할 수 있다. 이것은 코드를 보는 사람들이 큰 숫자를 더 쉽게 알아차릴 수

mypark.tistory.com

'C++ > 유용한 것들' 카테고리의 다른 글

서식문자  (0) 2022.06.06
문자열 다루기  (0) 2022.06.05
Cout에서 소수점 자리 고정하기  (0) 2022.06.04
#include <iostream>
using namespace std;

typedef int integer;

void Merge(integer * arr, integer * temp, int start, int mid, int end)
{
	for (int i = start; i <= end; ++i)
	{
		temp[i] = arr[i];
	}

	int part1 = start;
	int part2 = mid + 1;
	int index = start;

	while (part1 <= mid && part2 <= end)
	{
		if (temp[part1] <= temp[part2])
		{
			arr[index] = temp[part1];
			++part1;
		}
		else
		{
			arr[index] = temp[part2];
			++part2;
		}
		++index;
	}

	for (int i = 0; i <= mid - part1; ++i)
	{
		arr[index + i] = temp[part1 + i];
	}
}


void MergeSort(integer * arr, integer * temp, int start, int end)
{
	if (start < end)
	{
		int mid = (start + end) / 2;
		MergeSort(arr, temp, start, mid);
		MergeSort(arr, temp, mid + 1, end);
		Merge(arr, temp, start, mid, end);
	}
}

void MergeSort(integer * arr, const int & size)
{
	integer * temp = new integer[size];
	MergeSort(arr, temp, 0, size - 1);
}


int main()
{
	int many = 0;
	cin >> many;
	
	integer * num = new integer[1'000'000];
	for (int i = 0; i < many; ++i)
	{
		cin >> num[i];
	}
	MergeSort(num, many);
	for (int i = 0; i < many; ++i)
	{
		cout << num[i] << '\n';
	}
}

퀵정렬로도 풀어지는 문제지만

N^2의 경우를 생각해서 N log N을 보장하는 병합정렬로 풀었다.

 

이번에 숫자 정렬자(digit separator)를 처음 알게됐는데 앞으로 자주 써야겠다. 보기 훨씬 편한듯ㅎㅎ

'코딩 테스트 > 알고리즘 풀이' 카테고리의 다른 글

[백준 - 1080] 행렬  (0) 2022.07.30
[백준 - 1715] 카드 정렬하기  (0) 2022.07.28
[백준 - 10610] 30  (0) 2022.07.27
[백준 - 2217] 로프  (0) 2022.07.23
[백준 - 1541] 잃어버린 괄호  (0) 2022.07.23
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <functional>
using namespace std;
typedef int integer;

int main()
{
	string N;
	cin >> N;

	integer tempInt = 0;
	for (const char & data : N)
	{
		tempInt += data - '0';
	}

	if (tempInt % 3 == 0)
	{
		sort(N.begin(), N.end(), greater<>());
		if (N[N.length() - 1] == '0')
		{
			cout << N;
			return 0;
		}
	}
	cout << "-1";
	return 0;
}

좀 오래 걸렸었는데 그만큼 배우는게 있었다

 


1. 일단 문제 파악을 처음에 잘못했다

들어오는 N이 100,000 이하 라고 처음에 이해를 해버려서 처음엔 Out of range가 났었다.

자리수가 100,000 이하 였던 것.. =_=

굉장히 큰 수이므로 정수로 해결하던 부분을 문자열로 해결하는 방식으로 변경했다.

 


2. 복잡한 방식 채택

 

그 후에는 시간 초과가 났었는데

그 이유는 불필요한 for문을 사용했었다.

30의 배수가 되려면 각 자리의 합이 3의 배수이고 마지막 자리가 0이면 순서가 어떻든지 가능한 조건이였다.

 

근데 나는 내림차순으로 정렬하여 prev_permutation 을 사용하면서 매번 3, 2, 5 로 나눈 값이 0인지 확인하였는데

이부분이 시간 초과의 범인이였다

 


3.  잘못알고 있었던 atoi

입력을 123을 한다면

처음엔 예상 값이 그대로

1

2

3

이 나올줄 알았는데

 

123

23

3

이 나온다..

주소를 받아 integer가 아닌 문자가 나올때까지 읽기때문에 이러한 값이 나왔다..

 

그래서 '0'을 빼주어 integer로 변환 시켜 주었다.


4. 새로 알게 된 사용법

 

생각해보면 string은 char의 집합이고 char또한 정수형이기 때문에 sort함수를 이용할수 있지 않을까 해서

실행해봤는데 잘 됐다

 

그리고 시간초과가 나와서 여러가지 보다가

cout의 endl이 개행문자 출력과 함께 출력버퍼를 비우는 역할을 하기에 시간을 좀 먹는다고 한다.

'\n'을 통해 개행을 해야겠다.

'코딩 테스트 > 알고리즘 풀이' 카테고리의 다른 글

[백준 - 1715] 카드 정렬하기  (0) 2022.07.28
[백준 - 2751] 수 정렬하기2  (0) 2022.07.27
[백준 - 2217] 로프  (0) 2022.07.23
[백준 - 1541] 잃어버린 괄호  (0) 2022.07.23
[HackerRank] Time Conversion  (0) 2022.06.05
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;

int main()
{
	int N;
	cin >> N;

	vector<int> ropeList;
	
	for (int i = 0; i < N; ++i)
	{
		int rope = 0;
		scanf("%d", &rope);
		ropeList.push_back(rope);
	}

	sort(ropeList.begin(), ropeList.end(), greater<>());

	int maxW = 0;
	for (int i = 0; i < ropeList.size(); ++i)
	{
		int temp = ropeList[i] * (i + 1);
		if (maxW <= temp) maxW = temp;
	}
	cout << maxW;
	return 0;
}

분명 맞다고 생각했는데 여러번 틀렸다

틀린 부분은 저 마지막 for문에서 최대값 구하는 부분인데

이전 코드에서는 최대값이 아니면 바로 끝냈기 때문.

 

"5 1 1 1 3 1" 같은 입력값을 예로 들면

먼저 내림차순을 한다. 3 1 1 1 1 (5는 로프 개수 이므로 제외)

3 최대 3

1 최대 2

나는 여기서 멈추었었는데 끝까지 가보면

1 최대 3

1 최대 4

1 최대 5

으로 최대 중량 5를 구할 수 있다.

이러한 끝까지 생각해야하는 문제도 신경써야겠다.!

'코딩 테스트 > 알고리즘 풀이' 카테고리의 다른 글

[백준 - 1715] 카드 정렬하기  (0) 2022.07.28
[백준 - 2751] 수 정렬하기2  (0) 2022.07.27
[백준 - 10610] 30  (0) 2022.07.27
[백준 - 1541] 잃어버린 괄호  (0) 2022.07.23
[HackerRank] Time Conversion  (0) 2022.06.05
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;

void GetNum(const string & str, vector<int> & numList)
{
	string element;
	for (const auto & data : str)
	{
		
		if (data == 43 || data == 45)
		{
			numList.push_back(stoi(element));
			element = data;
		}
		else element += data;
		
	}
	numList.push_back(stoi(element));
}

int main()
{
	string input;
	cin >> input;

	vector<int> numList;
	GetNum(input, numList);
	
	int result = 0;
	bool transSwitch = false;
	for (auto & data : numList)
	{
		if (data < 0) transSwitch = true;
		if (transSwitch == true && 0 < data) data *= -1;
		result += data;
	}

	cout << result;

	return 0;
}

내가 푼 코드는 이러하다.

 

그리디 유형에 속해 있어서 그리디적으로 생각해보려고 했다.

수식 맨 처음부터 읽으면서 당장 '-'가 나온다면 그 후에 나오는 +는 모두 -로 바꾸어 계산하였다

 

input을 하나하나 읽으면서 동시에 result로 계산하는 방법이 더 나았지만

길이제한없는 연속된 정수를 따로 저장해보고 싶어서 저장하는 함수를 따로 구현하였다.

 

근데 다른 사람이 푼 코드가 충격이였다

#include <stdio.h>

int main()
{
  char cmd;
  int n,s,m=0;
  for(scanf("%d",&s);scanf("%c",&cmd),cmd!=10;)
  {
    if(cmd=='-')m=1;
    scanf("%d",&n);
    if(m)s-=n;
    else s+=n;
  }
  printf("%d",s);
  return 0;
}

ㅋㅋㅋㅋ보면서 대단하다고 생각했다

다음에 기회가 된다면 응용해 봐야겠다

'코딩 테스트 > 알고리즘 풀이' 카테고리의 다른 글

[백준 - 1715] 카드 정렬하기  (0) 2022.07.28
[백준 - 2751] 수 정렬하기2  (0) 2022.07.27
[백준 - 10610] 30  (0) 2022.07.27
[백준 - 2217] 로프  (0) 2022.07.23
[HackerRank] Time Conversion  (0) 2022.06.05

서식문자

%hhu			//unsigend char
%hhi,%hhd		//sigend char

%hu				//unsigend short
%hi,%hd			//sigend short

%d				//signed int
%ld				//long Int
%lld			//long long Int
%u				//unsigned int

%f				//float
%lf				//double

%c				//character
%s				//character array (string)

%o				//octal (8진수)
%x				//hexadecimal (16진수 알파벳은 소문자)
%X				//hexadecimal (16진수 알파벳은 대문자)

%				//% (\%로 출력이 되지 않고 %%로 출력이 된다)
\u250C		 //Unicode 250C

Printf

printf("%2d", value); //출력하는 자리수를 지정
printf("%02d", value); //자리수를 설정하고 자리수의 빈칸을 0으로 출력

printf("%.11lf", value); //소수점 이하 11자리까지 출력된다.

Scanf

//사용자 설정 형식을 입력 받는 경우
//Scanf는 지정한 형식에 따라 입력을 받는 함수이기에
//이 형식또한 우리가 설정할수있다, 오직 서식문자만이 아닌 밑처럼 형식을 변형해서 받을 수 있다.
scanf("%d:%d", &h, &m);
/*input*/			/*input*/			/*input*/			/*input*/
//12:243			//12 :243			//12:  243			//12,243

/*output*/			/*output*/			/*output*/			/*output*/
//a = 12, b = 243	//a = 12, b = error//a = 12, b = 243	//a = 12, b = error
//////////////////////////////////////////////////////////////////////
//숫자 한자리만 입력받는 경우
scanf("%1d", &a);
/*input*/
//12344432

/*output*/
//a = 1
//////////////////////////////////////////////////////////////////////
//공백문자를 패스하고 입력받는 경우
scanf(" %d %d", &a, &b);
/*input*/
//       23   123

/*output*/
//a = 23, b = 123

 


 

 

More Input and Output | Introduction to C

More on the standard input and output library

intro2c.sdds.ca

 

'C++ > 유용한 것들' 카테고리의 다른 글

숫자 구분자  (0) 2022.07.27
문자열 다루기  (0) 2022.06.05
Cout에서 소수점 자리 고정하기  (0) 2022.06.04

정말 만만하게 봐서 설계 대충 하다가 정말 오래 걸렸던 문제ㅠ

처음에는 정말 길게도 풀었다.

더보기
#include <bits/stdc++.h>

using namespace std;

void tokenizerTimeformat(vector<string> & time, bool & isAm, string & str)
{   
    string tempStr = str;
    const string delimiter = ":";
    size_t pos = 0;
    
    string tempdegit ="";
    for (int i = 0; i < str.length(); ++i)
    {
        if(isdigit(str[i]) == 0)
        {//is character not degit
            if(tempdegit.length() != 0)
            {
                time.push_back(tempdegit);
                tempdegit = "";
            }
        }
        else 
        {
            tempdegit += str[i];
        }
    }
    
    if (tempStr[8] == 'A') isAm = true;
    if (tempStr[8] == 'P') isAm = false;
}


string timeConversion(string s) 
{
    vector<string> time_s(0);
    vector<int> time_i(0);
    bool isAm = false;
    tokenizerTimeformat(time_s, isAm, s);
    cout<<"isAM : "<<isAm<<endl;

    for(auto data : time_s)
    {
        time_i.push_back(stoi(data));
    }

    if(isAm == false)
    {//isPM
        time_i[0] += 12;
        if (24 <= time_i[0])
        {
            time_i[0] -= 12;
        }
    }
    if(isAm == true)
    {
        if (12 <= time_i[0])
        {
            time_i[0] = 0;
        }
    }
    
    time_s[0] = to_string(time_i[0]);
    if(time_s[0].length() < 2)
    {
        time_s[0] = "0" + time_s[0];
    }
    
    return time_s[0] + ":" + time_s[1] + ":" + time_s[2];
}

int main()
{
    ofstream fout(getenv("OUTPUT_PATH"));

    string s;
    getline(cin, s);

    string result = timeConversion(s);

    fout << result << "\n";

    fout.close();

    return 0;
}

 

그러다가 scanf를 이렇게 사용할수도 있구나를 알게 돼서 적용하여 풀어보니까 정말 쉽게 풀렸다 =~=

규칙 있는 문자열을 입력받아 나눌 때 편하게 사용할 수 있을 것 같다.

#include <bits/stdc++.h>

using namespace std;

int main()
{
   int h, m ,s;
   char c;
   scanf("%d:%d:%d%c",&h ,&m ,&s, &c);
   
   if(c == 'A' && h == 12)
   {
       h = 0;
   }
   if(c == 'P')
   {
       if (h < 12) h += 12;
   }

   printf("%02d:%02d:%02d",h,m,s);
   return 0;
}

'코딩 테스트 > 알고리즘 풀이' 카테고리의 다른 글

[백준 - 1715] 카드 정렬하기  (0) 2022.07.28
[백준 - 2751] 수 정렬하기2  (0) 2022.07.27
[백준 - 10610] 30  (0) 2022.07.27
[백준 - 2217] 로프  (0) 2022.07.23
[백준 - 1541] 잃어버린 괄호  (0) 2022.07.23

개 등신같이 항상 문자열 다룰 때마다 까먹어서 하나씩 추가하면서 정리해야겠다


STRING

  • string to Int
int a = stoi(str);
int b = stoi("3");

 

  • 특정 문자 기준으로 자르기 (string tokenizer)
//////////////////////////////////////////////////////////////////////
//1. 이 방법은 구분기준이 문장이 될수 없고 문자만 가능!
#include <sstream>

string result = "";
stringstream ss("Hi Hello!! My Name");
string token = "";
const char delimiter = '!';

while (getline(ss, token, delimiter))
{
	cout << token << endl;
}

//////////////////////////////////////////////////////////////////////
//2.구분기준이 문장이 가능
string line = "Hi Hello ※※ My ※※ Name";
string delimiter = "※※";
int pos = 0;

//★ pos = line.find(delimiter)는 연산 순서 때문에 무조건 괄호로 감싸줘야한다! ★
while ( (pos = line.find(delimiter)) != string::npos)
{
	cout<<line.substr(0, pos)<<endl;
	line.erase(0, pos + delimiter.length());
}

//substr 처음 인덱스부터 끝 인덱스를 지정해주면 그만큼 문자열에서 가져온다.
//erase 지정 인덱스부터 지정 길이만큼 문자 삭제

 

  • 문자가 숫자인지 아닌지 판별
#include <cctype>

//isdigit(char)의 반환 값이 0이면 문자이고 아니면 숫자임
//문자 하나하나씩 판별해가는방식
string str = "1233BVBBA";

for (int i = 0; i < str.length(); ++i)
{
	if (isdigit(str[i]) == 0) cout << "문자임";
	else cout << "숫자임";
}

 

  • 문자열에서 문자열 검색하기 [ string::find( ) ]
더보기
int main() 
{
	string s, y;
	getline(cin, s); getline(cin, y); 
	
	while (pos != string::npos)
	{
		pos = s.find(y, pos + y.size());
	}
}

내가 가장 많이 쓰는 오버로딩 형식이다.

size_type find ( const string & str, size_type pos = 0 ) const;

 

호출된 문자열 객체의 pos번째 인덱스부터

str찾기 시작하며 찾은 첫 인덱스를 반환한다.

  • 문자열의 일부구간을 반환하기 [ string::substr( ) ]
더보기
#include <string>
using namespace std;

int main()
{
	string str = "ABCDEF";
    str.substr(3); 		//"DEF"
    str.substr(2, 2); 	//"CD"
    str.substr(2, 99); 	//"CDEF"
    str.substr(99, 2); 	// Error std::out_of_range
	return 0;
}

string substr (size_t pos = 0, size_t len = npos) const;

문자열의 pos번째 문자부터  len 길이 만큼의 문자열을 리턴한다.

len이 npos라면 알아서 문자열의 끝까지 적용시켜주고

반면에 pos는 유효한 인덱스가 아니면 에러를 일으키기에 주의할 것


https://plein-de-verite.tistory.com/339

 

[C++] 문자열 파싱하기 (토큰화하기)

Tokenizing a string in C++ string을 Tokenizing한다는 것은 delimiter를 기준으로 string을 split하는 것과 동일한 의미를 갖는다. string을 tokenize하는 여러 가지 방법을 알아보자! stringstream 클래스와 ge..

plein-de-verite.tistory.com

'C++ > 유용한 것들' 카테고리의 다른 글

숫자 구분자  (0) 2022.07.27
서식문자  (0) 2022.06.06
Cout에서 소수점 자리 고정하기  (0) 2022.06.04

+ Recent posts