문 제
온라인 저지에 가입한 사람들의 나이와 이름이 가입한 순서대로 주어진다. 이때, 회원들을 나이가 증가하는 순으로, 나이가 같으면 먼저 가입한 사람이 앞에 오는 순서로 정렬하는 프로그램을 작성하시오.
입 력
첫째 줄에 온라인 저지 회원의 수 N이 주어진다. (1 ≤ N ≤ 100,000)
둘째 줄부터 N개의 줄에는 각 회원의 나이와 이름이 공백으로 구분되어 주어진다. 나이는 1보다 크거나 같으며, 200보다 작거나 같은 정수이고, 이름은 알파벳 대소문자로 이루어져 있고, 길이가 100보다 작거나 같은 문자열이다. 입력은 가입한 순서로 주어진다.
3
21 Junkyu
21 Dohyun
20 Sunyoung
출 력
첫째 줄부터 총 N개의 줄에 걸쳐 온라인 저지 회원을 나이 순, 나이가 같으면 가입한 순으로 한 줄에 한 명씩 나이와 이름을 공백으로 구분해 출력한다.
20 Sunyoung
21 Junkyu
21 Dohyun
코 드
using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
namespace Algorithm
{
class Member
{
public int Age { get; set; }
public string? Name { get; set; }
public int Order { get; set; }
}
class Program
{
static void Main(string[] args)
{
int N = int.Parse(ReadLine());
List<Member> inputList = new List<Member>();
for (int i = 0; i < N; i++)
{
string[] value = ReadLine().Split(' ');
inputList.Add(new Member
{
Age = int.Parse(value[0]),
Name = value[1],
Order = i
});
}
var sortList = inputList.OrderBy(x => x.Age)
.ThenBy(x => x.Order)
.ToList();
foreach (var member in sortList)
WriteLine($"{member.Age} {member.Name}");
}
}
}
비교코드 - 1
소요시간 216ms, 내 코드보다 20배 감축…
using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.IO;
namespace Algorithm
{
class Member
{
public int Age { get; set; }
public string? Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
int N = int.Parse(ReadLine());
StreamWriter writer = new StreamWriter(OpenStandardOutput());
var inputList = Enumerable.Range(0, N)
.Select(_ =>
{
var values = ReadLine()?.Split(' ');
return new Member
{
Age = int.Parse(values?[0] ?? "0"),
Name = values?[1]
};
})
.ToList();
var sortList = inputList.OrderBy(x => x.Age).ToList();
foreach (var member in sortList)
{
writer.WriteLine($"{member.Age} {member.Name}");
}
writer.Close();
}
}
}
공 부
Enumerable.Range
- 반복 데이터 채우기
소요시간 216ms, 내 코드보다 20배 감축…
// #1 LINQ 사용
int[] arr = Enumerable.Repeat(-1, 10).ToArray();
// #2
int[] arr = new int[10];
Array.Fill(arr, -1);
- 연속 데이터 채우기
소요시간 216ms, 내 코드보다 20배 감축…
// #1 List 활용
List<int> myList = new List<int>(10); // 데이터 크기 10
for (int i = 0; i < myList.Count; i++)
myList[i] = i;
// #2 Enumerable.Range 활용, LINQ 사용
List<int> myList = Enumerable.Range(0, 10).ToList(); // 0부터 10개를 채워라
int[] myArray = Enumerable.Range(0, 10).ToArray(); // 0부터 10개를 채워라
결론 : 단순 값 변경이라면 반복문을, 특정 컬렉션을 새로 생성하면서 값을 채워넣을 때는 Enumerable.Range(,)가 용이!
- OrderBy, ThenBy
- OrderBy(x => x.Score) : Score를 기준으로 오름차순(디폴트)으로 정렬하겠다는 의미! 내림차순으로 정렬을 하고 싶다면 OrderBy 대신 OrderByDescending 사용!
- ThenBy(x => x.Score) : ThenBy도 정렬할 때 사용! OrderBy와 차이가 있다면 OrderBy로 우선 정렬을 하고 차선으로 ThenBy**를 이용하여 정렬한다는 의미!
’?’ null 조건부 연산자
- value가 null이 아니면 인덱스 ‘0’에 있는 요소에 액세스 한다라는 뜻! value 가 null인 경우 표현식은 ‘NullReferenceException’을 발생시키는 대신 ‘null’을 반환한다!
’??’ 널 병합 연산자
- 왼쪽 값이 null인 경우 기본값을 제공한다 라는 뜻! 위 ‘비교코드 - 1’에서 values?[0] 값이 null인지 확인하고 인덱스[0]에서 값을 검색하여 값이 null인 경우 다음 “0”을 사용하겠다 라는 뜻이다!