본문 바로가기

코딩

백준 12605 c++

 
 

 

 
 

내가 하던 풀이

#include <iostream>
using namespace std;
int main() {
int n;
string s;
int arr[];
 
 
cin>>n;
for(i=0'i<n;i++)
{
getline(cin,i);
}
}
 

 

 

 

 

 

해설

 
 
 
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int N; cin >> N;
cin.ignore();
for (int i = 1; i <= N; i++) {
string s, temp, ans;
stack<string> st;
getline(cin, s);
for (int k = 0; k < s.length(); k++) {
if (s[k] == ' ') {
st.push(temp);
st.push(" ");
temp.clear();
}
else temp += s[k];
}
st.push(temp);
while (!st.empty()) {
ans += st.top();
st.pop();
}
cout << "Case #" << i << ": " << ans << "\n";
}
}
 
 
#include<stack> 
#include<string> 을 가져온다.

우선 N을 입력받는다.

그리고 for 문을 써서 N회만큼 돌리는 코드를 짜준다.

string 문인 s, temp, ans 를 선언해주고

stack<string> st; 로 스택인 문자열을 st라고 선언하고 가져온다.

 

getline 을 통하여 띄어쓰기까지 가져옴.

 

for문을 통해서 s의 길이만큼 반복함.

보통인 else 의 경우에는 s 배열의 각각단어들을 temp 에 저장.

그러다가 s[k] 가 띄어쓰기를 만나는 순간. temp 의 단어들을 푸쉬하고 그다음 단어위에 띄어쓰기 하나를 올린다.  

그리고 temp 를 비운다. 새로운 단어들을 또 넣을 것 이기 때문이다.

 

이렇게 하면 스택에 단어들이 선입선출식으로 쌓인다.

 

 

 

그렇게 다 쌓은후

while (!st.empty()) {
ans += st.top();
st.pop();
}
 
여기서 ans 라는곳에 st.의 탑 부터 차곡차곡 더하고 st.pop 으로 맨위에것을 뺀다.

그것을 반복하면 역순으로 됨.

 
 

 

 

 

 

 

 

 

 

ios_base::sync_with_stdio(false);의 장점

ios_base::sync_with_stdio 구문은 c의 stdio와 cpp의 iostream을 동기화시켜주는 역할을 하는데, 이 때 iostream과 stdio의 버퍼를 모두 사용하기 때문에 딜레이가 발생합니다.

따라서, ios_base::sync_with_stdio(false); 코드를 작성해줌으로써 동기화를 비활성화시켜줍니다.

이로 인해, c++만의 독립적인 버퍼가 생성되어 c의 버퍼와 병행하여 사용할 수 없게 되지만, 사용하는 버퍼의 수가 줄어들었기 때문에 실행 속도는 빨라지게 됩니다.

알고리즘 문제를 풀 때는 대부분 싱글 쓰레드 환경이기 때문에 해당 코드를 추가해줘도 문제가 발생하지 않을 확률이 높습니다.

 

ios_base::sync_with_stdio(false);의 단점

동기화된 C++ 버퍼의 경우 thread-safe하기 때문에 모든 IO의 순서가 예상한 것과 정확히 일치함을 보장할 수 있습니다.

-> (output from different threads may interleave, but you get no data races).

하지만, ios_base::sync_with_stdio(false); 코드를 추가함으로 인해 동기화가 비활성화됐기 때문에 멀티 쓰레드 환경에서는 출력 순서를 보장할 수 없습니다.

그리고 버퍼가 분리되었기 때문에 cin과 C의 scanf, gets, getchar 등을 같이 사용하면 안되고 cout과 C의 printf, puts, putchar 등을 같이 사용하면 엉뚱한 결과가 나올 확률이 높기 때문에 사용하면 안 됩니다.

 

 

결론

알고리즘을 풀 때는 보통 싱글 쓰레드 환경이기 때문에 ios_base::sync_with_stdio(false); 코드를 추가해줘도 결과에 영향이 없고 C와 C++의 버퍼를 분리하기 때문에 속도가 빨라집니다. (이때, c 스타일의 입출력문을 혼용하지 않도록 주의해줘야 합니다.)

기본적으로 cin으로 읽을 때 먼저 출력 버퍼를 비우는데, 마찬가지로 알고리즘을 풀 때는 화면에 바로 보이는 것이 중요하지 않습니다. 따라서, 입력과 출력을 여러 번 번갈아가며 반복해야 하는 경우 필수적으로 cin.tie(null); 코드를 추가하여 cout과 cin의 묶음을 풀어줘야 합니다.

 

 

 

 

[c++] ios::sync_with_stdio(0), cin.tie(0) 는 왜 쓰는 걸까?

2021. 7. 19. 20:26

ios::sync_with_stdio(0)는 c의 stdio와 cpp의 iostream을 동기화 시켜준다. 문제는 iostream과 stdio의 버퍼를 모두 사용하기 때문에 딜레이가 발생한다. 따라서 이러한 동기화를 비활성화 시켜주기 위해 ios::sync_with_stdio(0)으로 선언해준다.

 

cin.tie(0)는 cin과 cout의 묶음을 풀어준다. 따라서 순서가 사라진다. 알고리즘을 풀때는 화면에 바로 보이는 것이 중요하지 않기 때문에 cin과 cout의 묶음을 풀어주어 더 빠르게 만들 수 있다.

 

 

 

 

 

cin.ignore() 를 하면 버퍼를 클리어한다.

 

 

 

버퍼를 사용하면서 얻을 수 있는 장점은 다음과 같습니다.

 

1. 문자를 하나씩 전달하는 것이 아닌 묶어서 한 번에 전달하므로, 전송 시간이 적게 걸려 성능이 향상됩니다.

2. 사용자가 문자를 잘못 입력했을 경우 수정을 할 수가 있습니다.

 

 

 

 

제공한 코드 세그먼트는 문자열의 각 문자를 분석 s하고 다음 작업을 수행합니다.
루프를 사용하여 문자열의 각 문자를 반복합니다 for (int k = 0; k < s.length(); k++).
루프 내에서 현재 문자가 s[k]공백 인지 확인합니다 ' '. 공백인 경우 단어의 끝을 나타냅니다.
s[k]공백인 경우 다음 단계를 수행합니다.
temp문자열의 내용을 스택에 푸시합니다 st. 문자열 temp에는 지금까지 구성된 현재 단어의 문자가 포함됩니다.
공백 문자를 " "스택에 푸시합니다 st. 이는 스택에서 단어를 분리하기 위해 수행됩니다.
temp새 단어 구성을 시작하기 위해 문자열을 지웁니다 .
가 공백이 아니면 s[k]현재 문자를 문자열 s[k]에 추가합니다 temp. 이것은 문자별로 현재 단어를 빌드하기 위해 수행됩니다.
요약하면 이 코드 세그먼트는 문자열을 개별 단어로 분할하여 처리하고 스택에 푸시합니다. 각 단어는 스택에서 공백으로 구분됩니다.

 

 

 

 

느낀점

 

머리로는 되는데 그거를 코딩화 하기가 힘들다.

생각하는 시간보다는 걍 코드를 많이쳐서 익숙해지게 하는게 우선인것 같다.

 

 

'코딩' 카테고리의 다른 글

백준 11725 c++  (0) 2023.07.09
백준 10828 c++  (0) 2023.07.07
백준 2798 c++  (0) 2023.07.01
백준 9372 c++  (0) 2023.06.30
백준 28173 c++  (0) 2023.06.22