백준 5단계 : 배열단계에 접어들었다. 이번 문제는 입력된 N개의 정수 중 최소값과 최대값을 구해야한다.
코드(내 코드)
using System;
//10818번: 최소 최대
class Program {
/*문제 : N개의 정수가 주어진다. 이때, 최솟값과 최댓값을 구하는 프로그램을 작성하시오.*/
static void Main()
{
//입력 : 첫째 줄에 정수의 개수 N을 입력받는다.
// - N을 입력받고 정수로 바꾼다.
string input = Console.ReadLine();
int n = int.Parse(input);
//입력 : 둘째 줄에 N개의 정수를 공백으로 구분하여 입력받는다.
// - n개의 정수를 공백으로 구분하여 받는다.
string[] input2 = Console.ReadLine().Split(' ');
// - N 크기의 정수형 배열을 생성한다.
int[] numbers = new int[n];
// - n개의 정수를 배열에 집어넣는다.
for (int i = 0; i<n; i++)
{
numbers[i] = int.Parse(input2[i]);
}
//출력 : 정수 N개 중 최솟값과 최댓값을 공백으로 구분하여 출력한다.
// - 최솟값을 넣을 변수를 설정한다.
int minNumber = numbers[numbers.Length - 1];
// - 최댓값을 넣을 변수를 설정한다.
int maxNumber = numbers[numbers.Length - 1];
// - 정수 N개를 비교하여 최솟값과 최댓값을 구하는 식을 짠다.
for (int i = 0; i < numbers.Length; i++)
{
// - 배열의 끝 수를 가져온다.
int endN = numbers[numbers.Length - (i+1)];
// 배열의 끝 수를 최대값 최소값 변수에 넣고 끝 수부터 차례대로 비교한다.
if (maxNumber <= endN)
{
maxNumber = endN;
}
if (minNumber >= endN)
{
minNumber = endN;
}
}
//결과를 출력한다.
Console.WriteLine("{0} {1}", minNumber, maxNumber);
}
}
... 코드가 많이 길다. 코드를 보면 알겠지만 for문이 두 번 쓰였는데, 충분히 겹쳐서 사용할 수 있다. 하지만 입력과 출력을 분리해서 생각하는게 문제 풀기가 편해서 그냥 위처럼 했는데.. 그 결과...
메모리 사용량이 어마어마하다. 그래서 이번 글에선 메모리에 최적화된 코드, 길이가 짧은 코드 코드를 따라 적어보면서 내 코드와 무슨 차이점이 있는지 비교분석해본다. (다른사람이 적은 코드를 가져와 비교)
우선 코드 길이는 200~300B 더 적고, 메모리는 40000KB나 차이가나는 분의 코드를 가져왔고 똑같이 넣어서 제출해봤는데 메모리 사용이나 속도는 똑같다. 그냥 C#버전이나 내부 로직에 따라 다른가보다..
코드비교 (1)
using System;
//10818번: 최소 최대
class Program {
/*문제 : N개의 정수가 주어진다. 이때, 최솟값과 최댓값을 구하는 프로그램을 작성하시오.*/
static void Main()
{
int n = int.Parse(Console.ReadLine());
string inputs = Console.ReadLine();
string[] input = inputs.Split();
int[] nums = Array.ConvertAll(input, int.Parse);
int max = nums[0];
int min = nums[0];
for (int i = 0; i < n; i++)
{
if(nums[i] > max)
{
max = nums[i];
}
if(nums[i] < min)
{
min = nums[i];
}
}
Console.WriteLine(min + " " + max);
}
}
어쨋든 비교를 해보자면 내 코드와 큰 차이점은 두 개가 있다.
1. 정수 N개를 받을 때 Array.ConvertAll()을 이용해서 쉽게 받았다. (본인은 for문을 돌려서 int에 하나씩 집어넣었다)
2. 수를 비교할때 [0]에서부터 올라가면서 비교했다.
1번은 뭐 알아두면 좋을 것 같다. 하지만 문제 푸는 입장으로서 내부 생김새를 가늠도 못하겠는 함수를 사용하기에는 조금 찝찝하기때문에 참고만 하자.
2번은 본받아야겠다. 나는 왜 끝에서부터 비교하려고 했는지ㅜㅜ 괜히 힘들게 끝수부터 비교했다. 다음부턴 앞수부터 차례대로 비교할수있으면 비교해야지..
코드비교 (2)
using System;
class Program
{
private static int[] numbers;
private static void Main()
{
int min = int.MaxValue;
int max = int.MinValue;
numbers = new int[int.Parse(Console.ReadLine())];
string[] args = Console.ReadLine().Split(' ');
for(int i = 0; i < numbers.Length; i++)
{
int arg = int.Parse(args[i]);
if (arg < min) min = arg;
if (max < arg) max = arg;
}
Console.Write(min.ToString() + " " + max.ToString());
}
}
이 코드도 무척 깔끔하다. 난 처음에 min값과 max값을 선언할때 어떤값을 넣어줘야 고민했었다. 처음엔 min, max에 0을 넣어줬었다... 그래서 오류를 맞이했고, 배열의 끝값을 min,max값에 넣어주는걸로 생각을 바꿨다.
위 코드에서는 애초에 선언할때 min값을 int.MaxValue값을 넣어줌으로서 최초 비교시 min값이 항상 최소로 들어갈수있게된다. max값도 마찬가지다. 예외처리를 굳이 할필요가 없는 멋진 변수선언인거같다...
그리고 for문을 돌면서 int배열을 하나씩 채우면서 최소 최대값을 구하고있다. for문을 두 번 돌린 나보단 훨씬 깔끔하다.
개인적으로 생각하기엔 위와같은 코드는 입출력 구분이 안되어있어서 경험이 없으면 생각하기 힘든 코드인거같다. 보통 절차 하나씩 생각해가면서 블록쌓기식으로 문제를 푸는데, 입력과 동시에 비교를 한다는 것은 뭔가 서순이 어긋난 느낌이랄까...
나 같은 경우 "입력받고! 다 입력받은 수를! 비교해야지!" 라고 생각했다면 위 코드는 "수를 입력받으면서! 비교해야지!" 라는 느낌인것같다.
어쨋든 오늘도 여러모로 배워갑니다...
콘솔실행