Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

10-pu2rile #35

Merged
merged 6 commits into from
Jul 22, 2024
Merged

10-pu2rile #35

merged 6 commits into from
Jul 22, 2024

Conversation

pu2rile
Copy link
Collaborator

@pu2rile pu2rile commented Jul 11, 2024

🔗 문제 링크

화학식량

✔️ 소요된 시간

30분

✨ 수도 코드

  1. chemical을 입력받는다
  2. 빈 스택(stack)을 초기화한다
  3. 원자량 딕셔너리(atomic)를 초기화한다
  4. chemical의 문자를 for문을 통해 순회한다
    • 문자 확인
      • '(' 인 경우: 스택에 '(' 추가
      • 'H', 'C', 'O'인 경우: 원자량을 스택에 추가
      • ')'인 경우:
        • 임시 변수(temp) 초기화
        • 스택의 top이 '('가 될 때까지 반복해서 temp에 더하기
        • 스택에서 '(' 제거 후 temp를 스택에 추가
      • 숫자인 경우: 스택의 top 값을 꺼내서 숫자와 곱한 후 스택에 추가
  5. 스택의 모든 값을 합산한다
  6. 합산 결과를 출력한다

순서도

2257 순서도

💻 코드

chemical = input()
stack = []
atomic = {'H':1, 'C':12, 'O':16} # 원자량 딕셔너리

for c in chemical:
  if c =='(': 
    stack.append(c)
  elif c == 'H' or c == 'C' or c == 'O':
    stack.append(atomic[c]) # 입력받은 원자의 원자량을 스택에 추가
  elif c == ')':
    temp = 0 # 닫는 괄호를 만나면 temp 초기화
    while True:
      if stack[-1] == '(': # 스택의 top이 여는 괄호면
        stack.pop() # 스택에서 여는 괄호를 삭제
        stack.append(temp) # 스택에 temp 추가
        break
      else:
        temp += stack.pop() # 여는 괄호 전까지의 스택 안의 모든 값을 temp에 저장
  else: # c가 숫자라면
    stack.append(stack.pop()*int(c)) # 스택의 top 값과 숫자를 곱하여 스택에 추가

print(sum(stack))

📚 새롭게 알게된 내용

여는 괄호 '('를 입력받았을 때 스택에서 삭제하는 걸 생각 못 해서 잠깐 주춤거렸던 문제입니다... ㅎㅎ
파이썬의 딕셔너리를 사용하니 문제가 쉽게 풀렸어요!! 이제 스택은 마스터한 것 같습니다 후후

Copy link
Member

@oesnuj oesnuj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

각 문자별로 처리 방식을 다이어그램으로 표현해주셔서 이해가 정말 쉬웠습니다. 저도 한번 활용해보겠습니다😮

저도 풀어봤는데 괄호 처리부분에서 고민을 좀 했습니다.
도현님이 쓰신 딕셔너리같이 map을 활용하여 원소값을 반환해주는 것도 좋은 방법같네요
저는 그냥 함수를 만들었습니다. 비슷한 로직으로 구현한 것 같아요!

코드
#include <iostream>
#include <vector>
#include <string>
using namespace std;

int calc(char c) {
    if (c == 'H')
        return 1;
    else if (c == 'C')
        return 12;
    else if (c == 'O')
        return 16;
    else 
        return 0;
}

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

    vector <int> s;
    for (const auto& c : str) {
        if (c == 'H' || c == 'O' || c == 'C') {
            s.push_back(calc(c));
        }
        else if (c == '(')
        {
            s.push_back(-1);
        }
        else if (c == ')') {
            int temp = 0;
            while (s.back() != -1) {
                temp += s.back();
                s.pop_back();
            }
            s.pop_back(); //여는 괄호 지워주기
            s.push_back(temp);
        }
        else
        {
            int temp = s.back() * (c - '0');
            s.pop_back();
            s.push_back(temp);
        }
    }
    
    int result = 0;
    while (!s.empty()) {
        result += s.back();
        s.pop_back();
    }
    cout << result;
    return 0;
}

비슷한 느낌으로 조금 더 응용한 문제 후위표기식가 있는데 한번 도전 해보시죠
PR 수고하셨습니다👏

Copy link
Member

@oesnuj oesnuj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고 다이어그램 만들때 뭘 쓰셨는지는 모르겠지만 draw.io라고 있는데, 저는 편해서 종종 사용하고 있어요.
다이어그램 가볍게 만들어야할때 추천드립니다.

draw.io

Comment on lines +10 to +18
elif c == ')':
temp = 0 # 닫는 괄호를 만나면 temp 초기화
while True:
if stack[-1] == '(': # 스택의 top이 여는 괄호면
stack.pop() # 스택에서 여는 괄호를 삭제
stack.append(temp) # 스택에 temp 추가
break
else:
temp += stack.pop() # 여는 괄호 전까지의 스택 안의 모든 값을 temp에 저장
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 break 사용 대신 while문에 탈출조건을 넣어주는 방법도 있습니다.

    temp = 0
    while stack[-1] != '(':
        temp += stack.pop()
    stack.pop() 
    stack.append(temp)

Copy link
Collaborator

@suhyun113 suhyun113 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문제 이름부터 화학식량...? 살짝 무섭군요,,
근데 문제를 읽어보니 먼가 재밌는 문제 같았어요!!
확실히 문자열을 순회해야 할 때 파이썬이 정말 편한 것 같아요! 코드를 보니 깔끔하게 잘하셨는데 순서도를 보니 훨씬 이해가 잘 되었습니다!
순서도는 알고리즘을 풀면서 한 번도 작성해 본 적이 없었는데...작성하면 문제를 이해하는데 도움이 많이 될 것 같네요🙂 준서님께서 추천해주신 사이트로 저도 한 번 작성해봐야 겠습니다ㅎㅎ PR 수고하셨어요~🫡

@pu2rile
Copy link
Collaborator Author

pu2rile commented Jul 22, 2024

그리고 다이어그램 만들때 뭘 쓰셨는지는 모르겠지만 draw.io라고 있는데, 저는 편해서 종종 사용하고 있어요. 다이어그램 가볍게 만들어야할때 추천드립니다.

draw.io

오오 저도 draw.io에서 작성했어요!! 요거 물건이군요??

@pu2rile
Copy link
Collaborator Author

pu2rile commented Jul 22, 2024

문제 이름부터 화학식량...? 살짝 무섭군요,, 근데 문제를 읽어보니 먼가 재밌는 문제 같았어요!! 확실히 문자열을 순회해야 할 때 파이썬이 정말 편한 것 같아요! 코드를 보니 깔끔하게 잘하셨는데 순서도를 보니 훨씬 이해가 잘 되었습니다! 순서도는 알고리즘을 풀면서 한 번도 작성해 본 적이 없었는데...작성하면 문제를 이해하는데 도움이 많이 될 것 같네요🙂 준서님께서 추천해주신 사이트로 저도 한 번 작성해봐야 겠습니다ㅎㅎ PR 수고하셨어요~🫡

저도 순서도를 정석으로 써 본 건 처음이었는데, 아무래도 혼자 문제 풀면서 그렸던 스택보다는 순서도를 작성해서 업로드하는 게 도움이 될 것 같아서 도전해 봤어요 ㅎㅎ 도움이 되셨다면 다행입니다!!!!!

@pu2rile pu2rile merged commit 4979c92 into main Jul 22, 2024
@pu2rile pu2rile deleted the 10-pu2rile branch July 22, 2024 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants