-
[Java] 프로그래머스로 다시 공부하는 자바일기 (프로그래머스 레벨1)프로그래밍 언어/Java 2021. 10. 4. 16:30
* 리액트 해보겠다고 JS 랑 JSX 를 주구장창 사용하다보니 헷갈리는 자바문법을 개인적으로 다시 정리하기 위한 글입니다.
* 네이버코테는 구글링이나 IDLE 금지라던데.... 헝헝엏엏ㅇㄹㄱ.
* 다 포기하고 C++이나 파이썬으로 코테를 보고싶지만.... 현업을 위한 자바숙련도 기르기 가즈아ㅏㅏㅏㅏㅏㅏㅏ
# x만큼 간격이 있는 n개의 숫자
1. 가변배열 선언
- new 자료형[갯수]
2. 형변환
- 작은 타입의 데이터를 큰 타입의 변수에 할당할때는 자동변환된다
ex) int a = 5;
long b= a;
- 다른 타입간의 연산은 큰 타입으로 변환된 후 연산된다.
ex) int a=5, i=0;
(long)a*(i+1) <= (i+1)이 long으로 변환되어 연산
class Solution { public long[] solution(int x, int n) { long[] answer=new long[n]; for(int i=0; i<n; i++){ answer[i] = (long)x*(i+1); } return answer; } }
# 하샤드 수
1. 형변환
- Integer.toString(target) : int -> str
- Integer.parseInt(target) : str -> int
2. Wrapper 클래스의 length
- 멤버변수 length가 아닌 메소드 length() 호출 (귀찮게.......!!!!!!!)
3. String 클래스는 배열처럼 사용 불가능
- C++, 파이썬은 됨 ㅎ ... 혼돈
- 따라서 for_each 사용불가능, [] 연산자 사용불가능
- 사용가능하게 JAVA 8 부터 IntStream 두..등장!
- 배열처럼 사용하려면 String[] 변수명 = String.valueOf(number).split("") 을 이용하자...
class Solution { public boolean solution(int x) { boolean answer = false; // x : 1<x<10_000 String str_x = Integer.toString(x); int judge=0; for(int i=0; i<str_x.length(); i++){ judge+= str_x.charAt(i)-'0'; } /* This is IntStream */ /* 위의 for 문과 같은 동작이나, 수행시간이 길다는 평이 있다. Integer.toString(x).chars().forEach(ch -> judge += ch - '0'); */ if(x%judge == 0) answer=true; return answer; } }
# 콜라츠 추측
1. 큰수의 연산은 int에 담을시 overflow 발생하여 데이터보존이 되지 않으므로 long에 담자..!
(프로그래머스에서 해당함수의 매개변수를 int 형으로 지정했으나 long 형으로 바꾸었다.)
- 오류가 뜨지않고 테스트통과가 된 이유? 자동 형변환!! (큰타입에 작은타입담기)
class Solution { public int solution(long num) { int answer = 0; while(num != 1){ if(num%2 == 0) num/=2; else num=num*3+1; answer++; } if(answer >=500) return -1; return answer; } }
# 핸드폰 번호 가리기
1. 하샤드 수에서 메모한 split을 이용한 String 클래스의 배열화
2. String -> char[] 변환 (from 모범답안)
3. String.valueOf(int, char) 의 사용법 (from 모범답안)
class Solution { public String solution(String phone_number) { String answer = ""; String[] temp = phone_number.split(""); int len=temp.length; for(String ch : temp){ if(len<=4) answer+=ch; else answer+="*"; len--; } return answer; } } /* 아래는 프로그래머스 유저의 모범답안*/ class Solution { public String solution(String phone_number) { char[] ch = phone_number.toCharArray(); for(int i = 0; i < ch.length - 4; i ++){ ch[i] = '*'; } return String.valueOf(ch); } }
# 최대공약수와 최소공배수
1. 정수론(유클리드 호제법) : https://dimenchoi.tistory.com/46
- 해당 정의대로 함수짜면 됨
class Solution { public static int gcd(int a, int b){ int remain=a%b; int neck=a/b; if(remain == 0) return b; return gcd(b,remain); } public int[] solution(int n, int m) { int[] answer = new int[2]; if(n<m){ // n should be larger int temp; temp=m; m=n; n=temp; } answer[0] = gcd(n,m); answer[1] = answer[0]*(n/answer[0])*(m/answer[0]); return answer; } }
# 제일 작은 수 제거하기
1. deepcopy
- https://developer-ping9.tistory.com/159
2. 배열생성하며 리턴
- return new int[]{-1,-2,-3}
import java.util.*; class Solution{ public static int[] solution(int[] arr) { int[] answer = new int[arr.length-1]; int[] default_answer = {-1}; if(arr.length == 1) return default_answer; int[] temp = arr.clone(); Arrays.sort(temp); int cnt=0; for(int item : arr){ if (item == temp[0]) continue; answer[cnt] = item; cnt++; } return answer; } } /* primitive -> object */ class Solution{ public int[] solution(int[] arr) { int[] answer = new int[arr.length-1]; if(arr.length == 1) return new int[]{-1}; List<Integer> list = new ArrayList<>(); for(int item : arr) list.add(item); Arrays.sort(arr); list.remove(new Integer(arr[0])); int cnt=0; for(Integer item : list) { answer[cnt]= item; cnt++; } return answer; } }
# 크레인 인형뽑기
1. list.remove(arg);
- arg 가 primitive int 이면 해당 index를 제거
- arg 가 object(Wrapper 클래스 Integer 포함) 이면 Object 를 제거
import java.util.*; class Solution { public int solution(int[][] board, int[] moves) { int answer = 0; List<Integer> list = new ArrayList<>(); for(int move : moves){ //move-1 needed for(int i=0; i<board.length; i++){ int doll = board[i][move-1]; if(doll>0){ board[i][move-1]=0; if(list.size() == 0) { list.add(doll); break; } if(list.get(list.size()-1) == doll){ answer+=2; list.remove(list.size()-1); break; } list.add(doll); break; } } } return answer; } }
# 로또 최고 순위와 최저 순위
1. Set
* Set은 인터페이스, HashSet은 자식클래스 (add, remove(idx or Obj), contains(Obj))
* List는 인터페이스, ArrayList는 자식클래스 (add, remove(idx or Obj), get(idx), contains(Obj))
* Map은 인터페이스, HashMap은 자식클래스 (put, remove, replace, entrySet, keySet, values)
# 메소드 (하위메소드들은 원본객체를 수정하여 만들어짐, 리턴은 boolean)
- retainAll(Set) : 교집합
- addAll(Set) : 합집합
- removeAll(Set) : 차집합
* 나중에 시간나면 원본은 안 건드리고 리턴을 Set으로 해주는 라이브러리나 만들자.
2. Math.min & Math.max
- case가 2개인 경우는 삼항연산자나 if문보다 min,max를 써주면 엄청 Sexy해 보인다... (메모메모)
import java.util.*; class Solution { public int[] solution(int[] lottos, int[] win_nums) { int[] answer = new int[2]; Set<Integer> set1 = new HashSet<>(); Set<Integer> set2 = new HashSet<>(); for(int item : lottos) set1.add(item); for(int item : win_nums) set2.add(item); int zeros=0; if(set1.contains(0)){ zeros = 6-set1.size()+1; } set1.retainAll(set2); //worst-case answer[1] = 7-set1.size(); if(answer[1] == 7 ) answer[1]=6; //best-case answer[0] = 7-set1.size()-zeros; if(answer[0] == 7 ) answer[0]=6; return answer; // mim & max 예시 //int[] answer = {Math.min(7 - max, 6), Math.min(7 - min, 6)}; } }
# 숫자 문자열과 영단어
1. map.entrySet()
- 리턴 자료형은 Set<Map.Entry<T, V>>
2. String 클래스의 replace(oldStr,newStr)
- 원본을 건드리지 않고, 리턴 자료형이 String
3. Entry<T, V>
- getKey()
- getValue()
* .... IDLE 없이 할 수 있을까....
4. String 클래스에 toCharArray() 있음
5. Character 클래스에 isDigit() 있음
import java.util.*; class Solution { public static int solution(String s) { // 0<=len(s)<=50 // s is not start with 0 // changed int s shoud be in 2_000_000_000 int answer = 0; Map<String, String> dict = new HashMap<>(); dict.put("0","zero"); dict.put("1","one"); dict.put("2","two"); dict.put("3","three"); dict.put("4","four"); dict.put("5","five"); dict.put("6","six"); dict.put("7","seven"); dict.put("8","eight"); dict.put("9","nine"); Set<Map.Entry<String,String>> entrySet = dict.entrySet(); for(Map.Entry<String,String> elem : entrySet){ s= s.replace(elem.getValue(),elem.getKey()); } try { answer = Integer.parseInt(s); }catch (Exception e){ System.out.println("Now S is : "+s); } return answer; } }
# 없는 숫자 더하기
1. 되짚고 넘어가기
* Set은 순서가 없는 객체이다
import java.util.*; class Solution { public int solution(int[] numbers) { int answer = 0; Set<Integer> base = new HashSet<>(); for(int i=0; i<10; i++){ base.add(i); } Set<Integer> set = new HashSet<>(); for(int num : numbers){ set.add(num); } base.removeAll(set); for(int item : base){ answer+=item; } return answer; } }
# 가장 큰 수
1. 래퍼클래스.compareTo(래퍼클래스)
- 숫자타입은 앞이 크면 1을 고정적으로 리턴
- 문자열타입은 비교대상끼리 일치하지않는 시점부터 비교
- 뒤의 문자열의 패턴과 다 일치하고, 앞의 문자열의 길이가 남는다면 길이만큼의 양수를 리턴. (반대의경우는 음수)
2. Comparator
- int compare(ob1, ob2) 을 오버라이드
3. 람다함수
- 어차피 compare 만 작성하면 되기에, 람다함수로 작성
4. 정렬함수에 대한 고찰
- 배열내의 원소 두개씩을 비교하면서, return 값이 양수여야 위치를 바꾸도록 설계 되어 있음
-
return 값이 0이나 음수인 경우는 continue 로 설계되어있겠지.(엄청나게 오버로딩 되어있다. 사용자가 요청시 병합정렬, 아니면 Timsort를 진행한다....)
import java.util.*; class Solution { public String solution(int[] numbers) { String answer = ""; // 정렬조건 // 1. 맨앞숫자가장큰것중 길이가 가장짧은것 // 2. 길이가 같다면 숫자가 큰것 String[] hi = new String[numbers.length]; int idx =0; for(int elem : numbers){ hi[idx]= String.valueOf(elem); idx++; } // 아예 합쳐보고 비교하면되는구나.... 한수배워갑니다. Arrays.sort(hi, (a,b)->{ return (b+a).compareTo(a+b); }); answer = hi[0].equals("0") ? "0" : String.join("",hi); return answer; } }
# 숫자의 표현
1. 모범답안들은 이중 for문으로 구성했다.
- 로직은 같다. return 이 break 로 바뀔뿐
class Solution { static boolean visited[]; static int cnt=0; public static void dfs(int start, int target){ if(start>target) return; int sum=0; for(int i=start; i<=target; i++){ //start with 1 sum+=i; if(sum == target){ cnt++; return; } else if(sum>target) return; if(!visited[i]){ visited[i]=true; dfs(start+1,target); } } } public int solution(int n) { int answer = 0; cnt=0; visited = new boolean[n]; dfs(1,n); return cnt; } }
728x90'프로그래밍 언어 > Java' 카테고리의 다른 글
[Java] 프로그래머스로 다시 공부하는 자바일기 (프로그래머스 레벨2) (0) 2021.10.05 [Java] 깊은복사(deepcopy) (0) 2021.10.04 Mac) Homebrew 로 Tomcat 서버 설치, 실행, 경로 (0) 2021.08.19 Mac) 이클립스, 톰캣 연동 (0) 2021.08.19 Java) 비트연산을 사용하는 이유 (0) 2021.08.12