제출한 코드
#include <iostream>
#include <string>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL);
int n;
string s;
cin >> n;
cin >> s;
int sum = 0;
for(int i=0; i<n; i++){
sum += (s[i] - '0');
}
cout << sum;
return 0;
}
이론 정리
string 의 인덱스 접근
- 배열처럼 접근하기
string str = "TEST";
일 때, str[0] 은 "T" 반환한다. 이때 반환되는 문자는 char형임에 주의하자
char 형 숫자를 int 형으로 변환하는 법
- 숫자의 아스키 값은 48번부터 0~9를 할당하고 있으므로, char형 '1' 은 정수값 49를 가진다
- 따라서 0의 아스키 값인 48을 char 형의 값에서 빼주면 순수한 숫자를 얻어낼 수 있다
char c = '1';
int n = c - 48;
// n = 1
- 위와 같은 코드는 정상적으로 작동은 하지만, 가독성면에서는 좋지 않을 수 있다. 왜냐하면 다른 개발자들이 봤을 때, 48이라는 숫자가 어디서 나온건지 이해가 가지 않을 수도 있기 때문이다
- 아래와 같이 작성을 추천
char c = '1';
int n = c - '0';
// n = 1
다시 말해 0이라는 문자는 숫자 48값을 가진다
내가 제출한 코드
#include <iostream>
#include <string>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL);
int arr[26];
fill_n(arr, 26, -1); // -1 로 초기화
string s;
cin >> s;
for(int i=0; i<s.length(); i++){
int z = s[i] - 'a'; // 자리: a 이면 z 는 0 이다
arr[z] = s.find(s[i]);
}
for (int v : arr) cout << v << " ";
return 0;
}
(내 생각)
- 알파벳 26개를 int 형 배열로 만들어서 모든 원소를 -1 로 초기화 (fill_n 메서드 활용)
- 입력받은 문자 첫번째가 만약 b 라고 가정해보자
- 알파벳 자리는 b - a 를 아스키코드로 변환하면 1 이라는 자리를 찾게 된다
- 배열[자리] = 해당 문자 위치 인덱스
- 해당 문자 위치 인덱스 는 find 함수를 활용해보았다
다른 사람 코드
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
string alphabet = "abcdefghijklmnopqrstuvwxyz";
cin >> s;
for(int i = 0; i < alphabet.length(); i++)
cout << (int)s.find(alphabet[i]) << " ";
return 0;
}
(int) 를 붙이는 이유를 찾아보았다
만약 없는 문자열을 찾으려 할 경우에는 string::npos가 반환된다.
npos의 값은 -1로 정의되어있지만, string::npos의 자료형이 unsigned이므로 2의 보수 개념에 의해 표현할 수 있는 최대 크기의 양수가 출력된다. 이를 방지하기 위해서는 unsigned가 아닌 일반 int형으로 캐스팅을 진행하여 출력하면 된다.
그래서 18446744073709551615 (unsigned형의 -1이므로 표현할 수 있는 최대 크기의 양수) 를 반환한다고 한다 이를 int 형으로 바꾸면 -1 됨
C 와 C++ 의 경우에는 배열 선언은 기본적으로 컴파일 타임에 크기가 결정된다
반대로 가변 길이 배열의 경우에는 int arr[n] 라고 작성하게 되면 컴파일 타임에는 해당 변수에 대한 타입 정보 정도만 갖고 있고 런타임에 n 이 주어지게 되면 그때 되어서야 n의 크기를 읽고 할당을 하게 된다
int main() {
int size;
cin >> size;
int arr[size];
}
int arr[size] 형태를 가르치지 않는 이유는 C++ 표준 문법이 아니다
해당 문법은 C99 의 문법인데, C++의 경우 C의 환경도 포함되어 있다보니 가능해진 것이다 실제 C++ 표준으로만 컴파일을 하게 되면 에러가 나거나, 컴파일러마다 차단된 경우들이 있다
int* arr = new int[size];
위처럼 선언하는 방식이 올바른 방식이다
마지막으로 가장 편리한 방식이 있다
바로 vector 클래스를 사용하는 것이다
vector 의 경우 사이즈를 결정하지 않아도 자유롭게 원소를 추가, 삭제 등을 수행할 수 있는 자료구조 클래스이다
소수점 출력과 관하여..
다음 두 가지 방식으로 출력을 할 수 있다
printf("%.3lf%%", result); // %기호를 출력하려면 %% 를 해야한다.
// or
cout << fixed;
cout.percision(3);
cout << result << "%";
다음은 vector 클래스를 사용하는 방식이다
int N;
cin >> N;
// 동적 배열 선언 및 생성
vector<int> vec;
for(int i = 0; i < N; i++) {
int value;
cin >> value;
vec.push_back(value); // 벡터의 맨 마지막 원소 뒤에 원소 추가
}
사실 vector 클래스를 사용하면 vector 자체가 가변적이라서 N을 넘겨줄 필요가 없다
방법 1)
#include <iostream>
using namespace std;
void func();
int main(int argc, const char *argv[]) {
int C;
cin >> C; // test case
for (int i = 0; i < C; i++) {
func();
}
return 0;
}
void func() {
int N;
cin >> N;
// 동적 배열 선언 및 생성
int *arr = new int[N]; // 혹은 int* arr = (int*)malloc(sizeOf(int) * size)
for (int i = 0; i < N; i++) {
cin >> arr[i]; // i ~ N - 1 까지 입력받은 요소로 초기화
}
// 평균 구하기
double avg = 0;
for (int i = 0; i < N; i++) {
avg += arr[i]; // 모든 성적 누적합
}
avg = avg / N; // 누적합에 대해 N으로 나눈다.
// 평균 점수를 넘는 인원 수 구하기
double count = 0;
for (int i = 0; i < N; i++) {
if (arr[i] > avg) {
count++;
}
}
// 평균을 넘는 인원 %
double result = (count / N) * 100;
cout << fixed;
cout.precision(3);
cout << result << "%\n";
delete[] arr; // 동적 할당을 할 경우에는 더이상 안쓰는 경우 반드시 메모리 해제를 해야한다.
}
delete 써줘야 함
방법 2)
#include <iostream>
#include <vector>
using namespace std;
void func();
int main(int argc, const char *argv[]) {
int C;
cin >> C; // test case
for (int i = 0; i < C; i++) {
func();
}
return 0;
}
void func() {
int N;
cin >> N;
// 동적 배열 선언 및 생성
vector<int> vec;
for (int i = 0; i < N; i++) {
int value;
cin >> value;
vec.push_back(value); // 벡터의 맨 마지막 원소 뒤에 원소 추가
}
// 평균 구하기
double avg = 0;
for (auto &val : vec) {
avg += val; // 모든 성적 누적합
}
avg = avg / N; // 누적합에 대해 N으로 나눈다.
// 평균 점수를 넘는 인원 수 구하기 (for-each)
double count = 0;
for (auto &val : vec) {
if (val > avg) {
count++;
}
}
// 평균을 넘는 인원 %
double result = (count / N) * 100;
cout << fixed;
cout.precision(3);
cout << result << "%\n";
}
배열 선언 및 초기화
1. 일부 값만 초기화된 경우
int arr1[5] = {10, 20, 30};
-> 10, 20, 30, 0, 0
2. brace 만 선언된 경우 : 배열 값은 0으로 초기화됨
int arr2[5] = {}
3. 0으로 초기화하는 방법
-> int a[100];
-> int b[100] = {};
-> int c[100] = {0,};
-> int d[100] = {0};
'🏃♀️ 코테 연습' 카테고리의 다른 글
[C++] 백준 10951번 (0) | 2023.02.10 |
---|---|
[C++] 백준 15552번 (0) | 2023.02.08 |
27. N!의 표현법 (0) | 2021.06.23 |
26. 말아톤 (0) | 2021.06.19 |
스터디 1일차 (0) | 2021.06.17 |