C#/알고리즘

7. 1181번 단어정렬(수정)

dev_sr 2020. 5. 24. 16:05

Array.Sort two condition 으로 검색하다가 찾은 LINQ로 맞음 

이거랑 ICompere 인터페이스 2개 이상 조건 다는 거랑

LINQ 많이 연습해보기

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
 
namespace _1181_2
{
    
    class Program
    {
        static void Main(string[] args)
        {
            int length = Int32.Parse(Console.ReadLine());
            string[] arr = new string[length];
 
            for(int i=0; i<arr.Length; i++)
            {
                arr[i] = Console.ReadLine();
            }
 
            arr = arr.Distinct().ToArray();
            var result = arr.OrderBy(x => x.Length).ThenBy(x => x);
 
 
           foreach(var data in result)
            {
                Console.WriteLine(data);
            }
            
        }
    }
}
 

 

 

 

Sort a List of Object by multiple fields in C# - Techie Delight

  In this post, we will see how to sort a List of objects against the multiple fields in C#.   1. Using LINQ To create a sorted copy of the list, we can use LINQ’s OrderBy method. To compare objects against subsequent fields, call ThenBy method (or The

www.techiedelight.com

 

----------------------------------------------------------------------------------------------------------------------------------------------

문제 규칙

 

  1. 먼저 입력할 단어 갯수를 입력받고 (20,000개 이내, 50자 제한)
  2. 길이가 짧은 것부터 정렬
  3. 길이가 같으면 사전 순으로 정렬
  4. 중복된 단어는 출력하지 않음

 

ICompareble, IComparer 인터페이스 이용해서 알파벳순-> 길이 순으로 정렬 했는데

값은 제대로 다 나오고 질문 게시판에 반례도 제대로 출력하는데

어디서 틀렸는지 모르겠다..

 

 

<공부한 내용>

1. IComparable 인터페이스 

interface IComparable
{
        int CompareTo(object obj);
}

입력으로 들어오는 obj를 비교해서

자신이 더 크면 양수
같으면 0
자신이 더 작으면 음수 

 

를 반환하여 어떤 값이 더 큰지 알려준다. 
컬렉션의 sort메서드를 사용하기 위해서 꼭 써야함


2. IComparer 인터페이스

interface IComparer 
{
        int CompareTo(object x, object y);
}

입력을 두개를 받아서

x  >  y : 양수
x  =  y :  0
x  <  y : 음수

 

를 반환해준다.
컬렉션의 sort메서드를 사용하기 위해서 꼭 써야함

입력인자가 없으면 내부에서 기본적으로
IComparable을 사용하게 됨

 

 

3. 배열이나 리스트의 중복 없애기

 

array= array.Distinct().ToArray();

list = list.Distinct().ToList();

array = new HashSet<string>(array).ToArray(); -> 정렬된 값이 흐트러질 수도 있다고 함

 

Distinc나 HashSet을 이용하면 중복 제거가 가능하다고 분명히 찾고 검증했는데

int나 string같은 기존 데이터 형식이 아니라

유저가 만든 클래스 타입이면 적용이 잘 안된다고 함

 

여기서는 제대로 적용이 안돼서 정렬된 배열의 word(string)값만

다시 string타입 리스트에 넣고 중복값을 제거함

 

*HashSet

-set 인터페이스를 구현한 HashTable

-입력된 순서대로 저장되지 않고 중복허용이 되지않음.

 

4. list.OrderBy(x => x)

 

리스트나 딕셔너리에 있는 값을 오름 차순으로 정렬함

 

5. list.OrderByDescending(x => x)

 

리스트나 딕셔너리에 있는 값을 내림 차순으로 정렬함

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
 
namespace _1181
{
    class Member : IComparable  //IComparable 를 상속받아야 
                                //이 클래스 안에 멤버값들을 비교 가능
    {
        public string word;
        public int length;
 
        public Member(string word, int length)
        {
            this.word = word;
            this.length = length;
 
        }
 
        public int CompareTo(object obj)    //IComparable는 변수 하나로 기존값과 비교함
        {
            Member member = obj as Member;
 
            //기존 member의 word와 새로들어오는 member의 word를 비교함
            return word.CompareTo(member.word);
 
            
        }
  
    }
    class AddComparer : IComparer
    {
        public int Compare(object x, object y)  //IComparer는 변수 두개를 서로 비교함
        {
            Member memberX = x as Member;
            Member memberY = y as Member;
 
            //member의 length와 다른 member의 length를 비교함
            return memberX.length.CompareTo(memberY.length);
        }
    }
 
 
 
    class Program
    {
        static void Main(string[] args)
        {
            //길이를 입력받아서 
            string inputLength = Console.ReadLine();
            int length = Int32.Parse(inputLength);
 
 
            if (length >= 1 && length <= 20000)
            {
                //조건에 맞으면 그 길이를 갖는 배열을 만듦
                Member[] arrMember = new Member[length];
 
 
                for (int i = 0; i < arrMember.Length; i++)
                {
                    string input = Console.ReadLine();
 
                    if (input.Length < 51)
                    {
                        //길이가 50이하인 문자열만 배열에 넣음
                        Member member = new Member(input,input.Length);
                        arrMember[i] = member;
                     
                    }
                    
                }
 
                //Array.Sort는 IComparer나 IComparable 인터페이스가 있어야 사용이 가능하다.
                //알파벳 순으로 비교하기
                Array.Sort(arrMember);
                //새로 비교하는 IComparer를 만듦
                AddComparer adComparer = new AddComparer();
                //길이 비교하기
                Array.Sort(arrMember,adComparer);
 
                List<string> list = new List<string>();
 
                foreach (var data in arrMember)
                {
                    //기존 배열에서 중복값 제거가 안돼서 string값만 넣는 리스트 만듦..
                    list.Add(data.word);
                }
 
                //string 데이터 형식에서 중복값을 제거하면 잘됨
                list = list.Distinct().ToList();
 
                
                foreach (var data in list)
                {
                    Console.WriteLine(data);
                }
 
            }
        }
    }
}
 

 

밑줄까지 입력값 , 밑줄부터 출력값

 

 

 

1181번: 단어 정렬

첫째 줄에 단어의 개수 N이 주어진다. (1≤N≤20,000) 둘째 줄부터 N개의 줄에 걸쳐 알파벳 소문자로 이루어진 단어가 한 줄에 하나씩 주어진다. 주어지는 문자열의 길이는 50을 넘지 않는다.

www.acmicpc.net

 

IComparer/IComparable인터페이스 참고

 

[C#] 8.2.5 IComparable 인터페이스와 IComparer 인터페이스 – 언제나 휴일

IComarable 인터페이스와 IComparer 인터페이스는 개체의 값 비교를 제공하기 위해 정의되었습니다. C#의 컬렉션은 대부분 Sort 메서드를 제공하는데 IComparable 인터페이스 기반의 요소를 보관하고 있을

ehpub.co.kr

 

 

자료구조 참고

 

C# 기본기 II. 자료 구조의 기본

C# 기본기 II. 자료 구조의 기본 게임을 개발하다 보면, 경험치 테이블, 몬스터 리스트, 퀘스트 리스트, 오브젝트 풀 관리 등 여러 가지 자료의 배열을 만들 일이 생깁니다. 처음으로 개발하게 되��

game-secret.tistory.com

 

 

Set - HashSet 사용하는 방법

- HashSet이란? Set인터페이스를 구현한 hash table입니다. - 특징 (1) 입력된 순서로 저장되지 않습니다. (2) element의 중복을 허용하지 않습니다. (3) null element를 허용합니다. (4) 동기화처리가 되지 않습.

developer-syubrofo.tistory.com

 

'C# > 알고리즘' 카테고리의 다른 글

9. 1302번 베스트셀러 (LINQ group by)  (0) 2020.06.07
8. 1343번 폴리오미노  (0) 2020.06.01
6. 2884번 알람시계  (0) 2020.04.26
5. 14681번 사분면 고르기  (0) 2020.04.26
4. 2753번 윤년  (0) 2020.04.26