🦔

ITスクール DAY9 今日の曜日with配列/整列アルゴリズム(selection, bubble)

2023/07/18に公開

今日の曜日

以前、配列を使わずに、宿題に挑んだが、先生が配列を使って表現することで方法を教えてくださった。
100ライン以上のコードがとても簡単になる。

BEFORE



public class Weekday2 {
	
    public static void main(String[] args) {
       
    int inputYear = 2023;
    int inputMonth =7;
    int inputDay =15;	
		
    boolean isLeapYear = 
    (inputYear%4==0 && inputYear%100 !=0 || inputYear%400==0);
		
    int howManyLeapYear = 0;
    int howManyComnYear = 0;
		
    int preYearsOfDaysSum = 0;
    int preMonthsOfDaysSum = 0;
    int totalDaysSum =0;
    int whatDayIsToday =0;
		
    String whatDay = "";
		
		
    if(isLeapYear) {
			  
    //평년 및 윤년 횟수
    for(int startYear=1; startYear<inputYear; startYear++) {
				  
    if(startYear%4==0 && startYear%100 !=0 || startYear%400==0) {
	  howManyLeapYear++;
    }else {
     howManyComnYear++;
	}
    }
		  
    //작년까지의 누적 일수
    preYearsOfDaysSum =(366*howManyLeapYear)+(365*howManyComnYear);
				
	      
   //이전 달까지의 누적 일수
   switch(inputMonth) {
	case 1: break;
	case 2: preMonthsOfDaysSum= 31; break;
	case 3: preMonthsOfDaysSum= 60; break; //+29
	case 4: preMonthsOfDaysSum= 91; break;
	case 5: preMonthsOfDaysSum= 121;break;	 
	case 6: preMonthsOfDaysSum= 152;break;
	case 7: preMonthsOfDaysSum= 182;break;
	case 8: preMonthsOfDaysSum= 213;break;
	case 9: preMonthsOfDaysSum= 244;break;
	case 10:preMonthsOfDaysSum= 274;break; 
	case 11:preMonthsOfDaysSum= 305;break;
	case 12:preMonthsOfDaysSum= 335;break;
	}	
		    	      
		      
    //오늘까지의 누적 일수    
    totalDaysSum = preYearsOfDaysSum + preMonthsOfDaysSum + inputDay;
    whatDayIsToday = totalDaysSum%7;
			     
			  
    //누적 일수를 통해 요일 산출 	    
    switch(whatDayIsToday) {
	case 0 : whatDay = "일요일"; break;
	case 1 : whatDay = "월요일"; break;
	case 2 : whatDay = "화요일"; break;
	case 3 : whatDay = "수요일"; break;
	case 4 : whatDay = "목요일"; break;
	case 5 : whatDay = "금요일"; break;
	case 6 : whatDay = "토요일"; break;
      }	  
			     
    System.out.println("평년횟수 : " + howManyComnYear);
    System.out.println("윤년횟수 : " + howManyLeapYear);
    System.out.println("작년까지의 누적일수 : " + preYearsOfDaysSum);
    System.out.println("저번달까지의 누적일수 : " + preMonthsOfDaysSum);
    System.out.println("이번달까지의 일수 : " + inputDay);
    System.out.println("오늘까지의 누적일수 :" + totalDaysSum);
    System.out.printf("윤년 오늘은 %s입니다.\n" , whatDay);
		     
   }//if{}end  : Leap Year
		
		
   else{
			  
   //평년 및 윤년 횟수
   for(int startYear=1; startYear<inputYear; startYear++) {
				  
    if(startYear%4==0 && startYear%100 !=0 || startYear%400==0) {
	  howManyLeapYear++;
    }else {
	  howManyComnYear++;
	 }
				  
     }
		  
   //작년까지의 누적 일수 
   preYearsOfDaysSum =(366*howManyLeapYear)+(365*howManyComnYear);
			
		      
   //이전 달까지의 누적 일수
  switch(inputMonth) {
	case 1: break;
	case 2: preMonthsOfDaysSum= 31; break;
	case 3: preMonthsOfDaysSum= 59; break; //+28
	case 4: preMonthsOfDaysSum= 90; break;
	case 5: preMonthsOfDaysSum= 120;break;	 
	case 6: preMonthsOfDaysSum= 151;break;
	case 7: preMonthsOfDaysSum= 181;break;
	case 8: preMonthsOfDaysSum= 212;break;
	case 9: preMonthsOfDaysSum= 243;break;
	case 10:preMonthsOfDaysSum= 273;break; 
	case 11:preMonthsOfDaysSum= 304;break;
	case 12:preMonthsOfDaysSum= 334;break;
	}	
		      
		    	        
  //오늘까지의 누적 일수    
  totalDaysSum = preYearsOfDaysSum + preMonthsOfDaysSum + inputDay;
  whatDayIsToday = totalDaysSum%7;
			     
			   
  //누적 일수를 통해 요일 산출 	    
	switch(whatDayIsToday) {
	case 0 : whatDay = "일요일"; break;
	case 1 : whatDay = "월요일"; break;
	case 2 : whatDay = "화요일"; break;
	case 3 : whatDay = "수요일"; break;
	case 4 : whatDay = "목요일"; break;
	case 5 : whatDay = "금요일"; break;
	case 6 : whatDay = "토요일"; break;
	}	  
			     
	System.out.println("평년횟수 : " + howManyComnYear);
	System.out.println("윤년횟수 : " + howManyLeapYear);
	System.out.println("작년까지의 누적일수 : " + preYearsOfDaysSum);
	System.out.println("저번달까지의 누적일수 : " + preMonthsOfDaysSum);
	System.out.println("이번달까지의 일수 : " + inputDay);
	System.out.println("오늘까지의 누적일수 :" + totalDaysSum);
	System.out.printf("윤년 오늘은 %s입니다.\n" , whatDay);
			     
	}//else {} end : Common Year
		
    }//main()end
 }//Class end


AFTER

WeekdayArray


int cYear = 2023; int cMonth = 7; int cDay =18;
int hap = 0; //변수 hap : 총날수
		
//(1) 서기 1년 ~ 서기 2022년
for(int y = 1; y < cYear; y++) {
if(y%4 == 0 && y%100 != 0 || y%400==0) {   //y가 윤년이니(판단)?
	hap += 366;
 } else {
	hap += 365;
 }
			
}//for end
		
		
//(2) 2023년(당해년) 1월~12월
          //0월 1월 2월 3월 4월
int[] mon = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 ,31}; 
 if(cYear%4 == 0 && cYear%100 != 0 || cYear%400==0) {//うるう年判断
  mon[2] = 29;
  }
  for(int m = 1; m < cMonth; m++ ) { //2023년의 1월~6월까지의 총날수
  hap +=mon[m];
  }
		
//(3) (해당월) 7월의 날수
hap += cDay;
		
//System.out.println(hap); //738719
switch(hap % 7) {
case 0: System.out.println("일"); break;
case 1: System.out.println("월"); break;
case 2: System.out.println("화"); break;
case 3: System.out.println("수"); break;
case 4: System.out.println("목"); break;
case 5: System.out.println("금"); break;
case 6: System.out.println("토"); break;
}
		

★整列アルゴリズム★

選択ソート(Selection Sort)

int[idx] > int[idx+1] = SWAP


int[] a = { 11, 23, 7, 9, 14 } を昇順に整列してみる。


int[] a = { 11, 23, 7, 9, 14 } 
N = 5 


<N-1回>  = 4回

          i           j
a[0]    a[0] = 11 > a[1]= 23 F   
        a[0] = 11 > a[2]= 7  T -> SWAP!         
        a[0] = 7  > a[3]= 9  F      
        a[0]=  7  > a[4]= 14 F
 
a[0]   =  7
int[]a =  { 7, 23, 11, 9, 14 }


<N-2回>  = 3回
         i            j
a[1]   a[1] = 23 >  a[2] = 11 T -> SWAP!
       a[1] = 11 >  a[3] = 9  T -> SWAP!
       a[1] = 9  >  a[4] = 14 F
             
a[1] = 9
a[2] = 23
a[3] = 11

int[]a =  { 7, 9, 23, 11, 14 }


<N-3回>  = 2回
         i           j
a[2]   a[2] = 23 > a[3] = 11 T  SWAP!
       a[2] = 11 > a[4] = 14 F 

a[2] = 11
a[3] = 23

int[] a =  { 7, 9, 11, 23, 14 }


<N-4回>  = 1回
        i            j
a[3]  a[3]  = 23  >a[4]  =14  T SWAP!

a[3] = 14
a[4] = 23

int[] a = { 7, 9, 11, 14, 23 }


SelectionSort

public class ArraySort {
  public static void main(String[] args) {
		 
		  
		 
// (1) 選択ソート
int[] a = new int[] {11,23,7,9,14};
System.out.println("====整列前====");
		   
for(int idx: a ){
   System.out.printf("%d ", idx);
}
System.out.println();
		   
		   
int loop = a.length - 1 ;
		   
for(int i=0; i< loop; i++){
   for(int j=i+1; j< a.length; j++){
	if(a[i] > a[j]){
	 int temp = a[i];
	 a[i] = a[j]; 
	 a[j] = temp;
       }
   }		        
   System.out.printf("===%d回転後===\n", i+1);   
			     
   for(int k=0; k<a.length; k++ ){	  
      System.out.printf("%d ", a[k]);
      }     
		         
   System.out.println();
  }//for end  
 }
}
====整列前====
11 23 7 9 14 
===1回転後===
7 23 11 9 14 
===2回転後===
7 9 23 11 14 
===3回転後===
7 9 11 23 14 
===4回転後===
7 9 11 14 23 


時間計算量:O(N^2)


https://chanhuiseok.github.io/posts/algo-5/

バブルソート(Bubble Sort)

BubbleSort

public class ArraySort2 {

public static void main(String[] args) {
// (2) バブルソート
nt[] a = new int[] {11,23,7,9,14};
System.out.println("====整列前====");
for(int idx = 0; idx<5; idx++) {
   System.out.printf("%d ", a[idx]);
}
			
for(int i =0; i < 4; i++) {     //総回転数(段階)数, 4段階(0,1,2,3)
   for(int j = 0; j<4-i; j++ ) {//各回転の比較回数 (4->3->2->1) 
	if(a[j] > a[j+1]) {                //前 > 後:  (小->大)
					   //前 < 後 : 降順(大->小)
    //swap	
   int temp = a[j];
   a[j] = a[j+1];
   a[j+1] = temp;
			
   }		 		
 } //(j)for end
System.out.printf("\n==[%d回転語]==\n" , i+1);
	for(int idx = 0; idx<5; idx++) {
	System.out.printf("%d ", a[idx]);
	} 
    } //(i) for end
		
System.out.println();
System.out.println("====整列後====");
for(int idx = 0; idx<5; idx++) {
   System.out.printf("%d ", a[idx]);
	}
			
     }//main	
   
 }//class





時間計算量:O(N^2)


https://chanhuiseok.github.io/posts/algo-5/

====整列前====
11 23 7 9 14 
==[1回転語]==
11 7 9 14 23 
==[2回転語]==
7 9 11 14 23 
==[3回転語]==
7 9 11 14 23 
==[4回転語]==
7 9 11 14 23 
====整列後====
7 9 11 14 23 

配列のコピー

浅いコピー



同じオブジェクトを参照している。
しかし、オブジェクトは一つで、bbが最初に参照した配列aaの要素を変更する可能性もある。

深いコピー

new演算子を使用して、新しいオブジェクトを生成し、for文で要素に代入する。
しかし、基本的にはSystemクラスのarraycopyメソッドを活用することが便利だ。

Discussion