반응형

👩회원 서비스

package inflearn.spring.service;

import inflearn.spring.domain.Member;
import inflearn.spring.repository.MemeberRepository;

import java.util.List;
import java.util.Optional;

public class MemberService {

    private final MemeberRepository memeberRepository;

    public MemberService(MemeberRepository memeberRepository) {
        this.memeberRepository = memeberRepository;
    }

    /* 회원 가입 */
    public Long join(Member member){
        validateDuplicateMember(member);    //중복 회원 검증
        memeberRepository.save(member);
        return  member.getId();
    }

    private void validateDuplicateMember(Member member) {
        memeberRepository.findByName(member.getName())
                .ifPresent(m -> {
                    throw new IllegalStateException("이미 존재하는 회원입니다.");
                });
    }

    /* 전체 회원 조회 */
    public List<Member> findMember(){
        return memeberRepository.findAll();
    }

    /* 회원 조회 */
    public Optional<Member> findOne(Long memberId){
        return memeberRepository.findById(memberId);
    }
}

 

🎈🎈중복검증

0. 기존

Optional<Member> result = memeberRepository.findByName(member.getName());
  
result.ifPresent(m -> {
   throw new IllegalStateException("이미 존재하는 회원입니다.");
});

1. 변수 없이 바로 스트림으로 코드 수정

memeberRepository.findByName(member.getName())
                .ifPresent(m -> {
                    throw new IllegalStateException("이미 존재하는 회원입니다.");
                });

2. 메서드 추출 (Ctrl + Alt + M)

	public Long join(Member member){
        validateDuplicateMember(member);    //중복 회원 검증
        memeberRepository.save(member);
        return  member.getId();
    }

    private void validateDuplicateMember(Member member) {
        memeberRepository.findByName(member.getName())
                .ifPresent(m -> {
                    throw new IllegalStateException("이미 존재하는 회원입니다.");
                });
    }

 

🎈🎈Service와 memeberRepository 메소드 명명

  • Service : 비지니스 로직과 같은 메소드 이름 ex) Join
  • memeberRepository : 기계적으로 ex) save

👩테스트케이스

테스트는 직관적으로 알아볼 수 있도록 한글로도 적어도 된다.

 

🎈🎈중복 회원 예외

  • try ~ catch문
    @Test
    public void 중복_회원_예외(){
        //given
        Member member1 = new Member();
        member1.setName("spring");

        Member member2 = new Member();
        member2.setName("spring");

        //when
        try {
            memberService.join(member2);
            fail();
        } catch (IllegalStateException e){
            assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
        }

        //then
    }

 

  • assertThrows() : memberService.join(member2)를 실행시켰을 때 IllegalStateException 예외가 발생하는지 확인getMessage()로 에러 메시지 확인도 가능
    @Test
    public void 중복_회원_예외(){
        //given
        Member member1 = new Member();
        member1.setName("spring");

        Member member2 = new Member();
        member2.setName("spring");

        //when
        memberService.join(member1);
        IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
        assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");

        //then
    }

 

🎈🎈DI

 

- 기존에는 회원 서비스가 메모리 회원 리포지토리를 직접 생성

public class MemberService {
     private final MemberRepository memberRepository = new MemoryMemberRepository();
}

 

- 회원 리포지토리의 코드가 회원 서비스 코드를 DI 가능하게 변경

> 같은 리포지토리로 테스트를 해야하는데 각각 객체 생성하므로 다음과 같이 수정 필요

public class MemberService {
     private final MemberRepository memberRepository;
     
     public MemberService(MemberRepository memberRepository) {
     	this.memberRepository = memberRepository;
     }
     //...
}

@BeforeEach : 각 테스트 실행 전에 호출. 테스트가 서로 영향이 없도록 항상 새로운 객체를 생성하고, 의존관계도 새로 맺어준다.

class MemberServiceTest {

    MemberService memberService;
    MemoryMemberRepository memberRepository;

    //DI
    @BeforeEach
    public void beforeEach(){
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }
    //...
}

 

🎈🎈 인텔리제이 꿀팁 : Shift + F10 이전 실행

 

 

출처 : 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

반응형
반응형

👩회원 객체

package hello.hellospring.domain;
public class Member {

     private Long id;
     private String name;
     
     public Long getId() {
     	return id;
     }
     public void setId(Long id) {
     	this.id = id;
     }
     public String getName() {
     	return name;
     }
     public void setName(String name) {
     	this.name = name;
     }
}

👩회원 리포지토리 인터페이스

package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import java.util.List;
import java.util.Optional;

public interface MemberRepository {
         Member save(Member member);
         Optional<Member> findById(Long id);
         Optional<Member> findByName(String name);
         List<Member> findAll();
}

 

👩회원 리포지토리 메모리 구현체

 

package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import java.util.*;
/**
 * 동시성 문제가 고려되어 있지 않음, 실무에서는 ConcurrentHashMap, AtomicLong 사용 고려
 */
public class MemoryMemberRepository implements MemberRepository {
     private static Map<Long, Member> store = new HashMap<>();
     private static long sequence = 0L;
 
 	 @Override
 	 public Member save(Member member) {
         member.setId(++sequence);
         store.put(member.getId(), member);
         return member;
     }
     
     @Override
     public Optional<Member> findById(Long id) {
     	return Optional.ofNullable(store.get(id));
     }
     
     @Override
     public List<Member> findAll() {
     	return new ArrayList<>(store.values());
     }
     
     @Override
     public Optional<Member> findByName(String name) {
         return store.values().stream()
         			.filter(member -> member.getName().equals(name))
         			.findAny();
     }
     
     public void clearStore() {
     	store.clear();
     }
}

 

🎈🎈동시성 문제 : ConcurrentHashMap, AtomicLong

 

🎈🎈Optional<T>

: null이 올 수 있는 값을 감싸는 Wrapper 클래스.  NPE(NullPointerException)가 발생하지 않도록 도와준다.

 

🎈🎈stream() 

: 스트림(Streams)은 람다를 활용할 수 있는 기술 중 하나.

 

-배열 또는 컬렉션 인스턴스에 하나 이상의 함수로 데이터를 필터링 및 가공

-람다식 활용 > 간결성

-함수형으로 처리

 

- Filter

- findFirst() vs findAny()

 

1. Stream을 직렬로 처리할 때 차이점 X

2. Stream을 병렬(parallel())로 처리할 때

findFirst() : 여러 요소가 조건에 부합해도 Stream의 가장 앞에 있는 요소를 리턴

findAny() : Multi thread에서 Stream을 처리할 때 가장 먼저 찾은 요소를 리턴

 @Override
 public Optional<Member> findByName(String name) {
     return store.values().stream()
                .filter(member -> member.getName().equals(name))
                .findAny();
 }

이 입문 코드에도 배울게 참 많다..!


🧛‍♂️회원 리포지토리 테스트 케이스 작성

package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Optional;
import static org.assertj.core.api.Assertions.*;

class MemoryMemberRepositoryTest {
     MemoryMemberRepository repository = new MemoryMemberRepository();
     
     @AfterEach
     public void afterEach() {
     	repository.clearStore();
     }
     
     @Test
     public void save() {
         //given
         Member member = new Member();
         member.setName("spring");
         //when
         repository.save(member);
         //then
         Member result = repository.findById(member.getId()).get();
         assertThat(result).isEqualTo(member);
     }
     
     @Test
     public void findByName() {
         //given
         Member member1 = new Member();
         member1.setName("spring1");
         repository.save(member1);
         Member member2 = new Member();
         member2.setName("spring2");
         repository.save(member2);
         //when
         Member result = repository.findByName("spring1").get();
         //then
         assertThat(result).isEqualTo(member1);
     }
     
     @Test
     public void findAll() {
         //given
         Member member1 = new Member();
         member1.setName("spring1");
         repository.save(member1);
         Member member2 = new Member();
         member2.setName("spring2");
         repository.save(member2);
         //when
         List<Member> result = repository.findAll();
         //then
         assertThat(result.size()).isEqualTo(2);
     }
}

🎈🎈인텔리제이 꿀팁 shift+f6 이름 한번에 바꾸기

 

🎈🎈@AfterEach : 각 테스트가 종료될 때 마다 이 기능을 실행한다. 여기서는 메모리 DB에 저장된 데이터를 삭제한다. 

 

테스트는 각각 독립적으로 실행되어야 한다. 테스트 순서에 의존관계가 있는 것은 좋은 테스트가 아니다

 

🎈🎈Repository를 인터페이스로 설계 : MemberRepository 인터페이스를 구현한 구현체의 변경이 쉽다.

 

Q. 자료형 변경한 이유는 무엇인가요? (MemberRepository > MemoryMemberRepository)

A. MemberRepository가 인터페이스를 참조하는 경우 인터페이스에서 정의된 메소드만 사용할 수 있는데요. 추가한 메소드인 clearStore()가 인터페이스가 아닌 이것을 구현한 클래스에 존재하기 때문에 찾지 못해서 MemoryMemberRepository 클래스를 참조하도록 바꿔준 거에요.

(답변 출처)

 

 

 

출처 : 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

반응형
반응형

ref. holycoders

- java.util 패키지의 Collection 프레임워크

- 후입선출(LIFO : Last In First Out)

 

 

🔩 선언

Stack<String> stringStack = new Stack<String>(); // String타입

Stack<Character> charStack = new Stack<Character>(); // Char타입

Stack<Integer> integerStack = new Stack<Integer>(); // Integer타입
Stack<Integer> integerStack2 = new Stack<>(); // 뒷 부분 타입 생략 가능

Integer, String, Character 등 다양한 형타입으로 선언 가능

 

Stack stack = new Stack(); // 타입 선언 생략 가능 > Object로 선언
Stack<class> stack = new Stack<class>(); // class타입

형타입 생략 가능하지만 웬만하면 명시해주는걸로..!

 

🔩 Stack 값 추가 : push()

stack.push(5);
stack.push(6);

 

🔩 Stack 값 제거 : pop();

stack.pop();	//6 제거
stack.pop();	//5 제거

*값이 없는데 pop()을 하면 오류가 떨어지기 때문에 널체크 주의!

 

🔩 Stack 크기 구하기 : size();

stack.size()

 

🔩 Stack 값 구하기 : peek();

import java.util.*;
import java.io.*;
  
public class StackDemo {
  
      // Main Method
    public static void main(String args[])
    {
        // Creating an empty Stack
        Stack<String> stack = new Stack<String>();
  
        // Use push() to add elements into the Stack
        stack.push("Welcome");
        stack.push("To");
        stack.push("Geeks");
        stack.push("For");
        stack.push("Geeks");
        
        // Displaying the Stack
		System.out.println("Stack: " + stack);

        // Fetching the element at the head of the Stack
        System.out.println("The element at the top of the"+ " stack is: " + stack.peek());
        
     }
 }

> 결과

Initial Stack: [Welcome, To, Geeks, For, Geeks]
The element at the top of the stack is: Geeks

 

🔩 Stack 값 비우기 : clear();

🔩 Stack null 체크 : isEmpty();

 


ref. https://www.geeksforgeeks.org/stack-class-in-java/

 

Stack Class in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

🗒 간단한 Stack 문제 풀고 싶으면 아래 문제 추천

https://www.acmicpc.net/problem/9012

 

9012번: 괄호

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고

www.acmicpc.net

 

반응형
반응형

 

상황) 선택된 라디오 버튼의 강의명과 강의시간의 값이 필요하다.

> 상위(부모) 요소에 접근하여 얻고자 하는 요소의 값을 얻을 수가 있다.

 

1. 체크된 라디오 버튼 변수 선언

const radBtn = $(":input:radio[name=sltUser]:checked");

2. 체크된 라디오 버튼의 상위 li를 가져오기

const li = radBtn.closest('li')					// 체크된 라디오버튼의 상위 li

3. find 메소드를 활용하여 td 값 가져오기

li.find('td:eq(0)').text();	// 강의명
li.find('td:eq(1)').text();	// 강의시간

 

* 전달받은 퍼블리싱이 아래와 같이 되어 있어서 이와 같이 접근하였으며, 상위 및 하위 요소를 찾는 것은 자주 쓰이므로 예제1이라 생각하기

 

- index.html

<li>
    <section>
      <header>
        <div>
          <label>
            <input type="radio" name="radBtn">
            <span>선택</span>
          </label>
        </div>
      </header>

      <table>
        <caption>상세</caption>
        <colgroup>
          <col style="width: 100px;">
          <col>
        </colgroup>
        <tbody>
          <tr>
            <th scope="row">강의명</th>
            <td>휘낭시에 만들기</td>
          </tr>
          <tr>
            <th scope="row">강의시간</th>
            <td>18:00 ~ 19:00</td>
          </tr>
        </tbody>
      </table>
    </section>
</li>

 

 

 

반응형
반응형

 

 갓으로 불리고 있는 인프런 강의에 단연 꼽히고 있다. 스프링을 쓰면서 어떻게 동작을 하는지, Beans나 서블릿과 같은 개념도 부족하다고 느껴서 나에게 투자해보자는 마음으로 강의를 듣고 있다. 유료강의다보니 고민을 하다가 고민하는 시간에 무료 강의분을 듣고 뒷 부분 강의를 사서 듣는게 맞다고 판단된다. 앞 부분에 인텔리제이 스프링 부터 환경세팅 부분도 있지만, 타임리프 엔진을 처음 써봐서 View 환경 설정부터 정리하기로 결심! 타임리프 처음 써보는데 재밌다🏃‍♀️


 

 

- helloController

@Controller
public class HelloController {
     @GetMapping("hello")
     public String hello(Model model) {
     model.addAttribute("data", "hello!!");
     return "hello";
 }
}

 

http://localhost:8080/hello을 던지면 SpringBoot는 내장 톰캣 서버에서 받아서 

 

@GetMapping("hello")

Get 방식으로 hello url 매칭되어 helloController의 hello 메서드가 실행이 됨.

model에 data를 담아 return함

 

**컨트롤러에서 리턴 값으로 문자를 반환하면 뷰 리졸버( viewResolver )가 화면을 찾아서 처리한다.

resources:templates/ +{ViewName}+ .html

 

 > 컨트롤러 리턴 값과 템플릿 파일 이름 매핑(타임리프 템플릿 엔진 처리) 

 

 

- resources/templates/hello.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
 <title>Hello</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'안녕하세요. ' + ${data}" >안녕하세요. 손님</p>
</body>
</html>

 

참고: spring-boot-devtools 라이브러리를 추가하면, html 파일을 컴파일만 해주면 서버 재시작 없이 View 파일 변경이 가능하다. (인텔리J 컴파일 방법: 메뉴 build > Recompile)

 


 

- 윈도우 환경에서 빌드하기

> cd c:study\hello-spring

> doskey ls = dir

> ls

> gradlew build

 

> cd build\libs

>  java -jar hello-spring-0.0.1-SNAPSHOT.jar

*서버 배포할 때는 jar 파일만 복사해서 서버에 넣어주기

 

 

 

 

출처 : 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

반응형
반응형

백준 11650번 좌표 정렬하기 https://www.acmicpc.net/problem/11650

 

11650번: 좌표 정렬하기

첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.

www.acmicpc.net

 

arr[0][0]과 arr[1][0]의 값이 같다면 arr[0][1] 값과 arr[1][1] 값을 비교하여 작은 값을 먼저 출력하면 된다.

 

즉, 오름차순 + 오름차순

 


Arrays.sort(arr);

// I cannot be cast to class java.lang.Comparable

 2차원 배열을 이런 식으로 정렬한다면 주석과 같은 오류가 뜬다.

 

1. Comparator로 정렬

for(int i=0; i<N; i++) {
    StringTokenizer st = new StringTokenizer(br.readLine(), " ");
    arr[i][0] = Integer.parseInt(st.nextToken());
    arr[i][1] = Integer.parseInt(st.nextToken());
}

Arrays.sort(arr, new Comparator<int[]>() {
    @Override
    public int compare(int[] o1, int[] o2) {
        return o1[0]==o2[0] ? o1[1]-o2[1] : o1[0]-o2[0];
    }
});

 

2. 람다식 정렬

for(int i=0; i<N; i++) {
    StringTokenizer st = new StringTokenizer(br.readLine(), " ");
    arr[i][0] = Integer.parseInt(st.nextToken());
    arr[i][1] = Integer.parseInt(st.nextToken());
}

Arrays.sort(arr, (o1, o2) -> { return o1[0]==o2[0] ? o1[1]-o2[1] : o1[0]-o2[0]; });

람다식이 훨씬 간결한 코드로 작성된다.

 

* o1, o2의 타입이 int로 같으므로 타입을 작성하지 않아도 됨.

 


🔍간단하게 더 알아보기

 

1. Comparable  VS Comparator 

 

Comparable -  this.val 와 o.val를 비교 (자기 자신과 매개변수를 비교), compareTo 메소드 필요

Comparator - 두 매개변수를 비교

 

나의 가상 스승님이신 블로거님의 정리. 흐릿해지면 정독해

https://st-lab.tistory.com/243

 

2.  Collections.sort() 

Arrays.~~만 쓰지말고 다른 것도 써보자!

 

반응형
반응형

https://www.acmicpc.net/problem/2231

 

2231번: 분해합

어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이

www.acmicpc.net

 

🌌 전체 코드 (밑에 응용 버전O)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main{
	public static void main(String args[]) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		int N = Integer.parseInt(br.readLine());

		int cnt=0;
		
		for(int i=0; i<N; i++) {
			int num=i;
			int sum=0;
			
			while(num != 0) {
				sum+=num%10;	//1자리 수부터 계산하여 sum에 합계
				num/=10;		//앞자리 수 숫자 계산을 위해 10 나누기
			}
			
			if(sum+i==N) {
				System.out.println(i);
				cnt++;
				break;
			} 
		}
		
		if(cnt==0) {
			System.out.println(0);	//생성자가 없으면 0 출력
		}
	}
}

브루트포스 알고리즘은 0부터 목표 수까지 그냥 돌리면 돼서 쉬운데 코드를 짤 때 완전탐색 방식으로 짜지 않다보니 꼬이고 꼬이는 편이다.. 풀이를 보면 쉬운데 보기 전에는 혼자 우주까지 가버린다. 여러 문제를 풀면 쉽게 풀릴거 같으니 문제를 많이 풀어봐야겠다.

 

완탐 방식을 생각못하고 효율적으로 짜야겠다며 처음엔 236이 주어지면 2이하, 3이하, 6이하의 숫자만 올 수 있어서 이를 코드로 녹이려고 했는데 중첩의 중첩 반복문이 될 아이디어였다.

 

해당 코드는 나의 가상스승님이신 블로거님 코드를 참고하였다.

https://st-lab.tistory.com/98

 

[백준] 2231번 : 분해합 - JAVA [자바]

www.acmicpc.net/problem/2231 2231번: 분해합 문제 어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다

st-lab.tistory.com


for(int i=0; i<N; i++) {
    int num=i;
    int sum=0;

    while(num != 0) {
        sum+=num%10;	//1자리 수부터 계산하여 sum에 합계
        num/=10;		//앞자리 수 숫자 계산을 위해 10 나누기
    }

    if(sum+i==N) {
        System.out.println(i);
        cnt++;
        break;
    } 
}

 

백준 예제로 실행해본다고 가정

while(num!=0){
    sum+=num%10;
    num/=10;
}

> num = 198 일 때,

 

1) sum = 8; num = 19;

sum+=198%10;

num/=10;

 

2) sum = 17; num = 1;

sum+=19%10;

num/=10;

 

2) sum = 18; num = 0;

sum+=1%10;

num/=10;

 

if(sum+i==N) {
    System.out.println(i);
    cnt++;
    break;
}

18+198 = 256;

생성자가 없을 경우를 생각해서 카운팅하고

제일 작은 수의 생성자를 출력해야하기 때문에 break문으로 for문을 탈출

 


🌌 전체 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main{
	public static void main(String args[]) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		String strN = br.readLine();
		int str_len = strN.length();	//N의 자릿수
		int N = Integer.parseInt(strN);	//int로 형타입 변환
		int cnt=0;
		
		for(int i=N-(str_len*9); i<N; i++) {
			int num=i;
			int sum=0;
			
			while(num != 0) {
				sum+=num%10;	//1자리 수부터 계산하여 sum에 합계
				num/=10;		//앞자리 수 숫자 계산을 위해 10 나누기
			}
			
			if(sum+i==N) {
				System.out.println(i);
				cnt++;
				break;
			} 
		}
		
		if(cnt==0) {
			System.out.println(0);
		}
	}
}

처음엔 이게 무슨 소리지 했다. 근데 겁나 간단함.

 

예를들어, 1234와 같은 4자리 수가 N으로 주어진다면

자릿수 별 합은 9+9+9+9가 최대가 되기 때문에 최댓값 9와 자릿수를 곱해야한다.

이를 N에서 빼면 최소 N-(str_len*9)부터 N까지의 숫자만 생성자가 될 수 있다.

 

생성자가 될 수 있는 최솟값은 1234-(9*4)인 것.

1234의 생성자 x를 구할 때

36+x = 1234니깐! x=1234-36!! 

for(int i=N-(str_len*9); i<N; i++) {
	...
 }

 

반응형
반응형

https://www.acmicpc.net/problem/1259

 

1259번: 팰린드롬수

입력은 여러 개의 테스트 케이스로 이루어져 있으며, 각 줄마다 1 이상 99999 이하의 정수가 주어진다. 입력의 마지막 줄에는 0이 주어지며, 이 줄은 문제에 포함되지 않는다.

www.acmicpc.net

 

🌌 전체 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main{
	public static void main(String args[]) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		StringBuilder sb2 = new StringBuilder();
		String str = "";

		while ((str = br.readLine()) != null && (Integer.parseInt(str) != 0)) {
			sb.setLength(0); //sb 객체 비우기
			String strReverse = sb.append(str).reverse().toString();

			if(str.equals(strReverse)) {
				sb2.append("yes" + "\n");
			} else {
				sb2.append("no" + "\n");
			}
		}
		System.out.println(sb2);
	}
}

나는 이 문제에서 StringBuilder를 적극 활용했다.

 

1. for문 배열 길이 신경 쓰기보다 EOF 체크를 하면서  while문을 돌렸고 0이라면 while문을 실행X

while ((str = br.readLine()) != null && (Integer.parseInt(str) != 0)) {
	...
}

 

2. sb 객체를 비우고 reverse() 메소드를 활용하여 input된 값과 비교

while ((str = br.readLine()) != null && (Integer.parseInt(str) != 0)) {
    sb.setLength(0); //sb 객체 비우기
    String strReverse = sb.append(str).reverse().toString();

    if(str.equals(strReverse)) {
        sb2.append("yes" + "\n");
    } else {
        sb2.append("no" + "\n");
    }
}

 

* 너무 간단하게 풀려서 다른 풀이를 확인해봤는데 역배열을 하여 비교하거나 배열의 반틈만 비교하는 방법이 있었다.

반응형