Back-End

[JAVA] 기초 공부 5(배열, 정렬)

Minch13r 2025. 1. 2. 17:46

2025.1.2 java 공부 start

 


배열 : 데이터를 저장하는 자료형
배열의 3가지 조건
1. 서로 관련된 데이터
2. 같은 자료형
3. 개수를 분명히 알아야 함

[연산자 new]
"힙(heap)" 메모리에 공간을 생성해주는 연산

	데이터 메모리 영역	  vs	힙 메모리 영역
	변수(데이터 메모리 영역)		개발자의 영역
	함수 >> main()			new >> 선언해야 영역 open
    					자동 초기화

배열을 쓰는 이유는 코드의 간편함을 위해서 쓴다. 예시를 들자면 stu1=80, stu2=99 ... 등 일 때 출력값을 stu1, stu2 이렇게 다 불러오는 것보다 stu[i]를 통해 반복문으로 인덱스값이 증가돼서 불러오는게 훨씬 편할 것이다.

 

배열을 쓰기 위해서는 위에 나온 3가지 조건을 꼭 지켜줘야 한다. 안 그러면 오류 나기도 하고 배열의 값을 미리 선언해주고 배열 안에 값을 넣어줘야 메모리 누수가 나지 않기 때문이다. 예를 들어서 배열을 100개가 들어갈만한 것을 선언하고 실제로 들어가는 것은 2개밖에 없다면 98개의 공간이 비기 때문에 메모리 누수가 일어난다.

 

heap 메모리에 int 형의 3개만큼 공간이 존재하는거고 studentlist가 주소를 기억해 주소 불러오면 heap 메모리 첫번째에 위치한 것을 불러오는 형태이다.

 

배열선언은 int[] stuList = new int[3];  이렇게 해주면 된다.

배열안에 데이터를 넣는 방법은 stuList[0]= 80; stuList[1]=99; stuList[2]=60; 이렇게 해주면 된다.

왜 첫번째를 0으로 했냐고? 이걸 index라고 하는데 약속 같은거다. 컴퓨터 상에서는 첫번째는 0부터 시작이다.

향상된 for문. forEach문

for(저장된 데이터의 타입	변수명 : 출력할 집합 데이터){
	System.out.println(변수명);
    }
package day005.class01;
/* 배열 : 데이터를 저장하는 자료형
배열의 3가지 조건
1. 서로 관련된 데이터
2. 같은 자료형
3. 개수를 분명히 알아야 함

[연산자 new]

*  */
public class Test01 {
    public static void main(String[] args) {
        // int num = 10; //4byte 만큼 저장
        // double d=3.14; //8byte 만큼 저장
//        int stu1=80;
//        int stu2=99;
//        int stu3=60;
//        int[] stu = new int[3];
//        for(int i=1; i<=3; i++){
//            System.out.println("학생 "+i+"은 "+stu1+"점 입니다.");
//        }

        int[] stuList = new int[3];
        // 변수명 예시를 stuArr stuList stuDatas
        // int는 정수형의 변수를 쓰고 싶다는 뜻, stuArr은 이름
        // new int[3]은 3칸만큼의공간을 갖고싶다라는 뜻
        stuList[0]=80;
        stuList[1]=99;
        stuList[2]=60;

//        System.out.println("학생 1의 점수는 "+stuList[0]+"점입니다.");
//        System.out.println("학생 2의 점수는 "+stuList[1]+"점입니다.");
//        System.out.println("학생 3의 점수는 "+stuList[2]+"점입니다.");

        for(int i=0;i<3;i++){ //i+1은 index 때문에 +1 해준거임
            System.out.println("학생 " + (i+1) + "의 점수는 "+stuList[i]+"점 입니다.");
        }

        for(int v : stuList){
            System.out.println(v);
        }
    }
}

 

향상된 for문은 front 측에서 많이 쓰고 기존 for문은 back 측에서 많이 쓴다.

package day005.class01;

import java.util.Random;
import java.util.Scanner;

public class Test02 {
    public static void main(String[] args) {
        // 사용자가 입력하는 값만큼 랜덤수 저장
        Scanner sc = new Scanner(System.in); //scanner 객체 생성
        Random rand = new Random(); //random 객체 생성

        int inputNum;
        while (true) { // 무한루프
            System.out.print("랜덤정수를 몇개 생성할까요? : ");
            inputNum = sc.nextInt(); //사용자가 입력하는 값

            if(inputNum>=0){ //종료 조건, 정상값이 입력됐을 때
                break;
            }
            System.out.println("0이상 정수를 입력해주세요!");
        }
        // 서로 관련된 데이터, 같은 자료형, 개수의 명확성(배열 3조건 만족 확인)
        int[] randList = new int[inputNum]; //동적할당

        for(int i=0; i<inputNum; i++){
            randList[i] = rand.nextInt(10); // 0~9
        }

        for(int v:randList){
            System.out.print(v+" ");
        }
    }
}

0~9 사이의 랜덤수를 몇개 뽑는지 내가 지정할 수 있는 코드이다. 향상된 for문과 기존 for문 둘 다 넣어봤다. 여러 코드를 확인하고 싶으면 내 깃허브를 들어오면 된다. 블로그 메인하면 가장 하단에 주소가 있다.


사용자가 입력하는 값 배열에 저장하기

package day005.class02;

import java.util.Scanner;

public class Test01 {
    public static void main(String[] args) {
        // 사용자가 입력하는 값들을 저장해보기
        int[] datas = new int[3];
        Scanner sc = new Scanner(System.in);

        // datas.length
        // 길이, 사이즈, 요소의 개수
        for(int i=0; i<datas.length; i++){
            while(true){
                System.out.print((i+1) + "번째 정수 입력 >> ");
                datas[i]=sc.nextInt();

                if(datas[i]>0){ //종료조건
                    break;
                }
                System.out.print("양수만 입력해주세요!");
            }
        }
        System.out.print("[ ");
        for(int v:datas){
            System.out.print(v + " ");
        }
        System.out.print("]");
    }
}

스캐너를 통해 5개의 정수를 입력하는데, 홀수들만 저장하게 하기

package day005.class02;

import java.util.Random;

public class Test02 {
    public static void main(String[] args) {
        // 5개 정수를 입력하는데, 홀수들만 저장

        // Random 만들기

        // 5개의 정수를 저장할 배열공간 선언
        // 1번 정수 저장공간
        // 저장할건데, 만약에 홀수가 아니라면?
        // 다시 1번 정수 저장
        // 저장할건데, 만약에 홀수가 아니라면?
        // while 사용

        Random rand = new Random();
        int[] datas = new int[5];

        for(int i=0; i<datas.length; i++){
            while(true){
                datas[i]=rand.nextInt(10);
                if(datas[i]%2==1){ // 종료조건
                    break;
                }
            }
        }

        for(int v:datas){
            System.out.println(v + " ");
        }
    }
}

5개의 정수를 입력 받아 총합과 평균 구하기

package day005.class02;

import java.util.Scanner;

public class Test03 {
    public static void main(String[] args) {
        // 5개의 정수를 입력
        // 총합과 평균

        int[] datas = new int[5];

        Scanner sc = new Scanner(System.in);

        for(int i=0; i<datas.length; i++){
            System.out.print((i+1)+ "번째 정수입력 >> ");
            datas[i]=sc.nextInt();
        }
        int total=0;
        double avg;

        for(int v : datas){
            total += v;
        }

        avg = total*1.0/datas.length;
        System.out.println("총합 : " + total);
        System.out.println("평균 : " + avg);
    }
}

사용자가 배열의 크기를 정하고 값이 짝수면 저장 안 하게 하기

이후 정수를 하나 더 입력받고 해당 번째에 저장된 정수 출력

package day005.class03;

import java.util.Scanner;

/* 사용자가 얼만큼 입력할지 정하고, 값들을 저장하는데 입력한 값이 짝수면 저장안함
*  모두 저장되었다면 정수를 하나 더 입력받아서, 해당 번째에 저장된 정수 출력
*  5
*  10 20 30 40 50
*  2 => 20*/
public class Test01 {
    public static void main(String[] args) {
        /* scanner 객체 생성
        *  값들을 저장할 배열 선언
        *  for(int i=0; i<=datas.length; i++) 이렇게 증가시키면서
        *  인덱스 값마다 정수 입력받기
        *  짝수면 저장 안 함
        *  모두 저장됐을 때, 정수 하나 더 입력받기
        *  입력받은 값에 해당하는 몇번째 위치한 것 출력
        * */

        Scanner scanner = new Scanner(System.in);
        int[] datas = new int[5]; // 값이 저장될 배열 선언

        for(int i=0; i<datas.length; i++){ //배열 길이만큼 늘어남
            while(true) {
                System.out.print((i + 1) + "번째 정수를 입력해주세요 : ");
                int input = scanner.nextInt();

                if(input % 2 == 0) { //짝수는 저장 안 됨, 유효성 검사
                    System.out.println("짝수는 저장되지 않습니다. 다시 입력해주세요.");
                    continue;  // while문의 처음으로 돌아가 다시 입력받음
                }

                // 홀수인 경우에만 배열에 저장하고 while문 종료
                datas[i] = input;
                break;
            }
        }

        System.out.print("[ ");
        for(int v:datas) {
            System.out.print(v+" ");
        }
        System.out.print(" ] ");

        System.out.println(); //줄바꿈

        while(true) { // 원하는 위치 확인하기 위해서 얼마나 반복할지 몰라서 while로 무한루프
            //오타가 나면 다시 해야하니까 불분명 때문에 while 쓰는거임
            System.out.print("몇번째 위치에 해당한 숫자를 알고 싶으신가요? : ");
            int num = scanner.nextInt(); //원하는 위치 입력받기

            if(num > 0 && num <= datas.length) { //원하는 위치가 1보다 크고 배열의 길이보다 작거나 같아야 함
                System.out.println("["+datas[num-1]+"]"); //인덱스가 0부터 시작하기 때문에
                //1번째부터 출력을 위해 num-1을 입력
                //num이 1일 때 [num] ex) [1] = 두번째 위치 출력
                //num이 1일 때 [num-1] ex) [0] = 첫번째 위치 출력
                break; // 올바른 입력을 받았으므로 반복문 종료
            } else { // 잘못된 숫자를 입력하면 다시 입력할 수 있게 유효성 검사
                System.out.println("잘못된 위치를 입력하셨습니다.");
                continue; // 다음 반복으로 넘어가서 다시 입력받기
            }
        }

    }
}

사용자가 배열의 크기를 정하고, 5개의 정수를 랜덤으로 중복없이 저장

이후 정수를 하나 입력받고 해당 번째에 저장된 정수 출력

package day005.class03;

import java.util.Random;
import java.util.Scanner;

/* 사용자가 얼만큼 입력할지 정하고, 5개의 정수를 랜덤으로 중복없이 저장
*  모두 저장되었다면 정수를 하나 더 입력받아서, 해당 번째에 저장된 정수 출력*/
public class Test02 {
    public static void main(String[] args) {
        /* 스캐너와 랜덤 객체 생성
        *  값들을 저장할 배열선언
        *  new int[3] 이런것보다 [변수} 하고 scanner로 값 받는게 나을 것 같음
        *  for(int i=0; i<datas.length; i++)을 통해 5개의 정수 랜덤으로 저장
        *  배열크기가 정수의 범위보다 크면 출력이 어려우니 배열+1로 정의하는게 좋을 것 같음
        *  중복있을 시 다시 진행, 이후 랜덤으로 중복없이 저장
        *  중복 카운트를 만들어서 중복되면 다시 하게 하고 카운트가 0 일 때 저장시킴
        *  저장된 후, 정수를 하나 더 입력받고, 해당 번째에 저장된 정수 출력*/

        // scanner와 random 객체 생성
        Scanner sc = new Scanner(System.in);
        Random rand = new Random();

        // 값들을 저장할 배열을 선언하고 배열 크기는 입력받기
        System.out.print("배열의 크기를 입력하세요: ");
        int size = sc.nextInt();
        int[] datas = new int[size];

        // 랜덤 숫자 저장
        for (int i = 0; i < datas.length; i++) {
            //랜덤 정수 범위를 1~10으로 지정해놓으면 배열 크기가 20을 입력 받으면 중복없이 숫자를 뽑을 수가 없음
            int randomNum = rand.nextInt(size + 1) + 1; // 1부터 배열 크기보다 1만큼 큰 숫자 사이 랜덤 숫자

            // 중복 검사
            int count = 0;
            for (int j = 0; j < i; j++) {
                if (datas[j] == randomNum) {
                    i--; // 중복이면 i를 감소시켜 현재 위치에 다시 저장하도록 함
                    count++; // 중복이 발견되면 count 증가
                    break;
                }
            }
            // 중복이 없을 경우에만 배열에 저장
            if (count == 0) {
                datas[i] = randomNum;
            }
        }

        System.out.print("[ ");
        for(int v:datas) {
            System.out.print(v+" "); //배열이 어떻게 저장되었는지 보여줌
        }
        System.out.print("]");
        System.out.println(); // 줄바꿈

        while(true) { // 원하는 위치 확인하기 위해서 얼마나 반복할지 몰라서 while로 무한루프
            //오타가 나면 다시 해야하니까 불분명 때문에 while 쓰는거임
            System.out.print("몇번째 위치에 해당한 숫자를 알고 싶으신가요? : ");
            int num = sc.nextInt(); //원하는 위치 입력받기

            if(num > 0 && num <= datas.length) { //원하는 위치가 1보다 크고 배열의 길이보다 작거나 같아야 함
                System.out.println("["+datas[num-1]+"]"); //인덱스가 0부터 시작하기 때문에
                //1번째부터 출력을 위해 num-1을 입력
                //num이 1일 때 [num] ex) [1] = 두번째 위치 출력
                //num이 1일 때 [num-1] ex) [0] = 첫번째 위치 출력
                break; // 올바른 입력을 받았으므로 반복문 종료
            } else { // 잘못된 숫자를 입력하면 다시 입력할 수 있게 유효성 검사
                System.out.println("잘못된 위치를 입력하셨습니다.");
                continue; // 다음 반복으로 넘어가서 다시 입력받기
            }
        }
    }
}

위에 코드랑 같지만 다른사람이 짠 코드라 약간 다를 수 있음. 참고용

package day005.class04;
/*
사용자가 얼만큼 입력할지 정하고, 값들을 저장하는데 입력한 값이 짝수면 저장안함
모두 저장되었다면 정수를 하나 더 입력받아서, 해당 번째에 저장된 정수 출력

6

11 31 123 123 -3 -1

2 --->> 31
 */

import java.util.Scanner;

public class Test01 {
    public static void main(String[] args) {
        /* 배열의 크기를 정하고
         *  배열의 사이즈를 정하고
         *  배열의 길이를 정하고
         *  배열에 저장될 요소(elements)의 개수를 정하고*/
        Scanner sc=new Scanner(System.in);
        int len; // scope 이슈 해결
        while(true) {
            System.out.print("배열의 길이 입력 >> ");
            len=sc.nextInt();
            if(len>0) {
                break;
            }
            System.out.println("배열의 길이는 1이상이어야만합니다! 다시입력해주세요!");
        }
        int[] datas=new int[len];
        for(int i=0;i<datas.length;i++) {
            while(true) {
                System.out.print((i+1)+"번째 데이터 입력 >> ");
                datas[i]=sc.nextInt();
                if(datas[i]%2==1) { // 종료조건
                    break;
                }
                System.out.println("홀수만 입력가능합니다! 다시입력해주세요!");
            }
        }
        int num; // scope 이슈 해결
        while(true) {
            System.out.print("몇번째 데이터를 출력할까요? >> ");
            num=sc.nextInt();
            if(1<= num && num<=datas.length) { // 종료조건
                break;
            }
            System.out.println("배열에 존재하지않는 인덱스넘버입니다! 다시입력해주세요!");
        }
        for(int v:datas) {
            System.out.print(v+" ");
        }
        System.out.println();
        System.out.println(datas[num-1]);

    }
}

최대값 찾기 알고리즘

package day005.class06;
// 최대값 찾기 알고리즘
public class Test01 {
    public static void main(String[] args) {
        int[] datas = new int[5];
        datas[0]=5;
        datas[1]=1;
        datas[2]=7;
        datas[3]=9;
        datas[4]=2;
        System.out.print("[ ");
        for(int v:datas){
            System.out.print(v+" ");
        }
        System.out.print("]");

        // 1. [0]에 있는 값이 최대값일거라고 단정짓기
        int max=datas[0];
        int maxIndex=0; //max값이 저장된 인덱스 위치

        // 2. [1]부터 마지막 인덱스까지 돌면서,
        // 최대값보다 큰 값이 있는지 확인
        for(int i=1; i<datas.length; i++){
            if(max < datas[i]){
                // 3. max가 잘못 설정된 경우
                // 즉, max보다 큰 값을 찾은 경우
                // max 재설정
                max = datas[i];
                maxIndex=i;
            }
        }
        System.out.println(max);
        System.out.println("max의 인덱스 : "+maxIndex);
    }
}

최소값 찾기 알고리즘

package day005.class06;
//최소값 찾기
public class Test02 {
    public static void main(String[] args) {
        int[] datas = new int[5];
        datas[0]=5;
        datas[1]=1;
        datas[2]=7;
        datas[3]=9;
        datas[4]=2;
        System.out.print("[ ");
        for(int v:datas){
            System.out.print(v+" ");
        }
        System.out.println("]");

        /* 최소값 단정짓기
         * min값이 저장된 인덱스
         * [1]부터 마지막 인덱스까지 돌면서
         * 최소값보다 작은 값이 존재하는지 확인
         * min보다 작은 값을 찾았을 때 min 재설정
         * min값 출력 및 인덱스 찾기*/

        int min = datas[0];
        int minIndex=0;
        for(int i=1; i<datas.length; i++){
            if(min > datas[i]){
                min=datas[i];
                minIndex=i;
            }
        }

        System.out.println(min);
        System.out.println("min의 인덱스 : " + minIndex);
    }
}

Bubble sort

package day005.class07;
// 정렬 알고리즘
//  : [버블] 삽입 선택 | 퀵
//  why?
//   데이터 검색을 빠르고 효율적으로 하기위함!
public class Test01 {
	public static void main(String[] args) {

		// [버블 정렬]
		// 1회전 정렬을 하면,
		// 가장 큰 값이 제자리를 찾음
		// --->> 4회전 정렬을 하면 모두 제자리를 찾음!

		int[] datas=new int[5];
		datas[0]=7;
		datas[1]=10;
		datas[2]=5;
		datas[3]=3;
		datas[4]=2;

		for(int v:datas) {
			System.out.print(v+" ");
		}
		System.out.println();

		for(int a=0;a<datas.length-1;a++) {
			// 1회전 정렬
			for(int i=0;i<datas.length-1;i++) { // 양옆 데이터끼리 비교하는 횟수
				if(datas[i] > datas[i+1]) {
					// 교환 알고리즘
					int tmp=datas[i];
					datas[i]=datas[i+1];
					datas[i+1]=tmp;
				}
			}

			System.out.print((a+1)+"회전 정렬 완료 : ");
			for(int v:datas) {
				System.out.print(v+" ");
			}
			System.out.println();
		}




	}
}

데이터 검색

package day005.class07;

import java.util.Random;
import java.util.Scanner;

// 데이터 검색하기
public class Test02 {
    public static void main(String[] args) {

       int[] datas=new int[10];
       Random rand=new Random();
       for(int i=0;i<datas.length;i++) {
          datas[i]=rand.nextInt(100)+1;
       }
       for(int v:datas) {
          System.out.print(v+" ");
       }
       System.out.println();
       
       Scanner sc=new Scanner(System.in);
       System.out.print("찾고싶은 정수 입력 >> ");
       int num=sc.nextInt();
       int index=0;
       
       boolean flag=false; // 못찾은상태
       
       for(int i=0;i<datas.length;i++) {
          if(num == datas[i]) {
             index=i;
             flag=true; // 플래그 ON
          }
       }
       
       if(flag) {
          System.out.println(num+"은 ["+index+"]에 있습니다.");
       }
       else {
          System.out.println(num+"은 없습니다.");
       }
       
       
       
       
       
    }
}

Binary Search

package day005.class07;

import java.util.Random;
import java.util.Scanner;

// 데이터 검색하기
// 이진 탐색(이분 검색) ===>> 데이터가 "정렬"되어있어야함!
public class Test03 {
    public static void main(String[] args) {

       int[] datas=new int[10];
       Random rand=new Random();
       for(int i=0;i<datas.length;i++) {
          datas[i]=rand.nextInt(100)+1;
       }

       // 버블 정렬
       for(int i=0;i<datas.length-1;i++) {
          for(int j=0;j<datas.length-1;j++) {
             if(datas[j] > datas[j+1]){
                int tmp=datas[j];
                datas[j]=datas[j+1];
                datas[j+1]=tmp;
             }
          }
       }

       for(int v:datas) {
          System.out.print(v+" ");
       }
       System.out.println();

       Scanner sc=new Scanner(System.in);
       System.out.print("찾고싶은 정수 입력 >> ");
       int num=sc.nextInt();

       int START=0;
       int END=9;
       // 이진 탐색
       int pivot;
       while(true) {
          pivot=(START+END)/2; // 피벗(기준)
          if(datas[pivot] < num) { // 가운데 숫자보다 내가 찾으려는게 크니?
             // 업! 상황
             START=pivot+1;
          }
          else if(datas[pivot] > num) { // 가운데 숫자보다 내가 찾으려는게 작니?
             // 다운! 상황
             END=pivot-1;
          }
          else { // 종료조건 : 찾았다면
             break;
          }  

          if(START > END) { // 종료조건 : 못찾았다면
             // CROSS(교차) 발생
             break;
          }
       }

       if(START<=END) {
          System.out.println(num+"은 ["+pivot+"]에 있습니다.");
       }
       else {
          System.out.println(num+"은 없습니다.");
       }












    }
}