✿∘˚˳°∘°
8일차 : 배열 본문
2022/12/07
[ 1. 버블 정렬 ] =====================================================================
작은수부터 출력하기(정렬)
[ 자리바꿈로직 ]
if(arr[0] > arr[1]) {
int tmp = arr[0];//배열 첫번째값을 임시로 넣어둘 임시공간
arr[0] = arr[1];
arr[1] = tmp;
}
if(arr[1] > arr[2]) {
int tmp = arr[1];
arr[1] = arr[2];
arr[2] = tmp;
}
if(arr[2] > arr[3]) {
int tmp = arr[2];
arr[2] = arr[3];
arr[3] = tmp;
}
if(arr[3] > arr[4]) {
int tmp = arr[3];
arr[3] = arr[4];
arr[4] = tmp;
} //첫번째 정렬끝
if(arr[0] > arr[1]) {
int tmp = arr[0];
arr[0] = arr[1];
arr[1] = tmp;
} ~~ 반복
public void exam4() {
//길이가 5인 정수형 배열을 생성하고 반복문을 통해 숫자 5개를 입력받는다.
//중간에 정렬하는 코드를 만들어서 작은수부터 출력한다.(정렬)
Scanner sc = new Scanner(System.in);
int[] arr = new int[10];
for(int i=0; i<arr.length; i++) {//입력for문
System.out.print((i+1)+"번째 숫자 입력 : ");
arr[i] = sc.nextInt();
}
//배열 0번째 값 과 배열 1번째 값을 비교해서
//배열 0번째가 더 크면 자리를 바꾸는 로직
for(int i=0; i<arr.length-1; i++) {
//배열 내부값을 검사하면 검사수 : 배열길이-1 / 5칸배열(0~4) : 0-1, 1-2, 2-3, 3-4
for(int j=0; j<arr.length-1-i; j++) {
//j와 j+1을 비교하기때문에 배열.length까지를 범위로 잡으면 배열을 넘어가므로 error
//거기에 한번돌아가면 마지막부터 배열값이 이미 정렬이되므로 -i를 해주어 불필요한 반복제거
//-i를 빼더라도 결과는 맞게 나오지만, 불필요한 반복이 동작하므로 i를 빼주는 것.
if(arr[j] > arr[j+1]) { //j인덱스가 j+1인덱스보다 값이 클때 구동
int tmp = arr[j];//j에 j+1값을 넣어줄거기때문에(덮어쓰기) 기존j는 변수를 많들어서 대입해놓음
arr[j] = arr[j+1];//j+1의 값을 j에 대입
arr[j+1] = tmp; //tmp에 저장되어있던 j인덱스의 값을 j+1인덱스에 대입(결과 : 위치가 서로 반대가됨)
}
}
}
/* if(arr[0] > arr[1]) {
//자리바꿈로직
int tmp = arr[0];//배열 첫번째값을 임시로 넣어둘 임시공간
arr[0] = arr[1];
arr[1] = tmp;
}
if(arr[1] > arr[2]) {
int tmp = arr[1];
arr[1] = arr[2];
arr[2] = tmp;
}
if(arr[2] > arr[3]) {
int tmp = arr[2];
arr[2] = arr[3];
arr[3] = tmp;
}
if(arr[3] > arr[4]) {
int tmp = arr[3];
arr[3] = arr[4];
arr[4] = tmp;
}================================= 첫번째 정렬
if(arr[0] > arr[1]) {
int tmp = arr[0];
arr[0] = arr[1];
arr[1] = tmp;
}
*/
for(int i=0; i<arr.length; i++) {//출력 for문
System.out.print(arr[i]+" ");
}
}
[ 2. 중복값 검사 ] ==================================================================
:정수를 입력받아 기존에 입력하여 배열에 들어간 값이면 중복입니다 출력 + 재입력
public void exam5() {
//1. 배열에 들어가는 숫자는 중복이면 중복입니다 메세지 출력
//2. 배열에 중복숫자가 들어갈 수 없도록
//단, 0은 입력하지 않는다고 가정
//num : 사용자가 입력한 숫자가 들어있음
//배열 : 최종적으로 저장할 숫자
Scanner sc = new Scanner(System.in);
int[] arr = new int[5];
for(int i=0; i<arr.length; i++) {
System.out.print((i+1)+"번째 숫자 입력 : ");
int num = sc.nextInt();
boolean bool = true;
for(int j=0; j<arr.length; j++) {
if(num == arr[j]) {
i--;//중복시 다시 해당회차를 입력받기 위해서
bool = false;//중복이 하나라도 있으면 아래의 값대입코드실행X
System.out.println("중복");
break; //하나라도 중복되면 로직종료(중복체크를 멈추는 break;)
} //else{ arr[i] = num; } => [X]
//이 경우 첫번째 배열이랑만 체크하고 다음인덱스랑 비교하지않고 값을 넣어버림
}
//중복이 하나라도 있으면 배열에 값을 넣지 않음
if(bool) {
arr[i] = num;
}
}
for(int i=0; i<arr.length; i++) {
System.out.print(arr[i]+"\t");
}
}
public void exam55() {
Scanner sc = new Scanner(System.in);//사용자가 입력받기위해 스캐너사용
int[] arr = new int[5];//5칸짜리 배열생성
for(int i=0; i<arr.length; i++) {
System.out.print((i+1)+"번째 숫자를 입력하세요 : ");//1~5번 입력을 받기위해(배열인덱스 0~4)
int num = sc.nextInt();//입력받은 숫자를 저장할 정수형변수
boolean bool = true;//중복일경우 입력받은 값을 배열에 넣지않기위한 변수
for(int j=0; j<arr.length; j++) { //j<arr.length인 이유 i로 하면 0/01/012이렇게검사되므로
if(arr[j] == num) { //j 0 1 2 ... arr.length
i--;//위에서 증감을하는데 재입력을 받기위해 i값을 줄여준다.
bool = false;//중복값이 나오면 아래에서 값대입을 하지않기위한변수
System.out.println("중복입니다.");
break; //j 0~arr.length까지 돌리는동안 중복이 하나라도 있으면 코드실행x
//i=0 - j~arr.length : 0번인덱스입력할때 배열인덱스중복검사(0~arr.length)
//i=1 - j~arr.length : 1번인덱스입력할때 배열인덱스중복검사(0~arr.length)
//배열인덱스 중복검사 시 만갸 arr[1]의 인덱스와 num이 중복되면 어차피 넣어주지 않을거기때문에
//break;를 통해 for문을 나가주고 다음 for문(i)을 실행하기위해
} //j-for문에 else{ arr[i]=num }을 해주면 안되는 이유
//여기에 else를 넣어버리면 0번인덱스만 검사를하고 이후인덱스는 중복여부검사를 하지않고
//(if문은 if가아니면 바로 else로 가버리니까)바로 값을 넣어버리므로 이후에는 중복값이 들어갈수잇다.
}
if(bool) {//내부for문(j)에서 arr[j]==num이 충족되면 bool = false가 되어 아래코드 실행x
arr[i] = num;
}
}
}
[ 3. 로또 프로그램 ] =================================================================
: 범위1~45 / 중복값X / 버블정렬 /
사용자에게 값을 6개 입력받아 중복값검사와 버블정렬 후 출력.
컴퓨터는 랜덤값 6개를 받아 중복값검사와 버블정렬 후 출력.
사용자가 입력한값과 컴퓨터의 랜덤값의 일치불일치를 확인하여 일치가 6이상일시 1등!
public void lotto() {
//범위조절(1~45), 유저컴퓨터 중복X
//사용자번호 컴퓨터번호 정렬되어 출력
//맞은갯수 출력(6개:1등 5개:2등 - 꽝)
Scanner sc = new Scanner(System.in);
Random r = new Random();
System.out.println("=========== 로또 프로그램 ===========");
int[] uLotto = new int[6];//입력한번호가 들어갈 배열(중복x, 버블정렬)
int[] cLotto = new int[6];//컴퓨터 랜덤번호가 들어갈배열(중복x, 버블정렬)
for(int i=0; i<uLotto.length; i++) {//사용자입력for문
boolean bool = true;//사용자중복값 외부for문안에있어야 구동할때마다 true가 되므로 꼭!!!!
System.out.print((i+1)+"번째 번호 입력(1~45) : ");
int uNum = sc.nextInt();//사용자가 입력한 로또번호
if(uNum <= 0 || uNum > 46) {
System.out.println("1~45중 한개를 입력해주세요.");
i--;
}else {//1 <= uNum && num <= 45
for(int j=0; j<uLotto.length; j++) {//사용자입력중복체크
if(uNum == uLotto[j]) {
bool = false;
i--;
System.out.println("이미 중복된 번호입니다. 다시 입력해주세요.");
break;
}
}
if(bool) {
uLotto[i] = uNum;
}
}//범위else문종료
}
//사용자값 출력 for문(작은순서대로 버블정렬)
for(int i=0; i<uLotto.length-1; i++) {
for(int j=0; j<uLotto.length-1-i; j++) {
if(uLotto[j] > uLotto[j+1]) {
int tmp = uLotto[j];
uLotto[j] = uLotto[j+1];
uLotto[j+1] = tmp;
}
}
}//사용자 버블정렬종료
int count = 0; //회차변수
while(true) {//54321등이 되어야 종료되는 반복문
//컴퓨터 랜덤번호 출력
int win = 0;//컴퓨터-사용자비교를해서 동일하면 카운트해줄 변수(while내부에 있어야계속 초기화)
for(int i=0; i<cLotto.length; i++) {//컴퓨터
int cNum = r.nextInt(45)+1;
boolean bool = true;
for(int j=0; j<cLotto.length; j++) {//컴퓨터 중복체크
if(cNum == cLotto[j]) {
bool = false;
i--;
break;
}
}
if(bool) {
cLotto[i] = cNum;
}
}
//컴퓨터 버블정렬
for(int i=0; i<cLotto.length-1; i++) {
for(int j=0; j<cLotto.length-1-i; j++) {
if(cLotto[j] > cLotto[j+1]) {
int tmp = cLotto[j];
cLotto[j] = cLotto[j+1];
cLotto[j+1] = tmp;
}
}
}
//컴퓨터 - 사용자 등수체크
for(int i=0; i<uLotto.length;i++) {
for(int j=0; j<cLotto.length;j++) {
if(uLotto[i] == cLotto[j]) {
win++;
break;//내부for문에서 동일값이 나오면 더이상 검사할필요없으니까(중복값검사를했으므로)
//반복문을 나가준다.
}
}
}
System.out.println("============ 결과 ============");
//사용자 출력
System.out.println("사용자 번호");
for(int i=0; i<uLotto.length; i++) {
System.out.print(uLotto[i]+" ");
}
System.out.println();
//컴퓨터 출력
System.out.println("컴퓨터 번호");
for(int i=0; i<cLotto.length; i++) {
System.out.print(cLotto[i]+" ");
}
System.out.println();
count++;
System.out.println("[회차] : "+count+" / [ 맞은 갯수 ] : "+win);
if(win == 6) {//switch~case문을 이용할경우 반복 시 while(변수)로 해줘야한다.
System.out.println("1등!");
break;
} else if(win == 5) {
System.out.println("2등!3등!");
} else if(win == 4) {
System.out.println("4등!");
} else if(win == 3 ) {
System.out.println("5등!");
}
else {
System.out.println("꽝!");
}
}
}
public void lotto2() {
//심심해서 한번더해보기
Scanner sc = new Scanner(System.in);
Random r = new Random();
int[] uLotto = new int[6];
int[] cLotto = new int[6];
int win = 0; //맞는갯수확인
System.out.println("======== 로또 프로그램 ========");
for(int i=0; i<uLotto.length; i++) {
boolean bool = true;
System.out.print((i+1)+"번째 번호 입력(1~45) : ");
int uNum = sc.nextInt();
if(uNum <= 0 || uNum > 45) {
System.out.println("잘못 입력하셨습니다. 1~45 중 한개를 입력해주세요.");
i--;
}else {
//중복체크
for(int j=0; j<uLotto.length; j++) {
if( uNum == uLotto[j] ) {
bool = false;
i--;
System.out.println("이미 중복된 번호입니다. 다시 입력해주세요.");
break;
}
}
if(bool) {
uLotto[i] = uNum;
}
}
}
//유저로또번호정렬(버블정렬)
for(int i=0; i<uLotto.length-1; i++) { //uLotto=5 0~3까지만 돌리면 되므로 -1
for(int j=0; j<uLotto.length-1-i; j++) {
//j와 j+1을 비교하기때문에 배열.length까지를 범위로 잡으면 배열을 넘어가므로 error
//거기에 한번돌아가면 마지막부터 배열값이 이미 정렬이되므로 -i를 해주어 불필요한 반복제거
if(uLotto[j] > uLotto[j+1]) {//만약 왼쪽(j)인덱스가 오른쪽(j+1)인덱스보다 크면 자리를 바꿔주는 if문
int tmp = uLotto[j]; //j번째 인덱스를 j+1번인덱스로 옮겨주기위해 빈변수에 넣어줌.
uLotto[j] = uLotto[j+1]; //j+1의 값을 j인덱스에 대입(덮어쓰기)
uLotto[j+1] = tmp; //tmp에 넣은 j인덱스에 있던 값을 j+1인덱스에 덮어쓰기
//기존 : j(큰수) j+1(작은수) -> 변경 : j(작은수) j+1(큰수)
}
}
}
System.out.println("사용자 번호");
for(int i=0; i<uLotto.length; i++) {
System.out.print(uLotto[i]+" ");
}
System.out.println();
//사용자(입력,정렬,중복) 끝
//컴퓨터시작
for(int i=0; i<cLotto.length; i++) { //컴퓨터가 랜덤으로 1~45사이의 값을 출력
int cNum = r.nextInt(45)+1;
boolean bool = true;
for(int j=0; j<cLotto.length; j++) {
if(cNum == cLotto[j]) {
bool = false;
i--;
break;
}
}
if(bool) {
cLotto[i] = cNum;
}
}
//컴퓨터가 생성한 랜덤값 버블정렬
for(int i=0; i<cLotto.length-1; i++) {
for(int j=0; j<cLotto.length-1-i; j++) {
if(cLotto[j] > cLotto[j+1]) {
int tmp = cLotto[j];
cLotto[j] = cLotto[j+1];
cLotto[j+1] = tmp;
}
}
}
System.out.println("컴퓨터 번호");
for(int i=0; i<cLotto.length; i++) {
System.out.print(cLotto[i]+" ");
}
System.out.println();
//컴퓨터 - 유저 비교코드
for(int i=0; i<uLotto.length; i++) {
for(int j=0; j<cLotto.length; j++) {
if(uLotto[i] == cLotto[j]) {
win++;
}
}
}
//갯수출력
System.out.println("맞는 갯수 : "+win);
if(win==6) {
System.out.println("1등!!");
} else if(win==5) {
System.out.println("2등!");
} else {
System.out.println("꽝!");
}
}
[ 4. 배열 복사 - 얕은 복사 / 깊은 복사 ] ===================================================
--- 추가, 알아두면 좋은 사항 ---------------------------------------------------------------------------------------------------------------------------
String str1 = "hi";
String str2 = sc.next();
if(str1 == str2){} -> false
참조형변수는 그 값이 있는 주소값을 가지고 있기때문에 str1의 값(주소값1)과 str2의 값(주소값1)을 비교하면
서로 같을 수 없음.(문자열 비교시 . equals를 사용한걸 참고)
---------------------------------------------------------------------------------------------------------------------------------------------------------------
1) 얕은 복사 : 객체의 주소값만 가져와 참조형변수에 저장하고 하나의 객체를 두 변수가 참조하고 있는것 -서로영향o
(스택메모리에있는 두 변수가 힙메모리에있는 하나의 객체를 참조)
2) 깊은 복사 : 다른 객체를 생성하여 새로운 객체에 값만 복사(똑같은형태로 만들어서) - 서로영향x
2-1) 깊은 복사를 하는 3가지방법 - fo문을 통한 1:1대입 / arraycopy / 배열별명.clone()
/*
배열복사
1.얕은 복사 : 객체의 주소값만 가져와 참조형변수에 저장하고 하나의 객체를 두 변수가 참조하고 있는것 -서로영향o
(스택메모리에있는 두 변수가 힙메모리에있는 하나의 객체를 참조)
String str1 = "hi";
String str2 = sc.next();
if(str1 == str2){} -> false
참조형변수는 그 값이 있는 주소값을 가지고 있기때문에 str1의 값(주소값1)과 str2의 값(주소값1)을 비교하면
서로 같을 수 없음.
2.깊은 복사 : 다른 객체를 생성하여 새로운 객체에 값만 복사(똑같은형태로 만들어서) - 서로영향x
*/
public void arrayCopy() {
int num1 = 10;
int num2 = num1;
System.out.println("num1 : "+num1); //10
System.out.println("num2 : "+num2); //10
num2 = 1000;
System.out.println("num1 : "+num1); //10
System.out.println("num2 : "+num2); //1000
//얕은복사
System.out.println("=== 얕은 복사 ===");
int[] arr1 = {1, 2, 3, 4};
int[] arr2 = arr1;
for(int i=0; i<arr1.length; i++) {
System.out.print(arr1[i]+" "); //1 2 3 4
}
System.out.println();
for(int i=0; i<arr2.length; i++) {
System.out.print(arr2[i]+" "); //1 2 3 4
}
System.out.println();
arr1[2] = 100;
arr2[3] = 1000;
for(int i=0; i<arr1.length; i++) {
System.out.print(arr1[i]+" "); //1 2 100 1000
}
System.out.println();
for(int i=0; i<arr2.length; i++) {
System.out.print(arr2[i]+" "); //1 2 100 1000
}
System.out.println();
//일반형변수와는 달리 참조형변수는 그 객체의 주소값을 가지고 있음
//arr2에 arr1을 넣으면 주소값이 들어간다. 결과적으로 같은객체를 가리키고있음(실제배열은 한개인것)
//그러므로 arr1[2]=100 arr2[3]=1000;을 출력했을때 배열1 배열2 둘다 값이 바뀐것
//깊은복사
System.out.println("=== 깊은 복사 ===");
int[] arr3 = {5, 6, 7, 8};
int[] arr4 = new int[arr3.length];//동일한 길이의 신규배열생성
//깊은복사 1.for문을 통한 1:1값대입
for(int i=0; i<arr3.length; i++) {//arr4에 arr3값을 복사하는 for문
arr4[i] = arr3[i];
}
for(int i=0; i<arr3.length; i++) {
System.out.print(arr3[i]+" ");
}
System.out.println();
for(int i=0; i<arr4.length; i++) {
System.out.print(arr4[i]+" ");
}
System.out.println();
arr3[1] = 1000;
arr4[0] = 0;
for(int i=0; i<arr3.length; i++) {
System.out.print(arr3[i]+" "); // 5 1000 7 8
}
System.out.println();
for(int i=0; i<arr4.length; i++) {
System.out.print(arr4[i]+" "); // 0 6 7 8
}
//중간에 값을 바꿔줘도 서로 영향을 주지않음 : 깊은복사
//서로영향을 주는게 얕은복사(원본데이터도함께변경시) / 영향이 가지않는게 깊은복사(원본데이터유지시)
System.out.println();
}
//깊은복사의 3가지방법
public void arrayCopy2() {
//1.for문을 통한 1:1값대입(위에서함)
//2.arraycopy
int[] arr1 = {1, 2, 3, 4, 5};//원본
int[] arr2 = new int[10];
//1 원본데이터가 저장되어있는 배열
//2 원본배열 중 복사시작 인덱스번호
//3 새 배열(복사값이 들어갈 배열)
//4 새 배열 중 복사된 데이터가 들어갈 시작 인덱스번호
//5 복사할 데이터 길이
System.arraycopy(arr1, 2, arr2, 5, 3);//특정데이터만 복사시 사용
//arr1의 2번인덱스부터 복사해서 arr2번의 5번인덱스부터 넣겠다. 3개를
//0000034500
for(int i=0; i<arr2.length; i++) {
System.out.print(arr2[i]+" ");
}
System.out.println();
int[] arr3 = arr1.clone();//전체데이터 복사시 사용
for(int i=0; i<arr3.length; i++) {
System.out.print(arr3[i]+" ");
}
}
[ 5. 2차원배열 ] ====================================================================
//2차원배열
//1차원 배열안에 다른 배열을 넣은것 / 배열은 저장된 값마다 인덱스 번호 두개로 설정 [행][열]
//3차원은 객체를 이용하고 배열은 2차원까지
public void test5() {
//2차원배열은 [][]를 사용
int[][] arr = new int[2][3]; //2행x3열의 배열
//실제로는 길이가 3인 배열을 2개 저장하는 배열
int k = 1;
for(int i=0; i<arr.length; i++) {//행은 그냥 length
for(int j=0; j<arr[i].length; j++) {//열은 따라갔을 때 그 배열의 length
arr[i][j] = k;
k++;
}
}
for(int i=0; i<arr.length; i++) {
for(int j=0; j<arr[i].length; j++) {
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
[ 후기 ] -------------------------------------------------------------------------------------------------------------------------------------------------------
오늘 제일 오래 연습해본 실습문제는 로또프로그램이었다.
처음에 버블정렬을 이해를 다했다고 생각했는데 사실 덜했던건지 조건식을 계속 잘못넣었는데 주석달면서 여러번 코딩해보니 완벽하게 이해할 수 있었다. 슬슬 8일차가 되니 연습문제도 복잡해지고 길어지기 시작했다. 실습문제가 복잡해 질수록 처음보면 이걸 어떻게해야하나...싶어지는데 막상 차근차근 짜다보면 완성되는게 너무신기하고 재미있다.
오늘 실수한 부분
1. 중복값검사에서 처음 코드짤 때 for문 로직 실수
2. 버블정렬 조건식에 -1되는이유
3. 로또프로그램 win(컴퓨터랑 맞은갯수)변수 위치를 잘못잡음(반복문 밖에 작성해서 계속 카운트됨)
변수위치 잘못잡는 실수를 자주한다. 신경써야겠다.
'국비수업 > JAVA' 카테고리의 다른 글
10일차 : 객체지향프로그래밍 (0) | 2022.12.12 |
---|---|
9일차 : 메소드(Method) (0) | 2022.12.08 |
7일차 : Random, 배열 (0) | 2022.12.07 |
6일차 : Break, Continue, Random (0) | 2022.12.06 |
5일차 : 제어문 (0) | 2022.12.06 |