[JAVA]15일차(만년달력/주민등록번호 유효성 검사/정렬알고리즘/선택 정렬/버블 정렬)

정효진·2021년 8월 3일
0

Developer Study

목록 보기
17/47
post-thumbnail

8월3일(화)

Test099~Test104

▪ 만년달력 코드

/*
실행 예)
『연도』를 입력하세요 : 2021
『월』을 입력하세요 : 8

        [ 2020년 8월 ]

  일  월  화  수  목  금  토
 =============================
   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
 =============================
 계속하려면 아무키나 누르세요....

○ 문제 분석 및 접근
	- 서기 1년 1월 1일 : 월요일
	- 연도가 4의 배수이면서 100의 배수가 아니거나,
	  400의 배수이면 2월은 29일(윤년),
	  나머지는 2월 28일(평년)
	- 만약 2021년 8월 달력을 그린다고 가정하면
	  1.1.1 ~ 2021.7.31 까지의 날 수를 구한다.
	  그 날 수에 『+1』 연산을 수행하면... (1.1.1 ~ 2021.8.1) 날 수 확인
	  이 날 수를 통해 2021년 8월 1일의 요일 확인


*/

// 2021 8 3 --> 화요일
// 2021 8 -> 2021 8 1 --> 일요일
import java.util.Scanner;

public class hyodii101
{
	public static void main(String[] args)
	{
		int y, m, w, nalsu;
		Scanner sc = new Scanner(System.in);
		do
		{
			System.out.print("『연도』를 입력하세요 : ");
			y = sc.nextInt();
		}
		while (y<1);
		
		do
		{
			System.out.print("『월』을 입력하세요 : ");
			m = sc.nextInt();
		}
		while (m<1 || m>12);


		int months[] = {31,28,31,30,31,30,31,31,30,31,30,31};

		String week[] = {"일","월","화","수","목","금","토"};

		if ((y%4==0 && y%100!=0) || y%400==0)
			months[1] = 29;
		
		nalsu = (y-1)*365 + (y-1)/4 - (y-1)/100 + (y-1)/400;

		for (int i=0; i<m-1; i++)
		{
			nalsu += months[i];
		}

		nalsu += 1;

		w =nalsu % 7;


		System.out.println();
		System.out.printf("\t[ %4d년 %2d월 ]",y,m);
		System.out.println();
		System.out.println("  일  월  화  수  목  금  토");
		System.out.println("=============================");

		for (int i=0; i<w; i++)
		{
			System.out.print("    ");
		}

		for (int i=1; i<=months[m-1]; i++)   //--check~!!
		{
			System.out.printf("%4d",i);
			w++;

			if(w%7==0)
				System.out.println();
		}
		if (w%7!=0)
		{
			System.out.println();
		}
		
		System.out.println("=============================");

	}
}

▪ 만년달력 코드 설명📝

import java.util.Scanner;

public class Test101
{
	public static void main(String[] args)
	{
		int nalsu, y, m, w;  //날수 년 월 요일
		Scanner sc = new Scanner(System.in);
		do
		{
			System.out.print("『연도』를 입력하세요 : ");
			y = sc.nextInt();
		}
		while (y<1);
		
		do
		{
			System.out.print("『월』을 입력하세요 : ");
			m = sc.nextInt();

		}
		while (m<1 || m>12);
		
		int[] months = {31,28,31,30,31,30,31,31,30,31,30,31};
		String[] days = {"일","월","화","수","목","금","토"};
				
		// 입력받은 년도에 해당하는 2월의 마지막 날 계산
		if((y%4==0 && y%100!=0) || y%400==0)
			months[1] = 29;
		/* 현재 months 배열의 1번째 요소(즉, 2월)가 28로 구성되어 있는 상태이기 때문에 생략 가능
		else
			months[1] = 28;
		*/

		// 1. 1년 1월 1일부터 입력받은 년도의 이전년도 12월 31일 까지의 날 수 계산
		nalsu = (y-1)*365 + (y-1)/4 - (y-1)/100 + (y-1)/400;

		// 2. 입력받은 월의 이전 월 까지의  날 수 계산 후 이 계산 결과를 1번의 결과에 더하는 연산
		for (int i=0;i<(m-1);i++ )
		{
			nalsu += months[i];
		}

		// 입력받은 월의 1일을 날 수 누적 연산
		nalsu += 1;  //++nalsu; 같은것

		//요일 산출 -> 입력받은 월의 1일이 무슨 요일인지 확인하기 위한 연산
		w = nalsu % 7;   // 0:일요일,1:월요일 .....

		// 출력(달력 그리기)		
		System.out.println();
		System.out.printf("\t[ %4d년 %2d월 ]\n",y,m);    // \t하면 탭임!!
		System.out.println();
		System.out.println("  일  월  화  수  목  금  토");  //4칸이 요일 하나 공백2개 글자1개가 2
		System.out.println("=============================");
		
		for (int i=0; i<w;i++)
		{
			System.out.print("    ");  //공백 4칸 발생
		}

		// 해달 월(입력한 월)의 날짜들이 출력될 수 있도록 반복문 구성
		for (int i=1; i<=months[m-1];i++)
		{
			System.out.printf("%4d",i);
			w++; //w는 1일이 무슨 요일인지 확인하기 위한것이니까 날짜를 처리할때마다 요일도 하나씩 증가

			// 일요일에 해당하는 날짜일 경우 개행
			if (w%7==0)
			{
				System.out.println();
			}
	
		}

		//2021년7월찍었을경우 불필요한 개행이 실행되는데 안나오게 처리!
		// 달의 마지막 날짜가 출력 형식을 모두 채웠을 경우
		// 이미 일요일 개행이 이루어 졌기 때문에 이 경우는 추가 개행을 하지않도록 처리~!!!
		if (w%7!=0)
		{
			System.out.println();
		}
		
		System.out.println("=============================");


	}
}
/*
『연도』를 입력하세요 : 2021
『월』을 입력하세요 : 8

        [ 2021년  8월 ]

  일  월  화  수  목  금  토
=============================
   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
=============================
계속하려면 아무 키나 누르십시오 . . .


『연도』를 입력하세요 : 2021
『월』을 입력하세요 : 7

        [ 2021년  7월 ]

  일  월  화  수  목  금  토
=============================
                   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
=============================
계속하려면 아무 키나 누르십시오 . . .
*/

▪ 주민등록번호 유효성 검사 코드

/*
○ 주민등록번호 검증 공식

1. 마지막 자리를 제외한 앞자리 수를 규칙에 맞게 곱한다.

	123456-1234567 (주민번호)
	****** ****** --------------------각 자릿수 곱하기
	234567 892345  (각 자리에 곱해질 수)

2. 규칙에 맞게 곱셈 연산을 수행한 결과를 모두 더한다.
ex) 7 5 0 6 1 5 - 1 8 6 2 1 3 3
    * * * * * *   * * * * * *
	2 3 4 5 6 7   8 9 2 3 4 5
------------------------------------
 ->14 +15 + 0 + 30 + 6 + 35 + 8 + 72 + 12 + 6 + 4 + 15
   
   == 217

3. 더해진 결과값을 11로 나누어 『나머지』를 취한다.
		 -----
     11 | 217     ==> 나머지 8


4. 11에서 나머지(8)를 뺀 결과값을 구한다.

	11 - 8 = 3

	※ 3. 의 처리 과정에서 나머지가 0인 경우 -> 11 -> 1
								    1인 경우 -> 10 -> 0
		
		이를 다시 10으로 나누어 나머지를 취한다.

5. 4의 연산 결과가 주민번호를 구성하는 마지막 숫자와 일치하는지의여부를 확인한다.

	일치    -> 유효한 주민번호
	분일치  -> 잘못된 주민번호


실행 예) 750615
주민번호 입력(xxxxxx-xxxxxxx) : 123456-12345678 -> 입력 갯수 초과
>> 입력 오류~!!!
계속하려면 아무 키나 누르셍...

주민번호 입력(xxxxxx-xxxxxxx) : 123456-123456  -> 입력 갯수 미달
>> 입력 오류~!!!
계속하려면 아무 키나 누르셍...

주민번호 입력(xxxxxx-xxxxxxx) : 941231-1234567   -> 유효한 주민 번호
>> 유효한 주민번호~!!!
계속하려면 아무 키나 누르셍...

주민번호 입력(xxxxxx-xxxxxxx) : 941231-1234569   -> 유효하지 않은 주민 번호
>> 잘못된 주민번호~!!!
계속하려면 아무 키나 누르셍...

※ 추가 팁~!!
배열.length      ->  배열의 길이(배열방의 갯수) 반환
문자열.length()  ->  문자열의 길이 반환
ex)
String str = "abcdefg";
str.length();           -> 7
"abcdefg".length();     -> 7
문자열.substring()      -> 문자열 추출
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

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

		String str; //--check~!! 주민번호는 String!

		int[] chk = {2,3,4,5,6,7,0,8,9,2,3,4,5};

		int tot = 0;

		System.out.print("주민번호 입력(xxxxxx-xxxxxxx) : ");
		str = br.readLine();

		if (str.length() != 14)
		{
			System.out.println(">> 입력 오류~!!!");
			return;
		}

		for (int i=0; i<13;i++)
		{
			if (i==6)
			{
				continue;
			}
			tot += chk[i] * Integer.parseInt(str.substring(i,(i+1)));
		}

		int su = tot % 11;
		int result = 11 - su;

		result = result % 10;

		if (result==Integer.parseInt(str.substring(13)))
		{
			System.out.println(">> 유효한 주민번호~!!!");
		}
		else
			System.out.println(">> 잘못된 주민번호~!!!");

	}
}

▪ 주민등록번호 유효성 검사 코드 설명📝

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

public class Test102
{
	public static void main(String[] args) throws IOException
	{
		/*

		//String arr = new String[14];
		//테스트
		String strTemp = "정효진";
		System.out.println(strTemp.length());
		//--==>> 3

		strTemp = "동해물과 백두산이";
		System.out.println(strTemp.length());
		//--==>> 9

		strTemp = "study-hard";
		System.out.println(strTemp.length());
		//--==>> 10

		// substring 테스트
		strTemp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		System.out.println(strTemp.substring(3,5));
		//--==>> DE
		// ABC DE FGHIJKLMNOPQRSTUVWXYZ
		// 012 34 5678

		strTemp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		System.out.println(strTemp.substring(13,17));
		//--==>> NOPQ
		// ABCDEFGHIJKLM NOPQ RSTUVWXYZ
		// 0123456789012 3456 7

		//strTemp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		//System.out.println(strTemp.substring(13,85));
		//--==>> 에러발생(컴파일 에러) 
		//		 StringIndexOutOfBoundsException

		strTemp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		System.out.println(strTemp.substring(5));
		//--==>> FGHIJKLMNOPQRSTUVWXYZ

		strTemp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		System.out.println(strTemp.substring(5,strTemp.length()));
		//--==>> FGHIJKLMNOPQRSTUVWXYZ           --------------
		//										strTemp의 전체 길이

		*/

		
		/*----------------------------------------------------------------------
		//[내가 푼 문제]
		Scanner sc = new Scanner(System.in);
		String num;
		int result, div,sum=0;
								     // 123456-1234567
									 // 234567 892345
		System.out.print("주민번호 입력(xxxxxx-xxxxxxx) : "); 
		num = sc.next();

		if (num.length() != 14)
		{			
			System.out.println(">> 입력 오류~!!!");
			return;
		}
		

		int[] arr = {2,3,4,5,6,7,0,8,9,2,3,4,5};

		for (int i=0; i<13;i++)
		{
			// 1. 마지막 자리를 제외한 앞자리 수를 규칙에 맞게 곱한다.
			// 2. 규칙에 맞게 곱셈 연산을 수행한 결과를 모두 더한다.
			sum += arr[i] * Integer.parseInt(num.substring(i,(i+1)));  //문자열을 int로 변경하는데쓰는 거
				
			
		}

		// 3. 더해진 결과값을 11로 나누어 『나머지』를 취한다.
		div = sum % 11;

		// 4. 11에서 나머지(8)를 뺀 결과값을 구한다.
		result = 11 - div;
		
		//※ 3. 의 처리 과정에서 나머지가 0인 경우 -> 11 -> 1
		//						    1인 경우 -> 10 -> 0

		
		// 이를 다시 10으로 나누어 나머지를 취한다.

		result %= result;

		//5. 4의 연산 결과가 주민번호를 구성하는 마지막 숫자와 일치하는지의여부를 확인한다.
		if (result==Integer.parseInt(num.substring(13)))

			System.out.println(">> 정확한 주민번호~!!");

		else

			System.out.println(">> 잘못된 주민번호~!!");
			-------------------------------------------------------------------*/
		
		//함께 푼 문제
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		//입력받은 주민번호(문자열 생성)
		String str;

				  // 9 5 0 1 0 5 - 1 2 3 4 5 6 7
		int[] chk = {2,3,4,5,6,7,0,8,9,2,3,4,5};
		//                      --  check~!!!

		//곱셈 연산 후 누적합(즉, 각 곱셈의 결과를 더해 나갈 수 있도록 처리...)
		int tot = 0;

		System.out.print("주민번호 입력(xxxxxx-xxxxxxx) : ");
		// str = Integer.parseInt(br.readLine());
		str = br.readLine();

		if (str.length() != 14)
		{
			System.out.println(">> 입력 오류~!!!");
			return;     //-- 메소드 종료 -> main() 메소드 종료 -> 프로그램 종료
		} 

		//테스트
		//System.out.println(">> 자리수 적합~!!");

		/*
		"750615-1252085"
		str.substring(0,1);
		"7"

		Integer.parseInt("7");

		tot += chk[0] * 7;

		str,substring(1,2);
		"5"
		Integer.parseInt("5");

		tot += chk[1] * 5;
		*/

		for (int i=0; i<13; i++)
		{
			//System.out.print(i + " ");  // 0 ~ 12

			if(i==6)
			{
				continue;   // (뒷부분 무시하고...) +  계속해라
			}

			tot += chk[i] * Integer.parseInt(str.substring(i,(i+1)));     //-- 뒷부분
			//         0 -> 2                              0   1   -> "7"   => tot += 2 * 7 
			//         1 -> 3                              1   2       5              3   5

			//         12   5                             12   13      8              5   8	
		
		}

		//---------------------------------------------여기까지는 1. 2. 수행한것!
		//						규칙에 맞게 곱셈 연산을 수행한 결과를 모두 더한 값은 변수 tot에 담겨있는 상황이 된다.

		int su = 11 - tot % 11;

		// 테스트
		System.out.println(su);
		// 10
		// 11
		
		// 최종 결과 출력 이전에....추가 연산 필요~!!!
		// su에 대한 연산 결과가 두 자리로 나올 경우(10 또는 11)
		// 주민번호 마지막 자리의 숫자와 비교할 수 없는 상황
		su = su % 10; //su%=10;

		//----------------------------------------------여기까지 수행하면 3. 과 4. 를 모두 끝낸 상황이며
		//                                              최종 연산 결과는 변수 su에 담겨있는 상황이 된다.

		//if (su==주민등록번호 마지막한자리숫자)
		if (su==Integer.parseInt(str.substring(13)))   //크기비교하려면 정수형태로 바꿔서
			System.out.println(">> 정확한 주민번호~!!!");
		else
			System.out.println(">> 잘못된 주민번호~!!!");
			

	}
}
/*
주민번호 입력(xxxxxx-xxxxxxx) : 941231-2548461
1
>> 정확한 주민번호~!!!
계속하려면 아무 키나 누르십시오 . . .



주민번호 입력(xxxxxx-xxxxxxx) : 941231-22335566
>> 입력 오류~!!!
계속하려면 아무 키나 누르십시오 . . .



주민번호 입력(xxxxxx-xxxxxxx) : 941231-1234567
2
>> 잘못된 주민번호~!!!
계속하려면 아무 키나 누르십시오 . . .
*/
		

◼ 정렬(Sort)

▪ 정렬이란?

: 데이터를 특정한 규칙(기준)에 맞게 순서대로 나열(오름차순, 내림차순)

▪ 정렬의 목적

: 데이터 처리 과정의 편의성이나 가독성을 높이기 위함
-> 보기 좋게... 검색하기 위함

▪ 정렬의 종류

: 선택 정렬, 버블 정력, 삽입 정렬, 힙 정렬, 퀵 정렬, 쉘 정렬....

✔ 알아둬야할 점!

===> 정렬이라는 행위는 부하가 심하다(많은 리소스가 필요하다)

▪ 선택 정렬(Selection Sort) 코드

public class hyodii103
{
	public static void main(String[] args)
	{
		int[] a = {52,42,12,62,60};

		System.out.print("Source Data : ");
		// 향상된 for 문(forEach 구문)  
		for (int n : a)
			System.out.print(n + " ");
		System.out.println();
		
		//Selection Sort
		for (int i=0; i<a.length-1; i++)
		{
			for (int j=i+1;j< a.length; j++)
			{
				if (a[i]>a[j])
				{
					a[i] = a[i]^a[j];
					a[j] = a[j]^a[i];
					a[i] = a[i]^a[j];
				}
			}
		}

		System.out.print("Sorted Data : ");
		for (int n : a )
			System.out.print(n + " ");
		System.out.println();
	}
}

▪ 선택 정렬(Selection Sort) 코드 설명📝

public class Test103
{
	public static void main(String[] args)
	{
		int [] a = {52, 42, 12, 62, 60};
		/*
		42 52 12 62 60     0   1
		== --
		12 52 42 62 60     0   2
		==    --
		12 52 42 62 60     0   3
		==       --
		12 52 42 62 60     0   4
		==          --
		-------------------------------------1회전  (가장작은수 젤 왼편 fix)
		12 42 52 62 60     1   2
		   == --
		12 42 52 62 60     1   3
		   ==    --
		12 42 52 62 60     1   4
		   ==       --
		-------------------------------------2회전  (42 fix)
		12 42 52 62 60     2   3
		      == --
		12 42 52 62 60     2   4
		      ==    --
		-------------------------------------3회전  (52 fix)
		12 42 52 60 62     3   4
		         == --
		-------------------------------------4회전  (62 fix)
		*/

		

		System.out.print("Source Data : ");
		/*
		for (int i=0; i<a.length; i++)
			System.out.print(a[i] + " ");
		System.out.println();
		*/
		//--==>> Source Data : 52 42 12 62 60

		
		// 향상된 for 문(forEach 구문)  
		//   => 배열이나 컬렉션이나 다중데이터구조안에서 첫번째요소부터 마지막요소까지 순차적으로 끄집어낼때 사용함
		for (int n : a)  //오른쪽에는 내가 접근해야하는 배열 과 왼쪽은 요소  (n은 내맘대로 정하면됨!)
			System.out.print(n + " ");
		System.out.println();
		//--==>> Source Data : 52 42 12 62 60



		//Selection Sort
		for (int i=0;i<a.length-1;i++ )      //웅(비교기준 데이터)   ->    0      1      2      3
		{
			for (int j=i+1; j<a.length; j++) //쑝(비교대상 데이터)   -> 1234     234    34      4
			{
				if (a[i]>a[j])    //--오름차순
				//if (a[i]<a[j])    //--내림차순
				{
					//자리 바꾸기
					a[i]=a[i]^a[j];
					a[j]=a[j]^a[i];
					a[i]=a[i]^a[j];
				}
			}
		}

	
		System.out.print("Sorted Data : ");
		/*
		for (int i=0; i<a.length; i++)
			System.out.print(a[i] + " ");
		System.out.println();
		*/
		for (int n: a)
			System.out.print(n + " ");
		System.out.println();
		//--==>> Sorted Data : 12 42 52 60 62
		
		
	}
}
/* 실행 결과
Source Data : 52 42 12 62 60
Sorted Data : 12 42 52 60 62
계속하려면 아무 키나 누르십시오 . . .
*/

▪ 버블 정렬(Bubble Sort) 코드

// 실행 예)
// Source Data : 52 42 12 62 60
// Sorted Data : 12 42 82 60 62
// 계속하려면 아무 키나 누르세요....

public class hyodii104
{
	public static void main(String[] args)
	{
		int[] a = {52,42,12,62,60};

		System.out.print("Source Data : ");
		// 향상된 for 문(forEach 구문)  
		for (int n : a)
			System.out.print(n + " ");
		System.out.println();


		// Bubble Sort
		int i=0;
		for (i=1; i<a.length;i++ )  // 뒤에서 비교 대상을 하나씩 줄여주는 역할
		{
			for (int j=0; j<a.length-i;j++ )   //--check~!! a.length-i
			{
				if (a[j]>a[j+1])
				{
					a[j] = a[j]^a[j+1];
					a[j+1] = a[j+1]^a[j];
					a[j] = a[j]^a[j+1];
				}
			}
		}
		System.out.print("Sorted Data : ");
		for (int n : a )
			System.out.print(n + " ");
		System.out.println();
	}
}

▪ 버블 정렬(Bubble Sort) 코드 설명📝

public class Test104
{
	public static void main(String[] args)
	{
		/* 버블소트는 인접해있는 것들끼리 비교

		42 52 12 62 60     0   1            기준(=) 0 1 2 3
		== --
		42 12 52 62 60     1   2
		   == --
		42 12 52 62 60     2   3
		      == --
		42 12 52 60 62     3   4
		         == --
		-------------------------------------1회전  (가장 큰수 젤 오른쪽fix)
		12 42 52 60 62     0   1             기준(=) 0 1 2 
		== --
		12 42 52 60 62     1   2
		   == --
		12 42 52 60 62     2   3
		      == --
		-------------------------------------2회전  (그래서 2회전때 62까지안감 60까지 자리잡음)
		12 42 52 60 62     0   1             기준(=) 0 1
		== --
		12 42 52 60 62     1   2
		   == --
		-------------------------------------3회전  (52 자리잡음)
		12 42 52 60 62     0   1             기준(=) 0
		== --
		-------------------------------------4회전  (42 자리잡음)
		
		*/
		System.out.print("Source Data : ");
		int[] a = {52, 42, 12, 62, 60};

		for (int n : a)
			System.out.print(n + " ");
		System.out.println();


		// Bubble Sort
		int i=0;
		for (i=1; i<a.length; i++)          // 뒤에서 비교 대상을 하나씩 줄여주는 역할
		{	
			//테스트
			//System.out.print(i + " ");    //--==>> 1 2 3 4
			
			for (int j=0; j<a.length-i;j++)
			{
				if (a[j]>a[j+1])  //인접해 있는 것과 비교니까!
				{
					a[j] = a[j]^a[j+1];
					a[j+1] = a[j+1]^a[j];
					a[j] = a[j]^a[j+1];
				}
			}
		}

		
		System.out.print("Sorted Data : ");
		for (int n : a)
			System.out.print(n + " ");
		System.out.println();

	}
}
/*
Source Data : 52 42 12 62 60
Sorted Data : 12 42 52 60 62
계속하려면 아무 키나 누르십시오 . . .
*/

※ 앞에서 확인해 본 Selection Sort(Test103) 나 Bubble Sort(Test104)의 성능은 같다.

(-> 반복의 횟수로 추정)
하지만, 향상된 Bubble Sort는 대상 데이터의 구조에 따라서
일단 Bubble Sort 나 Selestion Sort 보다 성능이 좋을 수 있다.

다음 포스팅에 이어서..!!

profile
개발새발

0개의 댓글

관련 채용 정보