Algorithm/02. 기본 자료구조

2-1. 배열(Array-2)

찹키리 2020. 9. 20. 20:57

<기수 변환>

 

・정숫값을 임의의 기수로 변환

 

: 10진수 정수를 n진수 정수로 변환하려면 정수를 n으로 나눈 나머지를 구하는 동시에, 그 몫에 대해 나눗셈을 반복한다. 이 과정을 몫이 0이 될 때까지 반복, 나머지를 거꾸로 늘어 놓은 숫자가 기수로 변환한 수가 된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
static int cardConvR(int x, int r, char[] d) {
        
        int digits = 0;
        String dchar = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        
        do {
            d[digits++= dchar.charAt(x % r);
 
            x /= r;
        } while (x != 0);
        return digits;
    }

 

 

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
public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int no;
        int cd;
        int dno;
        int retry;
        char[] cno = new char[32];
        
        System.out.println("10진수를 기수 변환");
        do {
            do {
                System.out.println("변환하는 음이 아닌 정수");
                no = stdIn.nextInt();
            } while(no < 0);
            
            do {
                System.out.println("어떤 진수로 변환?(2~36)");
                cd = stdIn.nextInt();
            } while(cd < 2 || cd > 36);
            
            dno = cardConvR(no, cd, cno);
            
            System.out.println(cd + "진수로는 ");
            for(int i = dno - 1; i >= 0; i--) {
                System.out.print(cno[i]);
            }
            System.out.println();
            
            System.out.println("함 더? (1.예 / 2.아니오): ");
            retry = stdIn.nextInt();
        } while(retry == 1);
    }

 

 

 

 

 

*String 클래스는 많은 생성자와 메서드를 제공한다.

String 클래스의 생성자와 메서드

char charAt(int i) // 인덱스가 i인 곳의 문자를 가져옴
int length() //문자열의 문자 수를 가져옴
boolean equals(String s) //문자열 s와 같은가를 조사

 

 

 

 

 

<소수의 나열>

 

소수 = 2부터 n-1까지의 어떤 정수로도 나누어떨어지지 않는 수

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class PrimeNumber1 {
    public static void main(String[] args) {
        int counter = 0;
        
        for(int n = 2; n <= 1000; n++) {
            int i;
            for(i = 2; i < n; i++) {
                counter++;
                if(n % i == 0)
                    break;
            }
            if(n == i)
                System.out.println(n);
        }
        
        System.out.println("나눗셈을 수행한 횟수: " + counter);
    }

 

 

-> 불필요한 나눗셈이 많다.

 

 

 

개선1)

 

소수 = 2부터 n-1까지의 어떤 소수로도 나누어떨어지지 않는다.

 

 

 

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
public class PrimeNumber2 {
    public static void main(String[] args) {
        
        int counter = 0;
        int ptr = 0;
        int[] prime = new int[500];
        
        prime[ptr++= 2;
        
        for(int n = 3; n <= 1000; n += 2) {
            int i;
            for(i = 1; i < ptr; i++) {
                counter++;
                if(n % prime[i] == 0)
                    break;
            }
            if(ptr == i)
                prime[ptr++= n;
        }
        
        for(int i = 0; i < ptr; i++) {
            System.out.println(prime[i]);
        }
        
        System.out.println("나눗셈을 수행한 횟수: " + counter);
    }

 

 

-> 나눗셈을 수행하는 횟수가 훨씬 줄었다.

 

 

 

개선2)

 

소수 = n의 제곱근 이하의 어떤 소수로도 나누어떨어지지 않는다.

 

 

 

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
public static void main(String[] args) {
        int counter = 0;
        int ptr = 0;
        int[] prime = new int[500];
        
        prime[ptr++= 2;
        prime[ptr++= 3;
        
        for(int n = 5; n <= 1000; n += 2) {
            boolean flag = false;
            for(int i = 1; prime[i] * prime[i] <= n; i++) {
                counter += 2;
                if(n % prime[i] == 0) {
                    flag = true;
                    break;
                }
            }
            if(!flag) {
                prime[ptr++= n;
                counter++;
            }
        }
        
        for(int i = 0; i < ptr; i++) {
            System.out.println(prime[i]);
        }
        System.out.println("곱셈과 나눗셈을 수정한 횟수: " + counter);
    }

 

 

 

 

 

 

<다차원 배열>

 

- 2차원 배열

int[][] x = new int[2][4]

 

 

= "int형을 구성 자료형으로 하는 배열"을 구성 자료형으로 하는 배열

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Int2DArray {
    public static void main(String[] args) {
        int[][]    x = new int[2][4];
        
        x[0][1= 37;
        x[0][3= 54;
        x[1][2= 65;
        
        for(int i = 0; i < 2; i++) {
            for(int j = 0; j < 4; j++) {
                System.out.println("x[" + i + "][" + j + "] = " + x[i][j]);
            }
        }

 

 

 

 

 

 

<한 해의 경과 일 수를 계산하는 프로그램>

 

static int[][] mdays = {
	{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},	//평년
	{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}	//윤년
};

 

//서기 year년은 윤년인가?(평년:0 / 윤년:1)
    static int isLeap(int year) {
        return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 1 : 0;
    }

 

//서기 y년 m월 d일의 그 해 경과 일 수
    static int dayOfYear(int y, int m, int d) {
        int days = d;
        
        for(int i = 1; i < m; i++) {
            days += mdays[isLeap(y)][i-1];
        }
        return days;
    }

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int retry;
        
        System.out.println("그 해 경과 일수 구하기");
        
        do {
            System.out.print("년: "); int year = stdIn.nextInt();
            System.out.print("월: "); int month = stdIn.nextInt();
            System.out.print("일: "); int day = stdIn.nextInt();
            
            System.out.printf("그 해 %d일째입니다.\n", dayOfYear(year, month, day));
            
            System.out.println("한 번 더?(1.예 / 2.아니오)");
            retry = stdIn.nextInt();
        } while(retry == 1);
    }

 

 

 

 

 

 

<다차원 배열의 내부>

・다차원 배열의 선언

 

int[][] x = new int[2][4]

 

int[][] x;
x = new int[2];
x[0] = new int[4];
x[1] = new int[4];

 

결과적으로는 같지만, 실제로 2차원 배열은 밑의 구조와 같이 4단계의 선언과 처리로 나누어진다.

즉, 각 행은 다른 배열 본체를 참조하는 것

 

 

 

 

 

・확장 for문

 

for (double i : a)
	sum += i;

*배열 a의 처음부터 끝까지 모든 요소를 한 개씩 스캔. 루프 본문에서는 현재 주목하고 있는 요소를 i라고 표현

 

for(int i = 0; i < a.length; i++)
	sum += a[i];

 

 

- 확장 for문의 장점

>배열의 요솟수(길이)를 조사하는 수고를 덜 수 있다.

>iterator와 같은 방법으로 스캔할 수 있다.

'Algorithm > 02. 기본 자료구조' 카테고리의 다른 글

2-2. 클래스(Class)  (0) 2020.09.29
2-1. 배열(Array-1)  (0) 2020.09.05