SyntaxHighlighter.all(); 게을러지고 싶어 부지런한 개발자 :: 게을러지고 싶어 부지런한 개발자

https://www.acmicpc.net/problem/10972규칙

 

1. 오른쪽에서 왼쪽으로 이동하면서 n과 n-1을 비교한다.

2. n-1 < n인경우를 찾는다. 찾은 인덱스를 기준으로 왼쪽 영역과 오른쪽 영역을 나눌 수 있다.

ex) 12543  --> 12 543

     123645987  --> 123645 987 

3. 해당 인덱스에 있는 숫자를 가지고 오른쪽 영역에서 오른쪽부터 왼쪽영역으로 움직이면서 크기를 비교한다.

4. 크다면 자리를 바꾼다.

5. 오른쪽영역의 숫자를 오름차순으로 정렬해준다.

 

글보다 숫자로 표기하면 더 이해하기 쉽다.

 

입력 : 326154

--> 3261 54  (영역 나누기)

--> 3261 54  (크기 비교하기)

--> 3264 51  (자리 바꾸기)

--> 3264 15  (오름차순 정렬)

출력 : 326415

 

 

 

10972번: 다음 순열

첫째 줄에 입력으로 주어진 순열의 다음에 오는 순열을 출력한다. 만약, 사전순으로 마지막에 오는 순열인 경우에는 -1을 출력한다.

www.acmicpc.net

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
 
//다음 순열
public class Baekjoon10972 {
 
    public static void main(String[] args) throws NumberFormatException, IOException {
        
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
        int N = Integer.parseInt(br.readLine()); 
        int arr[] = new int[N];
        
        StringTokenizer st = new StringTokenizer(br.readLine(), " "); 
        
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        
        if (nextPermutation(arr)) {
            for (int i = 0; i < N; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        } else {
            System.out.println("-1");
        }
    }
    
    public static boolean nextPermutation(int[] arr) {
        
        //뒤에서부터 탐색하면서 a-1보다 a가 더 큰 경우 찾음
        int a = arr.length - 1;
        while(a > 0 && arr[a-1>= arr[a]) a--;
        if (a <= 0 ) return false;
        
        //다시 뒤에서부터 탐색하며 a-1보다 b가 더 큰 경우 찾음
        int b = arr.length - 1;
        while(arr[a-1>= arr[b]) b--;
        
        //a랑 b를 swap
        int tmp = arr[a-1];
        arr[a-1= arr[b];
        arr[b] = tmp;
        
        //a에서부터 끝까지를 오름차순 정렬 
        int start = a;
        int end = arr.length - 1;
        while(start < end) {
            tmp = arr[start];
            arr[start] = arr[end];
            arr[end] = tmp;
            start++;
            end--;
        }
        return true;
    }
}

 

<자바의정석 3판, Ch2 내용 중> 

 

변수의 타입은 크게 기본형 & 참조형로 나눔 

기본형(Primitive type)

실제 값(data)을 저장   

<총 8개>

-문자형(char)

-정수형(byte, short, int, long)

-실수형(float, double)

-논리형(boolean) 

참조형(Reference type) 객체의 주소를 저장 . 8개의 기본형 제외한 나머지

 

기본형에서 boolean을 제외한 나머지 타입들은 서로 형변환이 가능 

-하지만 기본형 <-> 참조형은 서로 형변환 할 수 없음 (참조형의 형변환은 자바-Ch7에 설명) 

변환 방법:   (타입)피연산자

 

정수형에서 실수형으로 변환:

  • 실수형이 정수형보다 훨씬 큰 저장범위 갖기에 정수형-> 실수형 변환에 별 무리가 X
  • 한 가지 주의할 점: float는 약 7자리의 정밀도만을 제공하므로, 8자리 이상의 정수값을 실수형으로 변환할 때는 float이 아닌 약 15자리의 정밀도를 갖는 double로 형변환해야 오차 발생 안함                                            

Ex.

int형 12345678를 float으로 변환  → 12345679.0

int형 12345678를 double로 변환 → 12345678.0

 

실수형을 정수형으로 변환 

  • 실수형의 소수점 이하 값은 버려짐(자료의 손실 발생 가능) 
  • 반올림 발생 X  (ex. 실수 1.666 를 int로 형변환하면, 1이 됨) 

 

자동 형변환

: 서로 다른 타입의 변순간의 연산은 형변환을 하는 것이 원칙이지만,

값의 범위가 작은 타입에서 큰 타입으로의 형변환은 생략 가능 

(컴파일러가 생략된 형변환을 자동적으로 해줌) 

 

ex) int i = 3; 

     double d = 1.0 + i;    //double d = 1.0 + (double)i; 에서 형변환 생략됨 

 

 

 

 

기본형타입 간 형변환 예시 

class Main {
	
	public static void main(String[] args) {
		int i = 12345678; 
		float f = (float)i;  //int를 float으로 형변환
		int i2 = (int)f; 	 //float를 다시 int로 형변환
		
		double d = (double)i; //int를 double로 형변환
		int i3 = (int)d;      //double를 다시 int로  형변환 	
		System.out.println(i);   //출력:  12345678
		System.out.println(f);   //출력: 12345679.0
		System.out.println(i2);  //출력: 12345679
	
		System.out.println(d);	 //출력: 12345678.0
		System.out.println(i3);  //출력: 1234568
	}
}

 

jsp에서 작성한 Form 데이터를 스프링의 Controller가 받아오는 방법이 있다. 



1) HttpServletRequest 클래스 이용






2) @RequestParam 어노테이션







3) 데이터 (Command) 객체 이용  

-기존의 @RequestParam의 개선방법


-2)의 @RequestParam을 사용하는 경우, 데이터를 많이 받게 되면 코드가 길어지고 복잡해짐.

따라서 2)과 같은 기존 방법보다는 데이터 (command) 객체를 이용하면 훨씬 간결해진다. 


 


3-1) Command 객체의 이름 변경

그리고 개발자는 @ModelAttribute 어노테이션을 이용하면 커맨드 객체의 이름도 변경 가능! 


만약 객체의 이름이 studentInformation인데, 이걸 좀 더 줄여서 studentInfo이라고 변경하고자 한다면 아래와 같이 변경가능 


Controller.java

1
2
3
4
5
@RequestMapping("/studentView")
    public String studentView(@ModelAttribute("studentInfo") StudentInformation studentInformation) {
    
    return "studentView";   //studentView.jsp
}
cs


studentView.jsp

1
2
3
4
5
6
7
8
9
10
11
12
이름: ${studentInfo.name} <br />
나이: ${studentInfo.age} <br />
학년: ${studentInfo.grade} <br />
반: ${studentInfo.gradeNum} <br />
 
 
<!--만약 studentInfo로 커맨드 객체명을 바꾸지 않았더라면 아래와 같이 사용...
이름: ${studentInformation.name} <br />
나이: ${studentInformation.age} <br />
학년: ${studentInformation.grade} <br />
반: ${studentInformation.gradeNum} <br /> -->
cs





출처: 인프런 Wiz Spring 

//  /example + /mapping.do = /example/mapping.do


Controller에서 @RequestMapping을 클래스와 메소드에 아래 그림과 같이 모두 적용 시 나중에 브라우저 띄울 때 두 개를 합친 url을 써야 한다.


    /example + /mapping.do = /example/mapping.do





출력된 브라우저 화면



Controller에서 View로 데이터 전달하는 두 가지 방법이 있음





1) Model 클래스를 이용한 데이터 전달 

  

 Controller.java

1
2
3
4
5
6
7
@RequestMapping("/ex.do")
    public String ex(Model model) {            //Model 객체를 파라미터로 받음
        
        model.addAttribute("id""abcde");       //Model 객체에 데이터를 담음
        
        return "ex";                           //ex.jsp
    }
cs




실행결과 


id는 abcde 입니다. 





2) ModelAndView 클래스를 이용한 데이터 전달 


Controller.java 

1
2
3
4
5
6
7
8
9
@RequestMapping("/ex2.do")
    public ModelAndView ex2() {   //데이터 타입이 ModelAndView
        
        ModelAndView mv = new ModelAndView();  //ModelAndView 객체 생성
        mv.addObject("pw""12345");     //Model 객체에 데이터를 담음
        mv.setViewName("ex2");             //뷰이름 정함 (ex2.jsp)
        
        return mv;
    }
cs


실행결과


pw는 12345 입니다. 


숫자로 이루어진 문자열을 숫자로, 또는 그 반대로 변환하는 경우가 자주 있음.


●기본형 값을 String으로 변환


두가지 방법이 있음. 


(1) 숫자에 빈 문자열 ""을 더해주기

또는

(2) valueOf() 사용 

(성능은 valueOf()가 더 좋지만, 빈 문자열을 더하는 방법이 간단하고 편하기 때문에 성능향상이 필요한 경우에만 valueOf()를 쓰자. )


1
2
3
int i = 100;
String str1 = i + "";                //100을 "100"으로 변환하는 방법1
String str2 = String.valueOf(i);    //100을 "100"으로 변환하는 방법1
cs




●String을 기본형 값으로 변환 


반대로 String을 기본형으로 변환하는 방법도 간단함.


(1) parseInt() 사용

또는 

(2) valueOf() 사용 


1
2
3
int i1 = Integer.parseInt("100");    //"100"을 100으로 변환하는 방법1
int i2 = Integer.valueOf("100");    //"100"을 100으로 변환하는 방법2
 
cs




기본형과 문자열간의 변환방법을 정리하면 다음과 같다. 

 기본형 -> 문자열

문자열 -> 기본형 

String String.valueOf(boolean b)

String String.valueOf(char b)

String String.valueOf(int b)

String String.valueOf(long b)

String String.valueOf(float b)

String String.valueOf(double b)

boolean Boolean.parseBoolean(String s)
byte Byte.parseBoolean(String s)
short Short.parseBoolean(String s)
int Integer.parseBoolean(String s)
long long .parseBoolean(String s)
float Float.parseBoolean(String s)
double Double .parseBoolean(String s)


예외 & 예외처리란? 


예외(Exception): 프로그램에 문제가 있는 것.

예외처리(Exception handling): 예외로 인해 시스템 동작이 멈추는 것을 막는 것 



계층구조 


예외 클래스 계층도


계층구조 - Throwable 클래스 


Throwable 클래스: 모든 예외의 조상이 되는 Exception 클래스와 모든 오류의 조상이 되는 Error 클래스의 부모 클래스


-이 클래스에는 예외나 오류에 관한 다양한 정보를 확인할 수 있는 다음과 같은 메소드가 포함됨 

메소드설명
String getMessage()해당 throwable 객체에 대한 자세한 내용을 문자열로 반환함.
void printStackTrace()해당 throwable 객체와 표준 오류 스트림(standard error stream)에서 해당 객체의 스택 트레이스(stack trace)를 출력함.
String toString()해당 throwable 객체에 대한 간략한 내용을 문자열로 반환함.


계층구조 - Exception 클래스의 두 하위클래스

 

1. RuntimeException 클래스

2. 그 외의 Exception 클래스의 자식 클래스



1) RuntimeException클래스들: 주로 프로그래머의 실수로 발생하는 예외 

RuntimeException 클래스를 상속받는 자식 클래스들은 주로 치명적인 예외 상황을 발생시키지 않는 예외들로 구성됨

따라서 try / catch 문을 사용하기보다는 프로그램을 작성하면서 예외가 발생하지 않도록 주의를 기울이는 편이 좋음.

이처럼 예외처리를 개발자의 판단에 맞기는 경우 (ex. 데이터 오류 등), Unchecked Exception 라고 함 


ex)

- ArrayIndexOutOfBoundException: 배열에서 존재하지 않는 인덱스 가리킬때

- ArithmeticException: 정수를 0으로 나누려고 하는 경우

- ClassCastException: 클래스간의 형변환을 잘못한 경우 

- NumberFormatException: 숫자데이터 문제데이터 등을 넣었을 때

- NullPointerException: null 객체의 레퍼런스를 이용하거나 null 객체의 인스턴스 메소드를 호출하는 등 



2) Execption클래스들: 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외  

(RuntimeException클래스들을 제외한 나머지 클래스들)

 

 RuntimeException클래스들 이외의 Exception 클래스에 속하는 자식 클래스들은 치명적인 예외 상황을 발생시키므로, 반드시 try / catch 문을 사용하여 예외를 처리해야만 함. 이처럼 예외처리를 반드시 해야하는 경우는 (ex. 네트워크, 파일 시스템, 파일 입출력 등) Checked Exception라고 함 


ex) 


-ClassNotFoundException: 실수로 클래스의 이름을 잘못 적은 경우

-DataFormatException: 입력한 데이터 형식이 잘못된 경우

-FileNotFoundException: 존재하지 않는 파일의 이름 입력 시  





예외처리 방법


1. try-catch-fianally : 예외 발생 시 개발자가 알아서 해결


-catch문과 finally문은 선택(옵션)이므로 반드시 작성할 필요는 없음 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
try {
 
    예외를 처리하길 원하는 실행 코드;
 
catch (e1) {
 
    e1 예외가 발생할 경우에 실행될 코드;
 
catch (e2) {
 
    e2 예외가 발생할 경우에 실행될 코드;
 
}
 
...
 
finally {
 
    예외 발생 여부와 상관없이 무조건 실행될 코드;
 
}
cs



●어떤 예외가 발생했는지 알기 위해 사용하는 메소드들 

(Throwable클래스를 상속받고 있으므로 바로 호출가능) 


 e.printStackTrace();   :   어떤 예외 발생했는지 콘솔에 출력    ex) java.lang.ArithmeticException: / by zero

 e.getMessage();        :   예외 간략히 나타낸 문자열 나타냄    ex) / by zero

 
1
2
3
4
5
6
7
8
9
10
11
12
try {
 
    System.out.println(5 / 0);
 
catch (Exception e) {
 
    e.printStackTrace(); 
 
    String msg = e.getMessage(); //java.lang.ArithmeticException: / by zero
 
    System.out.println("Exception: " + msg); //Exception: / by zero 
}
cs


결과:



2. throws 키워드 사용하여 메소드에 예외 선언하기

:예외처리 직접 하지 않고 호출한 곳으로 넘김 (단순히 예외를 전달만 하므로 결국 try-catch문으로 예외처리 필요) 



사용자 정의 예외 클래스

자바에서는 Exception 클래스를 상속받아 자신만의 새로운 예외 클래스를 정의하여 사용 가능 

사용자 정의 예외 클래스에는 생성자뿐만 아니라 필드 및 메소드도 원하는 만큼 추가 가능


(요즘에는 Exception 클래스가 아닌 예외 처리를 강제하지 않는 RuntimeException 클래스를 상속받아 작성하는 경우 많음)

1
2
3
4
5
6
7
class MyException extends RuntimeException {
 
    MyException(String errMsg) {
 
        super(errMsg);
    }
}
cs



try-with-resources 문 (자동 자원 반환)

JDK1.7부터 try-with resources문이라는 try-catch문의 변형이 새로 추가됨 
-이 구문은 주로 입출력(I/O)과 관련된 클래스 사용 때 유용

ex) 파일에서 문자열을 한 줄 읽어오는 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static String readFile(String filePath) throws IOException {
 
    BufferedReader br = new BufferedReader(new FileReader(filePath));
 
    try {
 
        return br.readLine();
 
    } finally {
 
        if (br != null)
 
            br.close();
    }
}
cs

위와 같이 Java SE 7 이전에서는 finally 블록을 사용하여 사용한 파일을 닫아줘야 했음 


하지만 try-with-resources 문을 사용하면 다음과 같이 자동으로 파일의 닫기를 수행할 수 있음

1
2
3
4
5
6
7
static String readFile(String filePath) throws IOException {
 
    try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
 
        return br.readLine();
    }
}
cs




제어자란?

-주로 클래스, 변수 또는 메소드에 사용되며, 부가적 의미를 부여

-크게 접근제어자와 기타제어자로 나눌 수 있음

 

접근제어자(4가지 중 하나만 선택해서 사용 가능) public, protected, default, private 

기타제어자(여러 제어자 조합하여 사용 가능)  :     static, fianl, abstractm native, transient, synchronized, volatile, strictfp

 

 

Ⅰ.접근제어자

접근 제어자를 사용하는 이유

 

 - 데이터가 유효한 값을 유지하도록, 또는 비밀번호와 같은 데이털르 외부에서 함부로 변경하지 못하도록 하기 위해 .

  이것을 데이터 감추기 또는 데이터 은닉(data hiding)이라고 하며, 객체지향개념의 캡슐화(encapsulation)에 해당

  -외부에서 접근할 필요가 없는 멤버들을 private으로 지정하여 외부에 노출시키지 않음으로써 복잡성 줄임.

 

 

 

접근범위가 넓은 쪽에서 좁은 쪽의 순으로 왼쪽부터 나열

public > protected > (default) > private  

 

제어자 

같은 클래스 

같은 패키지  

다른 패키지 자손클래스 

전체 

public 

 

 

 

 

protected

 

 

 

 

(default) 

 

 

 

 

 private

 

 

 

 

 

 

 

private 접근제어자:

private 접근 제어자를 사용하여 선언된 클래스 멤버는 외부에 공개되지 않으며, 외부에서는 직접 접근 X

즉, 자바 프로그램은 private 멤버에 직접 접근할 수 없으며, 해당 객체의 public 메소드를 통해서만 접근할 수 O

private

 

 

 

default 접근제어자:

default를 위한 접근 제어자는 따로 존재 안하며, 접근 제어자가 지정되지 않으면 자동적으로 default 접근 제어를 갖게됨

 

 

default 접근 제어를 가지는 멤버는 같은 클래스의 멤버와 같은 패키지에 속하는 멤버에서만 접근할 수 있음.

default

 

 

 

 

 

protected 접근제어자:

-같은 패키지 내에서, 그리고 다른 패키지의 자식클래스에서 접근 가능

 protected

 

 

 

public 접근제어자:

public 접근 제어자를 사용하여 선언된 클래스 멤버는 외부로 공개되며, 해당 객체를 사용하는 프로그램 어디에서나 직접 접근 가능

 default

 

 

 

 

Ⅱ.기타제어자

-static, fianl, abstractm native, transient, synchronized, volatile, strictfp

-하나의 대상에 대해 여러 제어자를 조합하여 사용하는 것이 가능

 

static - 클래스의, 공통적인

 사용될 수 있는 곳 - 클래스, 메소드, 초기화 블럭

 

<static이 붙은 멤버변수>

-모든 인스턴스에 공통적으로 사용되는 클래스변수(=static이 붙은 변수)가 됨

-클래스변수는 인스턴스 생성하지 않고도 사용 가능

-클래스가 메모리에 로드될 때 생성됨 

 

<static이 붙은 메소드>

-인스턴스를 생성하지 않고도 사용 가능

-static이 붙은 메소드 내에서는 인스턴스 멤버들을 직접 사용할 수 X

 

 

 

final - 마지막의, 변경될 수 없는

-마지막, 또는 변경될 수 없는 의미를 가지며 거의 모든 대상에 사용 가능

 

용될 수 있는 곳 - 클래스, 메소드, 멤버변수, 지역변수  

 

-final이 붙은 변수는 상수이므로 일반적으로 선언과 초기화를 동시에 하지만, 생성자를 이용하여 인스터스변수의 경우 final멤버변수의 초기화를 가능하게 함

즉, 클래스 내에 매개변수를 갖는 생성자를 선언하여 final이 붙은 멤버변수가 다른 값을 갖도록 하는 것이 가능

 

 

 

abstract - 추상의, 미완성의

-'미완성'의 의미를 가지므로 메소드의 선언부만 작성하고 실제 수행내용은 구현하지 않은 추상메소드 선언 시 사용 됨

 용될 수 있는 곳 - 클래스, 메소드

 

 

+ Recent posts