정렬하기 - 오름차순, 내림차순으로 배열을 정렬

 

정렬의 방법은 여러가지가 있다.

여기서 정렬 알고리즘 두 개를 사용해 볼 것이다.

알고리즘은 나중에 따로 포스팅 할 예정이긴 하지만 여기서 두 가지 소개해 본다.

 

선택정렬과 버블정렬인데, 그 두 가지를 메서드로 구현해 보았다.

 

1. scanArray()

콘솔창에서 배열의 요소를 입력받는 메서드이다.

for문으로 각 배열의 요소를 입력 받는다.

int[] scanArray() {
		int[] arr = new int[5];
		String str = "";
		System.out.println("5개의 숫자를 입력하세요.");
		
		for(int i = 0; i<arr.length; i++) {
			arr[i] = scanner.nextInt();
		}
		
		return arr;
	}
	

 

2. showArray(int[] a)

배열을 보는 것이 잦으므로, 배열을 출력해주는 메서드를 정의했다.

배열이 보기 좋도록 쉼표를 사용하고, 마지막 요소는 쉼표 없이 출력한다.

void showArray(int[] a) {
		for (int i = 0; i<a.length; i++) {
			if(i<a.length-1) {
				System.out.print(a[i]+", ");
			}else {
				System.out.println(a[i]+" ");				
			}

		}
	}

 

3. 선택 정렬

선택정렬은 각 자리에 알맞는 요소를 그 위치로 옮기는 것으로

맨 첫번째 요소의 위치에는 가장 작거나 가장 큰 요소가 오는 것이다.

즉 자리에 맞는 값을 찾아서 그 자리에 넣는다! 는 것이 핵심이다.

 

각 요소 자리에 들어갈 수를 찾기 위해 요소 자리의 요소를 포함한 그 뒤의 모든 요소를 비교하여

알맞는 값을 그 자리에 넣는다.

배열[0]을 먼저 넣고, 그 뒤에 배열[1], [2] 식으로 나아가는데

이미 정렬된 자리의 수는 비교하지 않는 것이 포인트다.

비교하면 당연히 모든 비교연산에서 이미 정렬된 값이 선택되기 마련이다.

 

3-1. upSelectSort(int[] a)

오름차순으로 정렬하는 것이므로

배열의 첫 요소 자리에는 가장 작은 요소가 들어가고

배열의 끝 요소 자리에는 가장 큰 요소가 들어간다.

int[] upSelectSort(int[] a) {
		System.out.println("select 오름차순");
		
		for (int i = 0; i<a.length; i++) {
			int index = i;
			int std = a[i];
			
			for(int j = i ;j<a.length; j++) {
            // 조건식에 맞춰 기준이 되는 값을 기준에 저장하고 그 인덱스를 저장한다
				if(std>a[j]) {
					std = a[j];
					index =	j;
				}
			}
	 		// 배열 요소들을 교환한다.
			int tmp = a[i];
			a[i] = a[index];
			a[index] = tmp;
		}
		return a;
	}
	

  

3-2  downSelectSort(int[] a)

내림차순으로 정렬하는 것이므로

배열의 첫 요소 자리에는 가장 큰 요소가 들어가고

배열의 끝 요소 자리에는 가장 작은 요소가 들어간다.

int[] downSelectSort(int[] a) {
		System.out.println("select 내림차순");
		
		for (int i = 0; i<a.length; i++) {
			int index = i;
			int std = a[i];
			
			for(int j = i ;j<a.length; j++) {
               // 조건식에 맞춰 기준이 되는 값을 기준에 저장하고 그 인덱스를 저장한다
				if(std<a[j]) {
					std = a[j];
					index =	j;
				}
			}
		
        	// 요소를 교환한다
			int tmp = a[i];
			a[i] = a[index];
			a[index] = tmp;
		}
		return a;
	}

 

4. 버블 정렬

버블정렬은 이웃에 위치한 요소끼리 자리를 바꾸는 것으로

앞뒤로 비교하고 교환하며 끝까지 갔다가, 그 것을 요소 수만큼 반복한다

결국 맨 끝자리부터 정렬되서 차례로 채워지므로 비교 교환 후 그 것을 다시 반복해서

뒤에서 차례로 채워야 한다.

즉 비교,교환하는 반복문 하나와 그것을 전체 반복하여 요소수만큼 돌리는 반복문을 중첩시킨다

 

중간에 정렬이 이미 다 되어서 더 이상 반복 정렬하지 않아도 되게끔 만들려면

중간에 더 이상 버블 교환이 일어나지 않는다는 것을 체크할 변수를 하나 설정하면 된다

그 값이 변화하면 반복문을 빠져나오게 하면 된다.

 

나는 그렇게 하진 않았지만 그렇게 하면 수행시간을 줄일 수 있다.

 

4-1 upBubleSort(int[] a)

오름차순 정렬이다.

앞뒤로 교환해 가며 앞보다 큰 요소가 앞 요소랑 위치를 바꿔서 결국은 그 반복문에서 가장 큰 요소가 맨 뒤에 안착한다.

그 것을 요소수만큼 반복해서 자리를 계속 바꿔준다.

int[] upBubleSort(int[] a) {
		System.out.println("buble 오름차순");
		int[] arr = a; 
		for (int i = 1; i<arr.length; i++) {
			for(int j = 1 ;j<arr.length; j++) {
			
				if(arr[j-1]>=arr[j]) {
					int tmp = arr[j-1];
					arr[j-1] = arr[j];
					arr[j] = tmp;
				}
			}
		}
		return arr;
	}

 

4-2 downBubleSort(int[] a)

내림차순 정렬이다.

앞뒤로 교환해 가며 앞보다 작은 요소가 앞 요소랑 위치를 바꿔서 결국은 그 반복문에서 가장 작은 요소가 맨 뒤에 안착한다.

그 것을 요소수만큼 반복해서 자리를 계속 바꿔준다.

	int[] downBubleSort(int[] a) {
		System.out.println("buble 내림차순");
		int[] arr = a; 
		for (int i = 1; i<arr.length; i++) {
			for(int j = 1 ;j<arr.length; j++) {
			
				if(arr[j-1]<=arr[j]) {
					int tmp = arr[j-1];
					arr[j-1] = arr[j];
					arr[j] = tmp;
				}
			}
		}
		return arr;
	}

 

5. main()

	public static void main(String[] args) {
		ArrayPrac_sort sort = new ArrayPrac_sort();
		int[] arr = {5, 34, 26, 20, 3, 7};
			
		sort.showArray(sort.upBubleSort(arr));
		sort.showArray(sort.downBubleSort(arr));
		sort.showArray(sort.upSelectSort(arr));
		sort.showArray(sort.downSelectSort(arr));
		sort.scanner.close();
	}

 

6. 전체 코드

public class ArrayPrac_sort {
/* 정렬하기
 * 오름차순, 내림차순으로 배열을 정렬
 */
	
	Scanner scanner = new Scanner(System.in);

	int[] upSelectSort(int[] a) {
		System.out.println("select 오름차순");
		
		for (int i = 0; i<a.length; i++) {
			int index = i;
			int std = a[i];
			
			for(int j = i ;j<a.length; j++) {
				if(std>a[j]) {
					std = a[j];
					index =	j;
				}
			}
	
			int tmp = a[i];
			a[i] = a[index];
			a[index] = tmp;
		}
		return a;
	}
	
	int[] downSelectSort(int[] a) {
		System.out.println("select 내림차순");
		
		for (int i = 0; i<a.length; i++) {
			int index = i;
			int std = a[i];
			
			for(int j = i ;j<a.length; j++) {
				if(std<a[j]) {
					std = a[j];
					index =	j;
				}
			}
	
			int tmp = a[i];
			a[i] = a[index];
			a[index] = tmp;
		}
		return a;
	}
	
	int[] upBubleSort(int[] a) {
		System.out.println("buble 오름차순");
		int[] arr = a; 
		for (int i = 1; i<arr.length; i++) {
			for(int j = 1 ;j<arr.length; j++) {
			
				if(arr[j-1]>=arr[j]) {
					int tmp = arr[j-1];
					arr[j-1] = arr[j];
					arr[j] = tmp;
				}
			}
		}
		return arr;
	}
	
	int[] downBubleSort(int[] a) {
		System.out.println("buble 내림차순");
		int[] arr = a; 
		for (int i = 1; i<arr.length; i++) {
			for(int j = 1 ;j<arr.length; j++) {
			
				if(arr[j-1]<=arr[j]) {
					int tmp = arr[j-1];
					arr[j-1] = arr[j];
					arr[j] = tmp;
				}
			}
		}
		return arr;
	}
	
	int[] scanArray() {
		int[] arr = new int[5];
		String str = "";
		System.out.println("5개의 숫자를 입력하세요.");
		
		for(int i = 0; i<arr.length; i++) {
			arr[i] = scanner.nextInt();
		}
		
		return arr;
	}
	
	void showArray(int[] a) {
		for (int i = 0; i<a.length; i++) {
			if(i<a.length-1) {
				System.out.print(a[i]+", ");
			}else {
				System.out.println(a[i]+" ");				
			}

		}
	}
	
	public static void main(String[] args) {
		ArrayPrac_sort sort = new ArrayPrac_sort();
		int[] arr = {5, 34, 26, 20, 3, 7};
			
		sort.showArray(sort.upBubleSort(arr));
		sort.showArray(sort.downBubleSort(arr));
		sort.showArray(sort.upSelectSort(arr));
		sort.showArray(sort.downSelectSort(arr));
		sort.scanner.close();
	}
}

 

결과

배열 섞기 - 배열의 요소의 순서를 반복해서 바꾼다(카드 섞기, 로또번호 생성 등)

 

suffle( )

Math클래스의 random 함수로 난수를 발생해 그 값을 저장해서 인덱스로 사용한다.

난수는 0.0 ~ 0.1 사이의 값을 반환하므로 만약 난수 발생 범위가 정해져 있다면

난수 발생 후 범위만큼 곱하면 된다.

ex) 0 ~ 5 사이의 값을 난수로 받고 싶다면

Math.random() *5;

밑의 예시도 배열 크기가 5라서 난수 발생을 5 안으로 조절해서 사용했다.

int[] shuffle() {
		int[] arr = {1, 3, 23, 5, 12};
		String str = "";
		
		for(int i = 0; i< arr.length; i++) {
			double random = Math.random()*5;
            
            // math클래스의 random함수로 난수를 발생시킴
            
			int ran = (int) random;
            
			int tmp = arr[ran];
			arr[ran] = arr[i];
			arr[i]= tmp;
            
            // 난수를 발생시킨 값을 배열 인덱스로 넣어서 아무렇게 섞이도록 함
            
		}
        
		return arr;
	}

 

main ( )

shuffle을 끝내지 않으면 계속 동작하게 하도록 while문을 써서 계속 호출할 수 있도록 하였다.

끝내겠다는 표시인 "q"를 입력하기 전에는 계속 동작하도록 했다.

멈추기 위해서 if문을 두었고 조건은 시그널 값이 비어있으면 계속 shuffle을 호출하므로

엔터를 치면 계속 shuffle()을 호출하며 섞을 것이다.

public static void main(String[] args) {
		ArrayPrac_shuffle ss = new ArrayPrac_shuffle();
		Scanner scanner = new Scanner(System.in);
		
		System.out.println("섞기 : s, 끝내기 : q");
		
		while (true) {
		
			String signal = scanner.nextLine();
			
			if (signal.equals("q")) {
				break;
			} else if(signal.equals("s")) {
				ss.shuffle();
				continue;
			} else {
				System.out.println("잘못 눌렸습니다.");
				continue;
			}
			
		}
		scanner.close();
	}

 

전체 코드

public class ArrayPrac_shuffle {
/*섞기
 * 배열의 요소의 순서를 반복해서 바꾼다(카드 섞기, 로또번호 생성 등)
 */
	
	int[] shuffle() {
		int[] arr = {1, 3, 23, 5, 12};
		String str = "";
		
		for(int i = 0; i< arr.length; i++) {
			double random = Math.random()*5;
			int ran = (int) random;
			int tmp = arr[ran];
			arr[ran] = arr[i];
			arr[i]= tmp;
		}
		for(int i = 0; i< arr.length; i++) {
			if(i<arr.length-1) {
				str += arr[i]+", ";
			}else {
				str += arr[i]+"";
			}
		}
		
		System.out.println(str);
		return arr;
	}
	public static void main(String[] args) {
		ArrayPrac_shuffle ss = new ArrayPrac_shuffle();
		Scanner scanner = new Scanner(System.in);
		
		System.out.println("섞기 : s, 끝내기 : q");
		
		while (true) {
		
			String signal = scanner.nextLine();
			
			if (signal.equals("q")) {
				break;
			} else if(signal.equals("s")) {
				ss.shuffle();
				continue;
			} else {
				System.out.println("잘못 눌렸습니다.");
				continue;
			}
			
		}
		scanner.close();
	}

}

 

결과

최대값과 최소값 찾기 - 배열의 요소 중 제일 큰 값과 제일 작은 값을 찾음

객체 안에 메서드를 정의해서 main클래스에서 호출해 사용할 것이다.

 

Scanner 클래스를 사용할 것이고, 콘솔에서 입력한 값을 배열로 받아서 최대값과 최소값을 구한다.

 

 int( ) 

Scanner scanner = new Scanner(System.in);
	int scan() {
		String str = scanner.next();
		int tmp = Integer.parseInt(str);
		
		return tmp;
	}

클래스의 위에 멤버변수로 Scanner인스턴스를 만들고 스캐너 인스턴스로 받은 모든 값을 int형으로 바꾸는 메서드 int( ) 를 정의했다.

 

findMaxMin()

void findMaxMin() {
		
		int[] arr = new int[5];
		
		System.out.println("5개의 숫자를 입력하세요.");
		for(int i = 0; i<arr.length; i++) {
			arr[i] = scan();
		}
		
        // 값을 입력받고 난 뒤 
        
		int max=arr[0], min=arr[0];
		//최대값과 최소값을 비교하기 위해 변수를 선언한 후 배열의 첫 요소를 저장한다.
        
		for(int i = 0; i<arr.length; i++) {
						
			if (min > arr[i]) {
				min = arr[i];
			}
			if (max < arr[i]) {
				max = arr[i];
			}	
		}
		System.out.println("최대값 : "+max+" 최소값 : "+min);
	}
		

첫 요소를 선택해서 배열의 index가 커지면서 기준값과 배열의 요소값을 비교해

크거나 작으면 각각 max, min에 저장한 뒤 그 것을 반복한다.

for문을 벗어날 때면 i가 배열의 길이만큼 커져서 배열의 모든 숫자를 비교한 것이 된다.

어짜피 비교할 변수가 두개이므로 한방에 구하도록 한 for문 안에 구현했다.

 

전체 코드

public class ArrayPrac_maxmin {
/* 최대값과 최소값
 * 배열의 요소 중 제일 큰 값과 제일 작은 값을 찾음
 */
	Scanner scanner = new Scanner(System.in);
	int scan() {
		String str = scanner.next();
		int tmp = Integer.parseInt(str);
		
		return tmp;
	}
	
	void findMaxMin() {
		
		int[] arr = new int[5];
		
		System.out.println("5개의 숫자를 입력하세요.");
		for(int i = 0; i<arr.length; i++) {
			arr[i] = scan();
		}
		
		int max=arr[0], min=arr[0];
		
		for(int i = 0; i<arr.length; i++) {
						
			if (min > arr[i]) {
				min = arr[i];
			}
			if (max < arr[i]) {
				max = arr[i];
			}	
		}
		System.out.println("최대값 : "+max+" 최소값 : "+min);
	}
		
	
	public static void main(String[] args) {
		ArrayPrac_maxmin mm = new ArrayPrac_maxmin();
		mm.findMaxMin();
		mm.scanner.close();
	}
}

 

결과

07 생성자와 변수의 초기화

생성자

○ 생성자 : 인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드

클래스이름 (타입 변수명, 타입 변수명, …) { }

Test(){ }

Test(int a, String b, bollean c){

this.a = a;

this.b = b;

this.c = c;

}

인스턴스 변수의 초기화 작업에 주요 사용됨

클래스 내에 선언됨

생성자의 조건

(1)   생성자의 이름은 클래스의 이름과 같아야 함

(2)   생성자는 리턴 값이 없음

생성자도 오버로딩이 가능함(매개변수에 차이를 둬서 다르게 인스턴스 생성 가능)

연산자 new로 생성자를 통해 인스턴스를 생성하는 것

Test t = new Test();

(1)   연산자 new에 의해서 메모리(heap) Test클래스의 인스턴스가 생성됨

(2)   생성자 Test()가 호출되어 수행됨

(3)   연산자 new의 결과로, 생성된 Test인스턴스의 주소가 반환되어 참조변수 t에 저장됨

 

○ 기본 생성자

Test () {}

클래스에서 생성자를 정의하지 않고도 인스턴스를 생성할 수 있었던 것!

컴파일러가 기본생성자를 추가해줘서

클래스의 접근 제어자가 public 인 경우 생성자도 public 클래스이름()

기본생성자가 컴파일러에 의해 추가되는 경우는 클래스에 정의된 생성자가 하나도 없을 때!

다른 생성자 있으면 기본생성자 자동으로 추가 안되고

내가 직접 추가해야 됨

○ 매개변수 있는 생성자

Test(int a, String b, bollean c){

a = a;

b = b;

c = c;

}

매개변수 선언해서 호출 시 값을 넘겨받아서 인스턴스 초기화할 수 있음

인스턴스 내의 멤버변수는 접근 가능하니까~ ㅎㅎ

 

○ 생성자에서 다른 생성자 호출하기_this(), this

생성자 간에 서로 호출 가능함! 그 조건

(1)   생성자의 이름으로 클래스이름 대신 this 사용

(2)   한 생성자에서 다른 생성자를 호출할 때 반드시 첫 줄에서만 호출 가능

생성자 내에서 초기화 작업 도중에 다른 생성자 호출하게 되면 다른 생성자 내에서 멤버변수 값을 초기화 할 수 있으니까, 이전 초기화 작업이 무의미해질 수 있음

■ this!

(1)   인스턴스 변수 앞에 붙여주는 this

인스턴스 변수 앞 this : 참조변수. 인스턴스 자신을 가리킴

생성자의 매개변수와 클래스의 멤버변수 이름이 같은 경우 인스턴스 변수를 구별함

인스턴스의 주소가 저장되어 있음

모든 인스턴스 메서드에 지역변수로 숨겨진 채 존재(this를 써 주는 건 명시하는 거네)

□ static메서드는 this 사용할 수 없음

인스턴스 생성하지 않고도 static 메서드는 호출할 수 있으므로!

(2)   this()

□ this(매개변수) 생성자.

같은 클래스의 다른 생성자 호출할 때 사용

                                                           

○ 생성자를 이용한 인스턴스의 복사

Test(Test t){

      a = t.a;

      b = t.b;

      c = t.c;

}

■ Object 클래스의 clone메서드를 이용하면 간단히 인스턴스 복사할 수 있음

 

변수의 초기화

○ 초기화 : 변수를 선언하고 처음으로 값을 저장하는 것

멤버변수는 초기화 하지 않아도 자동적으로 자료형에 맞는 기본값으로 초기화 됨!

지역변수는 자동으로 초기화 안되므로 사용할 때 초기화 해야 됨

멤버변수 초기화 방법

(1)   명시적 초기화

(2)   생성자

(3)   초기화 블록

-      인스턴스 초기화 : 인스턴스 변수 초기화에 사용

-      클래스 초기화 : 클래스변수 초기화에 사용

 

○ 명시적 초기화

변수를 선언과 동시에 초기화 하는 것

복잡한 초기화 작업 필요할 때는 생성자나 초기화 블록 이용

 

○ 초기화 블록

클래스 초기화 블록 : 클래스 변수의 복잡한 초기화에 사용

인스턴스 초기화 블록 앞에 static 붙임

         클래스 초기화 블록은 클래스가 메모리에 처음 로딩

0될 때 한번만 수행됨

인스턴스 초기화 블록 : 인스턴스 변수의 복잡한 초기화에 사용

클래스 내에 블록{ } 만들고 그 안에 코드 작성

인스턴스 생성될 때마다 수행 됨

초기화 블록 내에는 메서드처럼 조건문, 반복문, 예외처리구문 등 자유롭게 사용 가능

초기화 작업이 복잡하여 명시적 초기화로 부족한 경우 초기화 블록 사용

생성자보다 초기화 블록이 먼저 수행됨

인스턴스 변수의 초기화는 주로 생성자를 사용,

인스턴스 초기화 블록은 모든 생성자에서 공통으로 수행되어야 하는 코드 넣는데 사용

 

○ 멤버변수의 초기화 시기와 순서

클래스 변수 초기화 시점 : 클래스가 처음 로딩될 때 단 한번 초기화 됨

인스턴스 변수의 초기화 시점 : 인스턴스가 생성될 때마다 각 인스턴스별로 초기화 이루어짐

클래스 변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 클래스 초기화 블록

인스턴스 변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블록 –> 생성자

클래스 변수는 항상 인스턴스 변수보다 먼저 생성되고 초기화 됨

 

 

'JAVA > 이론' 카테고리의 다른 글

[java][이론] 009 package와 import  (0) 2020.07.06
[java][이론] 008 상속  (0) 2020.07.06
[java][이론] 006 변수와 메서드  (0) 2020.07.02
[java][이론] 005 클래스와 객체  (0) 2020.07.02
[java][이론] 004 배열  (0) 2020.06.29

별 찍기를 해보려 한다.

별 찍기는 이중 for문의 반복연산자를 조정해서 도형을 콘솔에 출력하는 것으로 만든다.

간단한 알고리즘으로 다양하게 응용할 수 있으며

사람마다 찍는 방법이나 사고하는 방법이 다를 수 있다... 나도 왕도가 아니므로

사고 연습하기 좋은 것 같다.

 

메인함수

public static void main(String[] args) {
		
		STAR_01 ss = new STAR_01();
		
		ss.triangle();
		ss.halfTri();
		ss.reverseTri();
		ss.hexagon();
}

총 네 개의 모양을 별로 찍을 것이고,

각각 STAR_01 클래스에서 메서드를 호출해 콘솔에 찍는다.

 

triangle

삼각형이다. 매우 기본적인 도형이다.

꼭지점 좌 우로 한 칸씩 별이 늘어나면 삼각형이 완성이다.

꼭지점을 기준으로 i가 커지면(행이 아래로 내려가면) j가 출력하는 기준도 i에 맞게 변화 시킨다는 것이 포인트다.

void triangle() {
		for(int i = 0 ; i < 5 ; i++) {
			for(int j = 0; j < 9; j++) {
				// 행은 5줄, 열은 9줄
                
				int point = 4; // 중간 점을 찍어줘야 되므로 윗 꼭지점 기준이 됨
                
				if(j >= point-i && j <= point+i) // j의 조건을 i에 맞춰서 설정
                
                // 삼각형은 한 줄이 늘어날 때 마다 중심에서 양 옆으로 하나씩 별이 늘어남
                	System.out.print(" * "); 
                    
				else
                
                // j가 조건이 안 맞으면 공백 출력
					System.out.print("   ");
			}
			System.out.println();
		}
	}

 

halfTri

반쪽짜리 삼각형이다.

꼭지점이 맨 오른쪽에서 시작하는 직각삼각형 모양이라서, 첫 j의 기준점을 맨 오른쪽으로 잡아서

하나씩 앞으로 출력되는 기준을 당긴다.

	void halfTri() {
		for(int i = 0 ; i < 9 ; i++) {
			for(int j = 0; j < 9; j++) {
				
				int point = 8; // 맨 오른쪽이 기준
                
				if(j >= point-i)	
                
                // 8에서 출력 -> 7 8 출력 이런 식으로 첫 출력 번째가 앞으로 당겨짐
					System.out.print(" * ");
				
                else
					System.out.print("   ");
			}
			System.out.println();
		}
	}

 

reverseTri

역삼각형이다.

좀 까다롭기 시작한다.

j가 출력 될 순번을 왼쪽, 오른쪽 다 정해 줘야 한다.

전설 했듯이 j의 값을 i로 계산 하는 것이 효율적이다.

j의 왼쪽은 0 에서 중간으로, j의 오른쪽은 맨 끝에서 중간으로 서로 수렴하게 되어있다.

따라서 한 행씩 내려갈 때마다(i가 커질 때 마다)

j의 왼쪽은 한 칸씩 뒤로 가서 출력하고, j의 오른쪽은 한 칸씩 앞으로 와서 출력이 끝난다.

void reverseTri() {
		for(int i = 0 ; i < 5 ; i++) {
			for(int j = 0; j < 9; j++) {
				
				if(j <= 8-i && j >= i)	
                /* 
                j의 시작은 0 ~ 8 까지 다 출력이므로 
                i가 0이면 저 조건은 j는 8보다 작고 0보다 크면 다 출력이다. 
                i가 1이 되면 j는 1 ~ 7까지 출력하는 것이다.
                */
					System.out.print(" * ");
				else
					System.out.print("   ");
			}
			System.out.println();
		}
	}

 

hexagon

육각형이다.

public static void main(String[] args) {
  
  STAR_01 ss = new STAR_01();
  
//  ss.triangle();
//  ss.halfReverseTri();
//  ss.reverseTri();
  ss.hexagon();
//  ss.star();
 }

중간에 출력 방식이 변화한다.

따라서 구간마다 다른 조건을 넣어줘야 한다.

맨 윗부분은 그냥 삼각형과 같으며 i(행)만 조절해주면 된다.(i범위만 지정하면 된다는 거지)

중간은 걍 다 뽑는거니 쉽고

마지막 역삼각형은 좀 골치가 아프다 ㅎㅎ

void hexagon() {
		for(int i = 0 ; i < 13 ; i++) {
//			System.out.print("i = "+ i);
			
//			if(i >= 8)
//				System.out.printf("i = %d front : %d, end : %d",i,8-(i-8),i-8);
			
			for(int j = 0; j < 9; j++) {
            
				int point = 4; // 그냥 삼각형 뽑을 때의 꼭지점이 되는 기준
                
				if(i <= 3) { // i가 4행까지는 걍 삼각형
					if(j >= point-i && j <= point+i)
						System.out.print(" * ");
					else
						System.out.print("   ");
					
				} else if (i < 3 && i <= 7) { // 5행부터 8행까지는 그냥 네모
					System.out.print(" * ");
					
				} else { // 그 이후의 행은
				
                /*
                i가 0부터 시작하는 것이 아니라 이미 8까지 온 상황이므로
                (i-8)로 i를 0에서부터 시작하는 것 처럼 해줌
                그 후 역삼각형 뽑기
                */
                
					if(j <= 8-(i-8) && j >= i-8) 	
						System.out.print(" * ");
					else
						System.out.print("   ");
				}
			}
			System.out.println();
		}
	}

 

클래스 전체 소스

public class STAR_01 {

	void triangle() {
		for(int i = 0 ; i < 5 ; i++) {
			for(int j = 0; j < 9; j++) {
				
				int point = 4;
				if(j >= point-i && j <= point+i)
					System.out.print(" * ");
				else
					System.out.print("   ");
			}
			System.out.println();
		}
	}
	
	void reverseTri() {
		for(int i = 0 ; i < 5 ; i++) {
			for(int j = 0; j < 9; j++) {
				
				if(j <= 8-i && j >= i)	
					System.out.print(" * ");
				else
					System.out.print("   ");
			}
			System.out.println();
		}
	}
	
	void halfTri() {
		for(int i = 0 ; i < 9 ; i++) {
			for(int j = 0; j < 9; j++) {
				
				int point = 8;
				if(j >= point-i)	
					System.out.print(" * ");
				else
					System.out.print("   ");
			}
			System.out.println();
		}
	}
	
	void hexagon() {
		for(int i = 0 ; i < 13 ; i++) {
			
			for(int j = 0; j < 9; j++) {
				int point = 4;
				if(i <= 3) {
					if(j >= point-i && j <= point+i)
						System.out.print(" * ");
					else
						System.out.print("   ");
					
				} else if (i < 3 && i <= 7) {
					System.out.print(" * ");
					
				} else {
				
					if(j <= 8-(i-8) && j >= i-8)	
						System.out.print(" * ");
					else
						System.out.print("   ");
				}
			}
			System.out.println();
		}
	}
	
	void star() {
		for(int i = 0 ; i < 10 ; i ++) {
			for(int j = 0; j < 9; j++) {
				System.out.print("*");
			}
			System.out.println();
		}
	}
	
	public static void main(String[] args) {
		
		STAR_01 ss = new STAR_01();
		
		ss.triangle();
		System.out.println();
        
		ss.halfTri();
		System.out.println();
        
		ss.reverseTri();
		System.out.println();
        
		ss.hexagon();
		System.out.println();

	}
}

STAR_01의 main 실행 결과

shift를 이용하는 다양한 예제다.

 

TestShift01

32bit(8byte)로 표현한 8의 left shift와 right shift를 알아본다.

여기서 Integer.toBinaryString은 Integer 클래스에 있는 메서드고

String을 반환하는 toBinaryString은 TestShift01 클래스에서 정의한 메서드다.

public class TestShift01 {

	static String toBinaryString(int x) {
		String zero = "00000000000000000000000000000000"; // 32개(32bit표현)
		String tmp = zero + Integer.toBinaryString(x);
		
        // 매개변수 x로 받은 값을 2진법으로 표기한 것을 zero에 붙이고
        
		return tmp.substring(tmp.length()-32);
        
        // 붙인 문자열을 전체 길이 중 32를 뺀 곳에서 부터 자른다.
		
	} 
	public static void main(String[] args) {
		int dec = 8;
		
		System.out.printf("%d >> %d = %4d \t %s\n", dec, 2, dec >> 2, toBinaryString(dec >> 2));
        
        // 우측 시프트 2
        
		System.out.printf("%d << %d = %4d \t %s%n", dec, 1, dec << 1, toBinaryString(dec << 1));
        
        // 좌측 시프트 1
	}
}

TestShift01 결과

TestShift02

앞의 TestShift01에서 toBinaryString메서드를 이용해서

16진수 ABCD의 각 자리 숫자를 추출한다.

&연산은 둘 중 하나라도 0이면 0을 반환하는 논리연산자이므로 1과 &를 했을 때

1이면 1이 반환되고 0이면 0이 반환된다.

만약 00100110과 00001111을 & 하면 앞 4자리는 00001111의 0000떄문에 0이 되고

뒤 4 자리는 00001111의 1111때문에 0110이 된다.

public class TestShift02 {
	public static void main(String[] args) {
		int hex = 0xABCD; // 16진수로 ABCD
		int mask = 0xF; // 2진수로 표시하면 1111이 됨
		
		System.out.printf("hex = %s%n",TestShift01.toBinaryString(hex));
		System.out.printf("mask = %s%n",TestShift01.toBinaryString(mask));
		
        /* 각각 hex = 00000000000000001010101111001101 
       			 mask = 00000000000000000000000000001111로 출력됨 */
		
        // 첫 번째 글자
		System.out.printf("hex = %X%n", hex);
		System.out.printf("hex & mask = %X%n", hex & mask);
		
        hex = hex >> 4; // 우측으로 4비트 이동
        
        // 두 번째 글자
		System.out.printf("hex = %s%n",TestShift01.toBinaryString(hex));
		System.out.printf("hex & mask = %X%n", hex & mask);
		
		hex = hex >> 4; // 우측으로 4비트 이동
        
        // 세 번째 글자
		System.out.printf("hex = %s%n",TestShift01.toBinaryString(hex));
		System.out.printf("hex & mask = %X%n", hex & mask);

		hex = hex >> 4; // 우측으로 4비트 이동
        
        // 네 번째 글자
		System.out.printf("hex = %s%n",TestShift01.toBinaryString(hex));
		System.out.printf("hex & mask = %X%n", hex & mask);
				
	}
}

TestShift02 결과

 

 

 

 

 

 

+ Recent posts