본문 바로가기

Java/Java 알고리즘 LeetCode

[LeetCode- Ch.2 정렬 & 검색] 7. 로그 파일의 데이터 재정렬 ## (+ Comparator 오버라이딩)

반응형

https://leetcode.com/problems/reorder-data-in-log-files/submissions/

 

Reorder Data in Log Files - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

1. result 문자열 마지막에 " "공백 지우기

2. 문자 로그 정렬시, 문자 로그가 모두 같으면 개수가 적은 것 오름차순 정렬

 

import java.util.*;
class Solution {
    public String[] reorderLogFiles(String[] logs) {
        //첫 번째 단어는 식별자
        //식별자 제외 모두 숫자로 이루어진 경우
        //식별자 제외 모두 문자로 이루어진 경우

        //숫자 로그보다 문자로그가 앞에 온다.
        //문자로그는 오름차순
        //문자로그가 같을 경우 식별자 기준 정렬
        //숫자로그도 오름차순
        int n=logs.length;
        ArrayList<String[]> letter=new ArrayList<>();
        ArrayList<String []> digit=new ArrayList<>();

        for(int i=0;i<n;i++){
            String[] tmp=logs[i].split(" ");
            if(!Character.isDigit(tmp[1].charAt(0))) letter.add(tmp);
            else digit.add(tmp);
        }
        
        letter.sort(new Comparator<String[]>() {
            @Override
            public int compare(String[] o1, String[] o2) {
                for (int i = 1, j = 1; i < o1.length; i++, j++) {
                    if (o1[i].equals(o2[j])) continue;
                    return o1[i].compareTo(o2[j]);
                }
                //문자열이 다 같지만 문자의 개수가 다르면 개수가 적은 것 오름차순
                if(o1.length<o2.length) return o1.length-o2.length;
                
                return o1[0].compareTo(o2[0]);
            }
        });
   
        ArrayList<String> answer=new ArrayList<>();
        
        for(String[] tmp : letter){
            String result="";
            for(String x : tmp) {
                result+=x+" ";
            }
            result=result.substring(0, result.length()-1);
            answer.add(result);
        }
        System.out.println();
        for(String[] tmp : digit){
            String result="";
            for(String x : tmp) {
                result+=x+" ";
            }
            result=result.substring(0, result.length()-1);
            answer.add(result);
        }
        
        String[] arr = new String[answer.size()];
        for(int i=0;i<arr.length;i++){
            arr[i]=answer.get(i);
        }
        

        return arr;
    }
}

+) 세련된 코드

케이스 분류

1. 모두 문자 - 사전순서대로 (오름차순)

2. 모두 숫자 - 순서 유지

3. 첫번째는 숫자, 두번째는 문자 - 숫자가 문자보다 뒤로

4. 첫번째는 문자, 두번째는 숫자 - 문자가 숫자보다 앞으로


람다식을 이용한 Comparator 오버라이딩

Arrays.sort(logs, (s1, s2) ->{
//정렬시 사용할 변수 설정
//s1을 문자열 배열로, s2를 문자열 배열로
//s1의 숫자유무 판단, s2의 숫자유무 판단

//문자열 배열 2개과 숫자 유무 boolean 2개
//문자열 배열의 경우 문자와 숫자를 split(" ",2);로 공백 기준 2개로 분리
String[] split1, boolean isDigit1
String[] split2, boolean isDigit2

//1.문자열 배열 모두 숫자가 아닐 경우
//(1) 모두 문자일 경우 -> 같을 경우 / 다를 경우
//2. 문자열 배열 중 하나 이상 숫자일 경우
//(1) 모두 숫자일 경우
//: 0리턴 순서대로
//(2) 첫 번째가 숫자, 두 번째가 문자
//: 1리턴 오름차순
//(3) 첫 번째가 문자, 두 번째가 숫자
//: -1 리턴 내림차순
}

 

import java.util.*;
class Solution {
    public String[] reorderLogFiles(String[] logs) {
		Arrays.sort(logs, (s1, s2) -> {
            //정렬시 사용할 변수 설정
            //문자열 배열2개와 숫자 유무 boolean 2개
			String[] split1 = s1.split(" ", 2);
			String[] split2 = s2.split(" ", 2);

			boolean isDigit1 = Character.isDigit(split1[1].charAt(0));
			boolean isDigit2 = Character.isDigit(split2[1].charAt(0));
			//System.out.println("split1[1].charAt(0):" + split1[1].charAt(0));
			//System.out.println("split2[1].charAt(0):" + split2[1].charAt(0));
            
            //1.문자열 배열 모두 숫자가 아닐 경우
            //(1) 모두 문자일 경우 -> 같을 경우 / 다를 경우
            //2. 문자열 배열 중 하나 이상 숫자일 경우
            //(1) 모두 숫자일 경우
            //: 0리턴 순서대로
            //(2) 첫 번째가 숫자, 두 번째가 문자
            //: 1리턴 오름차순
            //(3) 첫 번째가 문자, 두 번째가 숫자
            //: -1 리턴 내림차순
            
			if (!isDigit1 && !isDigit2) {
				// 1. 모두 문자
				int comp = split1[1].compareTo(split2[1]);
				if (comp == 0)
					return split1[0].compareTo(split2[0]);
				else
					return comp;
			} else if (isDigit1 && isDigit2) {
				// 2. 모두 숫자
				return 0;
			} else if (isDigit1 && !isDigit2) {
				// 3. 첫번째는 숫자, 두번째는 문자
				return 1;
			} else {
				// 4. 첫번째는 문자, 두번째는 숫자.
				return -1;
			}
		});
		return logs;
	}
}

class Solution {
    public String[] reorderLogFiles(String[] logs) {
        Arrays.sort(logs, (s1, s2)-> {
            //1. 문자열부분과 숫자가능 부분 분리
            String[] split1= s1.split(" ", 2);
            String[] split2= s2.split(" ", 2);
            //숫자가능 부분이 숫자인지 판단
            boolean isdigit1 = Character.isDigit(split1[1].charAt(0));
            boolean isdigit2 = Character.isDigit(split2[1].charAt(0));
            
            //2. 케이스 분류
            if(!isdigit1 && !isdigit2){
                //둘 다 문자
                //뒷 부분이 같을 때와 다를 때로 구분
                int comp=split1[1].compareTo(split2[1]);
                if(comp==0){
                    //같으면 앞부분을 비교
                    return split1[0].compareTo(split2[0]);
                }else return comp;
                //같지 않으면 사전 순서대로 (오름차순)
            }else{
                //1. 둘 다 숫자
                if(isdigit1 && isdigit2)
                return 0;
                //기존 순서대로
                
                //2. 앞이 숫자
                else if(isdigit1&& !isdigit2)
                return 1;
                //문자가 먼저 ->기존객체가 크다, 내림차순 : 순서 교체
                
                //2. 뒤가 숫자
                else
                return -1;
                //문자가 먼저 ->파라미터가 크다, 오름차순 : 순서 그대로
            }
        });
        return logs;
    }
}
반응형