일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 컴파일
- java알고리즘문제풀이
- java알고리즘
- 항해15기
- 코딩부트캠프후기
- java list 출력
- 프로그래머스제일작은수
- 격파르타장점
- 격파르타후기
- sqld자격증합격
- 노베이스부트캠프
- javaJRE
- java참조자료형
- java list 저장
- java최솟값구하기
- javaJVM
- 격파르타비전공자
- java 자료구조 활용
- 항해99후기
- java기본자료형
- java set 저장
- java set 출력
- 격파르타합격후기
- 비전공자sqld
- 작은수제거하기
- java map 출력
- 프로그래머스
- java map
- 인터프린터언어
- java map 저장
- Today
- Total
코딩과 결혼합니다
230616 - 프로그래머스 알고리즘 문제 풀기 본문
오늘 한 일
새로운 주차로 (항해 99기준) 조가 바뀌었고, 알고리즘 문제를 풀었다.
문제 1) 직사각형 별찍기
알게 된 것 : 이 문제에서는 같은 문자열이 반복이 되는데 .repeat() 메서드를 쓰면 코드를 간단하게 줄일 수 있다.
- String 메서드 중 하나로 String 문자열을 파라미터의 주어진 횟수만큼 반복
- 이번 자바11에서 새로 추가된 String 메서드
for (int i = 0; i < b; i++) {
for (int j = 0; j < a; j++) {
System.out.print("*");
}
System.out.println();
} // repeat를 쓰지 않고 만든 2중 for문
풀이
//별(*) 문자를 이용해 가로의 길이가 n, 세로의 길이가 m인 직사각형 형태를 출력해보세요.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
for(int i=0; i<b; i++) {
System.out.println("*".repeat(a));
}
}
}
Scanner 로 숫자를 입력받아 가로의 길이가 a, 세로의 길이가 b인 직사각형 형태를 출력한다.
ex) a가 7, b가 3일 때

a번 만큼 *을 반복하고 "*".repeat(a) 이 반복한 별을 b번만큼 for문을 돌며 아래에 붙여준다.
문제 2) 짝수와 홀수
알게 된 것 : 팀원 분들께 왜 첫번째로 시도한 코드가 맞지 않는지 물어봤는데 큰 확률로 코드로 계산을 할 때 메모리가 너무 크거나 오래 걸릴 경우에 기준에 맞지 않아 오답이 나올 수 있다고 하셨다.
풀이
//정수 num이 짝수일 경우 "Even"을 반환하고 홀수인 경우 "Odd"를 반환하는 함수, solution을 완성해주세요.
첫 번째 시도
public class q2 {
public static void main(String[] args) {
int num = 4;
String answer = "";
switch ( num%2 ) {
case 0:
answer = "Even";
break;
case 1:
answer = "Odd";
break;
}
System.out.println(answer);
}
}
switch 문을 이용해 보았다.
임의의 숫자 num을 2으로 나누었을때 딱 나누어 떨어져 나머지가 0이면 Even(짝수),
나머지가 1이면 Odd(홀수)로 출력되게 하였다.
하지만 정답을 제출할때 80%의 정답률로 통과하지 못하였다.
두 번째 시도
if (num%2 == 0){
System.out.println("Even");
} else {
System.out.println("Odd");
}
if - else 문을 이용해 보았다.
마찬가지로 num을 2로 나눈 나머지가 0 이면 Even 아니면 Odd가 출력되게 하였다.
이런 방법도 있었다.
String evenOrOdd(int num) {
return (num % 2 == 0) ? "Even" : "Odd";
}
3항 연산자로 깔금하게!
문제 3) 가운데글자 가져오기
알게 된 것 : String substring(int index)
substring은 2가지 방식의 인자값을 받고 있으며 방식은 아래와 같다.
String substring(int startIndex);시작지점
String substring(int startIndex, int endIndex); 시작지점 ~ 종료지점 전까지
풀이
public static void main(String[] args) {
String s = "안녕하세요";
String answer = "";
int sl = s.length();
if (s.length()%2 == 0){
answer = s.substring(sl/2-1, sl/2+1);
System.out.println(answer);
} else {
answer = s.substring(sl/2, sl/2+1);
System.out.println(answer);
}
}
일단 s의 문자열 길이가 짝수인지 홀수인지에 따라 반환하는 글자수가 달라지므로 if-else 문으로 홀수와 짝수를 분리해주준다.
다음 어떻게 하면 s의 가운데 글자를 반환할 수 있을까 고민해보았다.
홀수인 경우는 sl (s.length)을 2로 나누었을때 나오는 몫이 sl 의 정가운데 index번호를 가르키는걸 알 수 있었다.
그 정가운데 번호를 반환하기 위해서 String s를 .substring() 매소드를 이용하여 원하는 부분만 (sl/2 부터 sl/2+1 전까지)
잘라낸다.
짝수인 경우도 위와 같은 원리로 필요한 2부분만 잘라내어 가운데 번호를 반환하였다.
문제 4) 두 정수 사이의 합
풀이
//예를 들어 a = 3, b = 5인 경우, 3 + 4 + 5 = 12이므로 12를 리턴합니다.
public static void main(String[] args) {
int a = -5;
int b = 0;
long answer = 0;
if (a > b) {
for (int i = b; i <= a; i++) {
answer += i;
}
} else {
for (int i = a; i <= b; i++) {
answer += i;
}
}
System.out.println(answer);
}
}
a가 -5, b가 0 일 때 -5 , -4, -3, -2, -1, 0 <- 이렇게 a와 b사이에 속한 모든 정수의 합을 리턴해주어야 한다.
여기서 두 정수 a,b의 대소관계를 정해져 있지 않기 때문에 2가지 경우를 생각해 보아야 한다.
1) a가 b보다 클 경우 2) b가 a보다 클경우
이 예시에서는 2) 번의 경우이므로 int i=a (제일 작은 정수) 부터 b까지 (제일 큰 정수) 1씩커지면서 더하여 answer에 넣는다. 그럼 답이 -15로 맞게 나온다.
문제 5) 문자열을 정수로 바꾸기
알게 된 것 : Integer.parseInt(String타입의 값)
parseInt()의 기능은 String타입의 숫자를 int타입으로 변환해준다.
charAt()은 String타입의 문자열에서 우리가 원하는 단어만 뽑아와서 char타입으로 변환시켜주는 명령어
char ch = str.charAt(1); // 2
char[] chArray = new char[4];
for (int i = 0; i <chArray.length ; i++) {
chArray[i] = str.charAt(i); //[1,2,3,4,5]
}
풀이
//예를들어 str이 "1234"이면 1234를 반환하고, "-1234"이면 -1234를 반환하면 됩니다.
//str은 부호(+,-)와 숫자로만 구성되어 있고, 잘못된 값이 입력되는 경우는 없습니다.
첫 번째 시도 (라 쓰고 삽질이라 읽는다.)
for (int i = 0; i <s.length() ; i++) {
System.out.println(arr[i]);
} //-> 배열에 잘 들어갔음을 확인
//인트형으로
for (int i = 0; i < strArr.length ; i++){
answer [i] = Integer.parseInt(strArr[i]);
System.out.print(answer[i]);
}
String s 를 하나씩 쪼개서 String[] strArr에 넣어주었다.
다음 int형으로 바꾸어 주기 위해 노력해 보았지만 실패했다...
그러다 문득 알아서 숫자형으로 반환해주는 함수가 있지 않을까? 싶어서 구글링 하였다.
두 번째 시도
int answer = 0;
answer = Integer.parseInt(s);
System.out.println(answer);
Integer.parseInt(s) 이라는 녀석을 알게되고 문제는 아주 쉽게 풀렸다고 한다..
문제 6) 없는 숫자 더하기
알게 된 것 : 정적 변수의 쓰임과 .anyMatch 함수 (이건 풀이과정 안에서 다뤄보겠음당)
- 오류 : Cannot resolve symbol 'i'
- java: local variables referenced from a lambda expression must be final or effectively final
풀이
public static void main(String[] args) {
int[] numbers = {1,2,3,4,6,7,8,0};
int answer = 0;
for(i=0; i<=9; i++) {
if (!IntStream.of(numbers).anyMatch(x -> x == i)) {
answer += i;
}
}
System.out.println(answer);
}
}
0부터 9까지의 숫자와 numbers를 비교하려 하였지만 잘 되지 않았다. 처음에는
int[] check = {1,2,3,4,5,6,7,8,9) 를 만들어서 for문으로 하나씩 돌며 .equres() 함수로 numbers와 비교하려 하였지만 두 배열의 크기가 달라 비교가 불가능 하였다.
다시 구글링의 세계로 요소를 비교할 수 있는 함수가 있을까 찾다가 알게된 게
- IntStream.of(numbers): 배열 numbers를 IntStream으로 변환
- .anyMatch(x -> x == i): IntStream의 요소 중에 x라는 변수를 각각 대입하여, 조건 x == i를 만족하는 원소가 있는지 검사한다. anyMatch() 메서드는 최소한 하나의 요소가 조건을 만족하면 true를 반환하고, 그렇지 않으면 false를 반환.
따라서, 해당 코드는 배열 numbers에서 값 i와 같은 원소가 있는지를 검사하고, 결과를 true 또는 false로 반환
그리고 실행을 해봤는데 계속 오류가 떴다.
Cannot resolve symbol 'i' = 기호 'i'를 확인할 수 없습니다.
for 루프에서 변수 i를 선언하지 않아서 생기는 오류였다.
그래서 이번에는 int i = 0; 으로 선언해 주었는데
java: local variables referenced from a lambda expression must be final or effectively final = java: 람다 식에서 참조되는 로컬 변수는 최종 변수이거나 실질적으로 최종 변수여야 합니다. 라는 알 수 없는 말을...
아직은 개념적인 부분이 많이 모자르기 때문에 이 람다 식은 당장 공부하기 보다는 넘어가는게 나을 것같다.
계속해서 의문이 들어서 알아보니 for(i=0; i<=9; i++) 의 i와 (x -> x == i) 의 i는 다른거라고 한다!! 그래서 for문에서 초기 값으로 설정해준 i는 x==i에 영향을 주지 못하였다. 그만 알아보겠다.
해결1(인텔리제이의 수정기능)
int finalI = i;
if (!IntStream.of(numbers).anyMatch(x -> x == finalI)) {
answer += i;
}
}
람다 식이 원하는대로 for문 안에 finalI변수로 선언하여 사용.
해결2(i 변수를 정적변수로 선언 하고 초기화)
public static int i = 0; //정적변수
public static void main(String[] args) {
int[] numbers = {1,2,3,4,6,7,8,0};
int answer = 0;
int i =0;
for(i=0; i<=9; i++) {
if (!IntStream.of(numbers).anyMatch(x -> x == i)) {
answer += i;
}
}
System.out.println(answer);
}
}
정적 변수는 해당 클래스의 모든 인스턴스에 공유되는 변수이다.
이렇게 선언된 변수는 클래스 내 어디서들 접근할 수 있으므로 main 메소드에서 int i =0;를 다시 선언하면 중복 선언 오류가 발생한다.
문제 7) 음양 더하기
풀이
//이 정수들의 부호를 차례대로 담은 불리언 배열 signs가 매개변수로 주어집니다.
//실제 정수들의 합을 구하여 return 하도록 solution 함수를 완성해주세요.
public static void main(String[] args) {
int[] absolutes = {-2,-1,3};
boolean[] signs = {false,false,true}; // ababsolutes 의 요소가 양수면 boolean은 '같은' 인덱스에 true를 아니면 false
int answer = 0;
for (int i = 0; i <absolutes.length ; i++) {
if (signs[i] == true){
answer += absolutes[i];
} else if (signs[i] == false){
answer += absolutes[i]; //프로그래머스는 absolutes의 요소가 절대값을 나오므로 -= 을 해주어야함
}
}
System.out.println(answer);
}
}
* 인텔리제이에서 값이 잘나오는지 보려고 absoulte 와 signs 값을 임의대로 초기화 하였다. 원래는 프로그래머스에서 알아서 값을 대입해줌.
absolutes.length 만큼 for문을 반복하는데 if signs[i]가 true이면 즉, absolutes 가 양수이면 answer에 그 양수 값을 더해주고
if signs[i]가 false이면 즉, absolutes 가 음수이면 answer에 그 음수 값을 더해준다.
프로그래머스에서는 answer -= absolutes[i] 가 맞지만 내가 임의대로 적은 {-2, -1, 3) 은 절대값으로 처리가 되어 있지 않으므로 -= 을 해주면 -(-2) 가 되어 양수가 되어버린다. 그래서 여기서는 += 으로 적었다.
이런 방법도 있었다.
public int solution(int[] absolutes, boolean[] signs) {
int answer = 0;
for (int i = 0; i < absolutes.length; i++) {
answer += (signs[i]) ? absolutes[i] : -absolutes[i];
}
return answer;
}
}
마찬가지로 absolutes.length 만큼 반복문을 도는데
삼항 연산자로 signs[i]가 true이면 absolutes[i]를 더하도록, signs[i]가 flase이면 -absolutes[i]를 더하도록 하였다.좋군
문제 8) 평균 구하기
풀이
public static void main(String[] args) {
int[] arr = {1,2,3,4};
int sum =0;
double answer =0;
for (int i = 0; i <arr.length ; i++) {
sum += arr[i];
answer = (double)sum/arr.length;
}
System.out.println(answer);
}
}
평균은 주어진 값들을 다 더하고 그 값들의 수대로 나누어 주는 것.
먼저 arr의 요소들을 모두 더해주기 위해 int sum을 선언, 0으로 초기화 하고
for문으로 arr.length 만큼 반복하여 sum += arr[i];
다음 평균값은 뒤에 소수점도 같이 나와야 하므로 int sum을 double형으로 변환해주고 arr.length 로 나눠준다.
문제 9) 핸드폰 번호 가리기
알게 된 것 : .repeat와 .substring을 다시 한 번 써보며 기능을 익히게 되었다.
풀이
//전화번호가 문자열 phone_number로 주어졌을 때,
//전화번호의 뒷 4자리를 제외한 나머지 숫자를 전부 *으로 가린 문자열을 리턴하는 함수, solution을 완성해주세요.
public static void main(String[] args) {
String phone_number = "01033334444";
int length = phone_number.length();
String s = phone_number.substring(length-4,length);
String answer = "";
System.out.println("*".repeat(length-4) + s);
}
}
임의로 phone_number를 지정해주었다.
뒤의 4자리수를 빼고는 어떤 길이의 폰 번호든 *로 바꿔줘야 하므로
phone_number의 길이를 담는 변수 length 를 만들고
phone_number를 .substring으로 뒤에서 4번째 ~ 마지막까지의 숫자만 잘라낸다.
다음 .repeat 매소드로 length에서 4를 뺀만큼 "*"을 반복해주고, 뒤에 잘라낸 4자리 숫자를 붙여준다.
그럼 *******4444 의 결과가 나온다.
문제를 푸는 것보다 TIL 쓰는 게 더 힘들다 ^^
'2세 > 기타' 카테고리의 다른 글
230621 - 프로그래머스 제일 작은 수 제거하기/ 오류와 해결과정 (0) | 2023.06.21 |
---|---|
230620 - 알고리즘 문제를 풀며 (0) | 2023.06.20 |
230615 - 자료구조 요리 레시피 메모장 만들기 (2) | 2023.06.15 |
230614 - 대망의 Java 야구 게임 (1) | 2023.06.14 |
230613 (0) | 2023.06.13 |