예전에 틀렸던 부분 그대로 다시 틀렸다 ... 
 
#include <bits/stdc++.h>
using namespace std;

int n; // 기타 개수
string st;
vector<string> v;

int digit_sum(string &a){ // 문자열 중에 숫자만 뽑아서 합을 리턴
  int sum = 0;
  for(auto num : a) {
    if(isdigit(num)) sum += (num - '0');
  }
  return sum;
}

bool check(string &a, string &b){

  int alen = a.size(), blen = b.size(); // 문자열 길이 
  int asum = digit_sum(a), bsum = digit_sum(b); // 숫자합 

  // 길이가 다르면 길이끼리 비교
  if(alen != blen) return alen < blen;
  // 합이 다르면 합끼리 비교
  if(asum != bsum) return asum < bsum;
  // 사전순
  return a < b;
}

int main(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);

  cin >> n;

  while(n--){
    cin >> st;
    v.push_back(st);
  }
  sort(v.begin(), v.end(), check); // 비교함수로 정렬 
  for(auto s : v) cout << s << '\n';

  return 0;
}
 
문제의 정렬 조건은 3가지다. 
 
첫 째, 문자열 길이 →  size() 를 구해 비교
둘 째, 숫자 합 크기 → 문자를 isdigit() 으로 숫자인지 판별. 리턴은 bool
셋 째, 사전순 → a < b 아스키코드 오름차순이라서 간단.
 

아래는 틀린코드다.
bool check(string &a, string &b){

  int alen = a.size(), blen = b.size();

  if(alen < blen) return alen < blen;
  else if(alen == blen){ // 각각 숫자만 뽑아서 합 비교 
    int asum = 0, bsum = 0;
    for(int i = 0; i < alen; i++){ // 길이가 같으니까 인덱스 똑같이 사용 
      if(isdigit(a[i])) asum += (a[i] - '0');
      if(isdigit(b[i])) bsum += (b[i] - '0');
    }
    return asum < bsum;
  }else{ // 사전순
    return a < b;
  }
}
 
틀린 원인
길이 비교라는게, 길이가 달라야 비교하는 것이다. 
아래 처럼 <  로 조건을 넣으니까 틀렸다. 
[X] if(alen < blen) 
[O] if(alen != blen) 
 
숫자 합 비교도 마찬가지다. “달라야"비교한다. 
[X] if(asum < bsum) 
[O] if(asum != bsum) 
 
728x90

'알고리즘 > 백준' 카테고리의 다른 글

좋은 단어 백준 3986번 c++ (두번째 풀기)  (0) 2022.02.11
Hasing 백준 15829번 c++  (0) 2022.02.11
곱셈 백준 1629번 c++  (0) 2022.02.09
큰 수 A+B 백준 10757번 c++  (0) 2022.02.09
피보나치 수 4 백준 10826번 c++  (0) 2022.02.08

문제

시리얼 번호 백준 1431

"맞았습니다."코드

#include <bits/stdc++.h>
using namespace std;

string numberst = "0123456789";
vector<string> v;

bool cmp(string &a, string &b){
  int asize = a.size(), bsize = b.size();
  int asum = 0, bsum = 0;

  if(asize != bsize) return asize < bsize;
  for(int i = 0; i < asize; i++){
    if(numberst.find(a[i]) <= numberst.size()) asum += (a[i] - '0');
  }
  for(int i = 0; i < bsize; i++){
    if(numberst.find(b[i]) <= numberst.size()) bsum += (b[i] - '0');
  }
  if(asum != bsum) return asum < bsum;
  return a < b;
}
int main(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);

  int n;
  string st;
  cin >> n;
  for(int i = 0; i < n; i++){ cin >> st; v.push_back(st);}
  sort(v.begin(), v.end(), cmp);
  for(auto i : v) cout << i << '\n';
  return 0;
}

리뷰

비교함수를 조건대로 구현하는건 어렵지 않게 느껴졌는데.
find 함수를 틀리게 쓰는 것을 모르고.. 시간을 조금 허비했다.

numberst.find(b[i]) <= numberst.size()

이렇게 써야 하는데

[ 틀린 코드 ] numberst.find(b[i]) <= b.size() 

이렇게 b문자열 사이즈와 비교하고 있어서 틀린거였다.

숫자 문자열 numberst 를 만들어 놨다.
문자열을 순회하면서 이 문자가 numberst의 어디 인덱스에 속하냐를 묻는건데.

..... 앞으로 조심하자.

string 의 find() 함수 c++ reference
첫 번째로 매칭되는 문자의 인덱스를 리턴해준다.

find() 함수
범위 안에 원하는 값을 찾는 함수.

int myints[] = {10, 20, 30, 40};
int* p;

p = std::find(myints, myints + 4, 30);
if (p != myints + 4)
    std::cout << "Element found in myints: " << *p << '\n';
else
    std::cout << "Element not found in myints\n";

find() 모두의 코드 레퍼런스

728x90

'알고리즘 > 백준' 카테고리의 다른 글

구간 합 구하기4 백준 11659 c++  (0) 2021.12.23
1,2,3 더하기 백준 9095번 c++  (0) 2021.12.22
국영수 백준 10825 c++  (0) 2021.12.21
접미사 배열 백준 11656 c++  (0) 2021.12.20
1로 만들기 백준 1463번 c++  (0) 2021.12.20

+ Recent posts