
[CS50 Practice - #Average Temperatures]
우리는 역사상 가장 더운 날씨로 매년 기록을 깨고 있는 것 같습니다. 기후 과학자들은 가까운 미래의 상황을 더 잘 예측하고 대비할 수 있도록 수년에 걸쳐 "new normals"이라고 불리는 것을 추적합니다. 공식 normals은 30년 단위로 계산되며 연간 단위로 구성됩니다. 연간/계절, 월간, 일별, 시간별 평균과 약 15,000개의 미국 기상 관측소에서 수집한 기온, 강수량 및 기타 기후 변수에 대한 통계로 구성됩니다.
7월은 미국의 대부분의 대도시에서 일년 중 가장 더운 달입니다. 화씨 80도 이상의 주간 기온은 거의 모든 곳에서 정기적으로 발생합니다. 예외는 태평양 연안의 일부 도시입니다.
이 문제에서는 10개 도시의 평균 최고 기온 값을 내림차순으로 정렬합니다.
Hints
main 함수는 temps 배열을 초기화하고, sort_cities 함수를 호출하고 정렬된 순서로 배열을 인쇄합니다. 원하는 O(n2) 정렬 알고리즘(버블 정렬, 선택 정렬 또는 삽입 정렬 등)을 사용하여 배열을 온도별로 내림차순으로 정렬합니다.
어떤 정렬 알고리즘을 선택했으며 그 이유는 무엇입니까?
// Practice working with structs
// Practice applying sorting algorithms
#include <cs50.h>
#include <stdio.h>
#define NUM_CITIES 10
typedef struct
{
string city;
int temp;
}
avg_temp;
avg_temp temps[NUM_CITIES];
void sort_cities(void);
int main(void)
{
temps[0].city = "Austin";
temps[0].temp = 97;
temps[1].city = "Boston";
temps[1].temp = 82;
temps[2].city = "Chicago";
temps[2].temp = 85;
temps[3].city = "Denver";
temps[3].temp = 90;
temps[4].city = "Las Vegas";
temps[4].temp = 105;
temps[5].city = "Los Angeles";
temps[5].temp = 82;
temps[6].city = "Miami";
temps[6].temp = 97;
temps[7].city = "New York";
temps[7].temp = 85;
temps[8].city = "Phoenix";
temps[8].temp = 107;
temps[9].city = "San Francisco";
temps[9].temp = 66;
sort_cities();
printf("\nAverage July Temperatures by City\n\n");
for (int i = 0; i < NUM_CITIES; i++)
{
printf("%s: %i\n", temps[i].city, temps[i].temp);
}
}
// TODO: Sort cities by temperature in descending order
void sort_cities(void)
{
// Add your code here
}
서로 인접한 두 원소를 검사하여 정렬하는 알고리즘
인접한 2개의 레코드를 비교하여 크기가 순서대로 되어 있지 않으면 서로 교환한다.
// TODO: Sort cities by temperature in descending order
void sort_cities(void)
{
// Add your code here
// ● 내림차순 버블정렬
// ● 실행 시간의 상한 O(n^2) | 실행 시간의 하한 Ω(n^2)
// ** 실행 시간의 상한 최대치로 구현;;
// (n-1)*(n-1)
for (int i = 0; i < NUM_CITIES; i++)
{
for ( int j = 0; j < NUM_CITIES; j++ )
{
if (temps[j].temp < temps[j + 1].temp)
{
avg_temp tmp; // 구조체 복사
tmp = temps[j];
temps[j] = temps[j + 1];
temps[j + 1] = tmp;
}
}
}
문제점 : 시간복잡도를 최대로 갖는 방법으로 정렬함
// TODO: Sort cities by temperature in descending order
void sort_cities(void)
{
// Add your code here
// ● 내림차순 버블정렬
// ● 실행 시간의 상한 O(n^2) | 실행 시간의 하한 Ω(n^2)
// ** 실행 시간의 상한을 최소로 하는 방법
// 더 이상의 교환이 없으면 멈춘다.
int counter = 1; // 교환 횟수를 카운터 변수 할당 (0이 아닌 숫자 아무거나)
avg_temp tmp; // 구조체 복사
while (counter != 0) // 조건문이 참이 될 때까지 반복 (counter가 0이면 중단)
{
counter = 0; // 카운터 0으로 초기화
for (int i = 0; i < NUM_CITIES; i++)
{
if (temps[i].temp < temps[i + 1].temp)
{
tmp = temps[i];
temps[i] = temps[i + 1];
temps[i + 1] = tmp;
counter ++;
}
}
}
// TODO: Sort cities by temperature in descending order
void sort_cities(void)
{
// Add your code here
// ● 내림차순 선택정렬
// ● 실행 시간의 상한 O(n^2) | 실행 시간의 하한 Ω(n^2)
int start = 0; // 비교 시작 지점
int counter = 1; // 조건문이 참이 될 때까지 반복 (counter가 0이면 중단)
avg_temp tmp; // 구조체 복사
while (counter != 0) // 조건문이 참이 될 때까지 반복 (counter가 0이면 중단)
{
counter = 0; // counter 초기화
for (int i = start; i < NUM_CITIES; i++)
{
if ( temps[start].temp < temps[i + 1].temp )
{
tmp = temps[start];
temps[start] = temps[i + 1];
temps[i + 1] = tmp;
counter ++; // 교환이 이루어지면 counter + 1
}
}
start ++; // 반복문이 종료된 후 start지점 + 1
//(temps[0] -> temps[1] -> temps[2] -> temps[3] .. -> temps[9])
}
중첩 반복문으로 풀이하는 방법도 있는 듯 하다.
원하는 답이 나오는 데에만 집중하지 말고 더욱 효율적인 코드가 무엇일지 고민하는 습관이 필요하다는 것을 느꼈다.
버블 정렬에서 처음 couter를 넣는 방법으로 접근했었는데 while문이 생각처럼 되지 않아
방법을 이리저리 찾다가 중첩 for문으로 정렬이 되길래 오 됐다! 했는데 그건 정렬만 된거지 시간복잡도를 고려를 안했다는 것을 해외 유튜브 풀이를 보고 알았다.
오히려 couter로 접근하는 법이 더 좋은 방법이었다. 차근차근 고민해도 된다! 좋은 코드 짤 것