no image
[JAVA] 날짜 계산기 알고리즘
Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다. 2023.01.01을 기준으로 100일 전은2022년 9월 23일(기준날 미포함)이고, 100일 후는2023년 4월 11일이다. 이러한 알고리즘을 자바로 구현하면 아래와 같다. 클래스 선언부 static class YMD { int year; int month; int day; YMD(int y, int m, int d) //생성자 { this.year = y; this.month = m; this.day = d; } int[][] arr = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //평년 arr[0][] {31, 29, 31, 30, 31, 30, 31, 31, 3..
2023.01.26
no image
[JAVA] 한 해의 경과 일 수 / 남은 일 수를 계산하는 알고리즘
Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다. 4월 15일을 예로 들면 그 해의 경과 일수를 구하면 아래와 같다. 1월의 일 수 + 2월의 일 수 + 3월의 일 수 + 15 m월 d일의 그 해 경과 일수는 아래와 같다. 1, 2, ..., m-1월의 일 수의 합 + d 그런데 2월의 일 수는 평년은 28일, 윤년은 29일로 해에 따라 달라진다. 윤년, 평년 지구가 태양 둘레를 한 바퀴 도는 일수는 정확히 365일이 아니다. 이를 조정하기 위해 4로 나누어 떨어지는 해를 윤년으로 하여 1년을 366일로 한다. 하지만 그래도 정확하기 않으므로 아래와 같은 규칙을 적용한다. -해당 연도를 4로 나누어 떨어지면 우선 윤년으로 하고 -윤년 중에서 100으로 나누어 떨어지면 ..
2023.01.25
no image
[JAVA] n이하의 소수를 구하는 알고리즘
Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다. 소수 소수는 자신과 1 이외의 정수로 나누어떨어지지 않는 정수이다. 예를 들어 소수 13은 2, 3, ..., 12 가운데 어떤 정수로도 나누어 떨어지지 않는다 그러므로 어떤 정수 n에 대하여 아래의 조건을 만족하면 소수임을 알 수 있다. "소수 n은 2부터 n-1까지의 어떤 정수로도 나누어 떨어지지 않는다." 만약 나누어 떨어지는 정수가 하나 이상 존재하면 그 수는 합성수이다. n 이하의 소수를 나열하는 알고리즘 (시간복잡도 높음, 공간복잡도 낮음) static void PrimeNumber(int n) { for(int i = 2; i
2023.01.24
no image
[JAVA] n진수 변환 알고리즘
Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다. 10진수를 n진수로 변환하는 방법을 모른다면 아래의 포스팅에서[10진수-n진수 변환] 부분을 읽고 오시는 것을 추천합니다. 2022.11.29 - [Math/이산수학] - 진수, 진법 변환, 보수 진수, 진법 변환, 보수 [진수] [10진수] 기수가 10인 수 0, 1, 2 ,3, 4, 5, 6 ,7, 8, 9 -> 10개 수로 표현 [2진수] 기수가 2인 수 0, 1 두개의 수로 표현 [8진수와 16진수] [8진수] 0~7까지 8개의 수로 표현 2진수 3자리는 8진수 1자리 2진수 rebugs.tistory.com 10진수를 2~36진수로 변환하는 알고리즘 static void cardConvR(int x, int r..
2023.01.23
no image
[JAVA] 배열 비교, 복사, 역순으로 복사 알고리즘
Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다. 배열 비교 두 배열의 모든 요소의 값이 같은지를 판단하는 알고리즘 static boolean equals(int[] a, int[] b) { if(a.length != b.length) return false; //배열의 길이가 다르면 false 리턴 for(int i = 0; i < a.length; ++i) if(a[i] != b[i]) return false; //요소의 값이 다르면 false 리턴 return true; //배열의 길이가 같고, 모든 요소의 값이 같으면 true 리턴 } 아래는 실행예제 public class Main{ static boolean equals(int[] a, int[] b) { i..
2023.01.22
no image
[JAVA] 배열 요소를 역순으로 정렬하는 알고리즘
Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다. 배열의 요소가 1, 2, 3, 4, 5, 6, 7 이렇게 7개 있다고 하면 역순으로 정렬하면 7, 6, 5, 4, 3, 2, 1이다. 그림에서 보는 것과 같이 요소들을 서로 바꿔주면 된다. 요소들을 바꿔주려면 먼저 swap함수를 정의해야한다. static void swap(int[] arr, int a, int b) //배열의 요소 값을 스왑 { int temp; temp = arr[a]; arr[a]= arr[b]; arr[b] = temp; } 매개변수 a와 b에 교환할 배열의 인덱스를 받고, 인덱스 a의 값과 인덱스 b의 값을 바꾼다.(swap) 이 swap 메소드를 응용해서 요소를 역순으로 정렬하는 알고리즘을 구..
2023.01.21
no image
[JAVA] n개의 데이터 최댓값 구하기(난수 사용)
Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다. 배열, 난수 사용, 최댓값 구하기 n명의 사람 수를 받아오고, 랜덤으로 사람키를 지정해서 최댓값 출력 import java.util.Random; import java.util.Scanner; public class Main{ static int maxOf(int[] a) { int max = a[0]; for (int i = 1; i max) max = a[i]; return max; } public static void main(String[] args) { Random rand = new Random(); Scanner stdIn = new Scanner(Syste..
2023.01.20
no image
[JAVA] 다중루프(중첩 for문) - 곱셈표, 도형, 피라미드
Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다. 곱셈표 일반 곱셈표 public class Test{ public static void main(String[] args) { for(int i = 1; i1) {System.out.printf("%3d", (i-1)+(j-1));} } System.out.println(); } } } /* | 1 2 3 4 5 6 7 8 9 ---+--------------------------- 1| 2 3 4 5 6 7 8 9 10 2| 3 4 5 6 7 8 9 10 11 3| 4 5 6 7 8 9 10 11 12 4| 5 6 7 8 9 10 11 12 13 5| 6 7 8 9 10 11 12 13 14 6| 7 8 9 10 11..
2023.01.19

Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다.


2023.01.01을 기준으로 100일 전은2022년 9월 23일(기준날 미포함)이고,

100일 후는2023년 4월 11일이다.

이러한 알고리즘을 자바로 구현하면 아래와 같다.

클래스 선언부

static class YMD { 
		int year;
		int month;
		int day;

		YMD(int y, int m, int d) //생성자
		{
			this.year = y;
			this.month = m;
			this.day = d;
		}
		
		int[][] arr = {
		        {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //평년 arr[0][]
		        {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} //윤년 arr[1][]
		};
	
		static int isLeap(int year) { //윤년이면 1을 리턴, 평년이면 0을 리턴
			return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 1 : 0;
		}
		
		YMD after(int n) //n일 후 날짜를 리턴하는 메소드
		{
			YMD temp = new YMD(this.year, this.month, this.day);
			if (n < 0)
				return (before(-n));

			temp.day += n;

			while (temp.day > arr[isLeap(temp.year)][temp.month - 1]) {
				temp.day -= arr[isLeap(temp.year)][temp.month - 1];
				if (++temp.month > 12) {
					temp.year++;
					temp.month = 1;
				}
			}
			return temp;
		}
		
		YMD before(int n) //n일 전 날짜를 리턴하는 메소드
		{
			YMD temp = new YMD(this.year, this.month, this.day);
			if (n < 0)
				return (after(-n));

			temp.day -= n;

			while (temp.day < 1) {
				if (--temp.month < 1) {
					temp.year--;
					temp.month = 12;
				}
				temp.day += arr[isLeap(temp.year)][temp.month - 1];
			}
			return temp;
		}
	}

 

실행예제

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    System.out.print("날짜를 입력하세요. 입력 예 : 2023 1 18\n");
    int y, m, d;
    y = sc.nextInt();
    m = sc.nextInt();
    d = sc.nextInt();
    YMD date = new YMD(y, m, d);

    System.out.print("몇 일 앞/뒤의 날짜를 구할까요?:");
    int n = sc.nextInt();

    YMD d1 = date.after(n);
    System.out.printf("%d일 뒤의 날짜는 %d년 %d월 %d일입니다.\n", n, d1.year, d1.month, d1.day);

    YMD d2 = date.before(n);
    System.out.printf("%d일 앞의 날짜는 %d년 %d월 %d일입니다.\n", n, d2.year, d2.month, d2.day);
}
/*
날짜를 입력하세요. 입력 예 : 2023 1 18
2023 1 18
몇 일 앞/뒤의 날짜를 구할까요?:1000
1000일 뒤의 날짜는 2025년 10월 14일입니다.
1000일 앞의 날짜는 2020년 4월 23일입니다.
*/

네이버 날짜 계산기는 기준일을 1일로 치지만 위 알고리즘은 기준일을 0일로 삼는다.

네이버는 내일을 2일째 되는날이라고 하지만, 위 알고리즘은 1일째 되는날이라고 한다.

설명
arr의 행에 오는 isLeap()메소드는 temp의 연도가 윤년이면 1, 평년이면 0을 리턴한다.
열에오는 temp의 month에 -1을 한 이유는 배열의 인덱스는 0부터 시작하기 때문이다.
2023.01.18에 1000일을 한 temp객체는 초기에 2023.01.1018로 되어있다.
while루프는 temp의 day가 달의 일수보다 같거나 작을 때 까지 반복한다.
day는 루프를 돌면서 계속 달의 일수만큼 감소된다.
달의 일수가 감소할 때, 달은 계속 증가하게 되고, 달이 12를 넘어가면 연도를 +1해준다.

2024년은 윤년이므로 2월이 29일 인 것을 볼 수 있다.

 

 

Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다.


4월 15일을 예로 들면 그 해의 경과 일수를 구하면 아래와 같다.

  • 1월의 일 수 + 2월의 일 수 + 3월의 일 수 + 15

m월 d일의 그 해 경과 일수는 아래와 같다.

  • 1, 2, ..., m-1월의 일 수의 합 + d

그런데 2월의 일 수는 평년은 28일, 윤년은 29일로 해에 따라 달라진다.

윤년, 평년
지구가 태양 둘레를 한 바퀴 도는 일수는 정확히 365일이 아니다.
이를 조정하기 위해 4로 나누어 떨어지는 해를 윤년으로 하여 1년을 366일로 한다.
하지만 그래도 정확하기 않으므로 아래와 같은 규칙을 적용한다.
-해당 연도를 4로 나누어 떨어지면 우선 윤년으로 하고
-윤년 중에서 100으로 나누어 떨어지면 다시 평년으로 한다.
-하지만 평년 중에서 400으로 나누어 떨어지면 다시 윤년으로 한다.

윤년인지 평년인지 구분하는 조건문은 아래와 같다.
if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0) //이 조건식이 참이면 윤년이다.

else //위 조건식이 참이 아니면 평년이다.​

 

int[][] arr = {
        {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //평년 arr[0][]
        {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} //윤년 arr[1][]
};

평년이면 위 코드처럼 2차원 배열을 선언하고 arr[0][]을 이용하고, 윤년이면 arr[1][]을 이용하면 된다.

 

한 해의 경과일 수를 계산하는 알고리즘

static int dayOfYear(int y, int m, int d)
{
    int[][] arr = {
            {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
            {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };
    int days = d;
    if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0) for(int i = 1; i < m; ++i) days += arr[1][i-1]; //윤년일 때
    else for(int i = 1; i < m; ++i) days += arr[0][i-1]; //평년일 때

    return days;
}

 

실행 예제

public class Main{
	static int dayOfYear(int y, int m, int d)
	{
		int[][] arr = {
				{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
				{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
		};
		int days = d;
		if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0) for(int i = 1; i < m; ++i) days += arr[1][i-1]; //윤년일 때
		else for(int i = 1; i < m; ++i) days += arr[0][i-1]; //평년일 때
		
		return days;
	}
	public static void main(String[] args) {
		System.out.println(dayOfYear(2022, 3, 1)); //평년
		System.out.println(dayOfYear(2023, 3, 1)); //평년
		System.out.println(dayOfYear(2024, 3, 1)); //윤년
	}
}
/*
60
60
61
*/

 

while문으로 작성

while 문으로 변수 i와 days 없이 구현

static int dayOfYear(int y, int m, int d)
{
    int[][] arr = {
            {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
            {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };

    if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0) while(--m != 0) d += arr[1][m-1];
    else while(--m != 0) d += arr[0][m-1];

    return d;
}

 

 

한 해의 남은 일 수를 계산하는 알고리즘

경과한 일 수를 구할 수 있다면 남은 일 수를 계산하는 것은 간단하다.

  • 윤년이면 366일에서 경과일 수를 빼준다.
  • 평년이면 365일에서 경과일 수를 빼준다.
static int leftDayOfYear(int y, int m, int d)
{
    int[][] arr = {
            {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
            {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };
    int days = d;
    if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0) //윤년일 때
    {
        for(int i = 1; i < m; ++i) days += arr[1][i-1];
        return 366 - days;
    }
    else //평년일 때
    {
        for(int i = 1; i < m; ++i) days += arr[0][i-1];
        return 365 - days;
    }
}

 

실행 예제

public class Main{
	static int leftDayOfYear(int y, int m, int d)
	{
	    int[][] arr = {
	            {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
	            {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
	    };
	    int days = d;
	    if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0) //윤년일 때
	    {
	    	for(int i = 1; i < m; ++i) days += arr[1][i-1];
	    	return 366 - days;
	    }
	    else //평년일 때
	    {
	    	for(int i = 1; i < m; ++i) days += arr[0][i-1];
	    	return 365 - days;
	    }
	}
	public static void main(String[] args) {
		System.out.println(leftDayOfYear(2022, 2, 28)); //평년
		System.out.println(leftDayOfYear(2023, 2, 28)); //평년
		System.out.println(leftDayOfYear(2024, 2, 28)); //윤년
	}
}
/*
306
306
307
*/

Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다.


소수
소수는 자신과 1 이외의 정수로 나누어떨어지지 않는 정수이다.
예를 들어 소수 13은 2, 3, ..., 12 가운데 어떤 정수로도 나누어 떨어지지 않는다
그러므로 어떤 정수 n에 대하여 아래의 조건을 만족하면 소수임을 알 수 있다.
"소수 n은 2부터 n-1까지의 어떤 정수로도 나누어 떨어지지 않는다."
만약 나누어 떨어지는 정수가 하나 이상 존재하면 그 수는 합성수이다.

 

n 이하의 소수를 나열하는 알고리즘 (시간복잡도 높음, 공간복잡도 낮음)

static void PrimeNumber(int n)
{
    for(int i = 2; i <= n; ++i)
    {
        for(int j = 2; j <= i; ++j)
        {
            if(i == j) System.out.println(i);
            if(i % j == 0) break;
        }
    }
}
설명
바깥쪽 루프는 2부터 n까지 반복을 하고, 안쪽 루프는 2부터 i까지 반복한다.
i와 j가 같다면(안쪽 루프와 바깥쪽 루프를 모두 돌았다면) 소수인 것이므로 출력한다.
i를 j로 나눈 나머지가 0이라면 소수가 아니므로 루프(안쪽)를 탈출한다.

 

실행 예제

public class Main{
	static void PrimeNumber(int n)
	{
		for(int i = 2; i <= n; ++i)
		{
			for(int j = 2; j <= i; ++j)
			{
				if(i == j) System.out.println(i);
				if(i % j == 0) break;
			}
		}
	}
	public static void main(String[] args) {
		PrimeNumber(55);
	}
}
/*
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
*/

 

 

알고리즘 개선1 (시간복잡도 중간, 공간복잡도 높음)

처음 제시한 알고리즘은 불필요한 연산을 하고 있다.

어떤 수가 2 또는 3으로 나누어 떨어지지 않으면 2X2인 4 또는 2X3인 6으로도 나누어 떨어지지 않는다.

따라서 어떤 수가 소수인지 여부는 아래의 조건을 만족하는지 조사하면 된다.

"소수 n은 2부터 n-1까지 어떤 소수로도 나누어 떨어지지 않는다."

예를 들어 7이 소수인지는 7보다 작은 소수(2, 3, 5)로 나눗셈을 하면 충분하다. 이렇게 하면 성능을 향상할 수 있다.

static void PrimeNumber(int n)
{
    int []arr = new int[n]; //소수를 저장하기 위한 배열을 동적할당
    int count = 0; //소수의 개수를 저장
    arr[count++] = 2; //arr[0]에 2를 저장하고 count를 +1 증가시킴
    for(int i = 3; i <= n; i += 2) //짝수는 검사하지 않음
    {
        int j;
        for(j = 1; j < count; ++j) if(i % arr[j] == 0) break;
        if(j == count) arr[count++] = i;
    }
    for(int i = 0; i < count; ++i) System.out.println(arr[i]);
}
설명
2는 소수이므로 arr[0]에는 2를 넣고
바깥 루프는 3부터 n까지 반복을 진행하고, 안쪽 루프는 1부터 count -1까지 반복한다.
안쪽 루프에서 i를 arr[j]로 나누고 나머지가 0이면 루프를 탈출한다.
안쪽 루프를 다 돌고 j와 count가 같다면 arr[count]에 i를 대입한다.


위 알고리즘은 시간복잡도는 감소하지만, 공간복잡도는 증가한다. (연산횟수는 감소하지만, 메모리 사용량은 증가한다)

 

실행예제

public class Main{
	static void PrimeNumber(int n)
	{
		int []arr = new int[n]; //소수를 저장하기 위한 배열을 동적할당
		int count = 0; //소수의 개수를 저장
		arr[count++] = 2; //arr[0]에 2를 저장하고 count를 +1 증가시킴
		for(int i = 3; i <= n; i += 2) //짝수는 검사하지 않음
		{
			int j;
			for(j = 1; j < count; ++j) if(i % arr[j] == 0) break;
			if(j == count) arr[count++] = i;
		}
		for(int i = 0; i < count; ++i) System.out.println(arr[i]);
	}
	public static void main(String[] args) {
		PrimeNumber(55);
	}
}
/*
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
*/

 

알고리즘 개선2 (시간복잡도 낮음, 공간복잡도 높음)

100의 약수를 구하는 과정은 아래와 같다.

  • 2 X 50
  • 4 X 25
  • 5 X 20
  • 10 X 10
  • 20 X 5
  • 25 X 4
  • 50 X 2

10 X 10을 기준으로 위아래는 똑같다.

기준을 잡고 기준을 포함해서 위나 아래만 하나를 골라서 소수로 나눗셈을 시도하고, 그 과정에서 한 번도 나누어 떨어지지 않으면 소수라고 판단한다는 것이다.

(예를 들어 100이 5로 나누어떨어지지 않는다면 20으로도 나눠어 떨어지지 않는다.)

따라서 어떤 수가 소수인지 여부는 아래의 조건을 만족하는지 조사하면 된다.

"소수 n은 n의 제곱근 이하의 어떤 소수로도 나누어 떨어지지 않는다."

static void PrimeNumber(int k)
{
    int count = 0;
    int[] arr = new int[k];

    arr[count++] = 2;
    arr[count++] = 3;

    for (int i = 5 ; i <= k; i += 2) {
        boolean flag = false;
        for (int j = 1; arr[j] * arr[j] <= i; j++) {
            if (i % arr[j] == 0) flag = true; break;
        }
        if (!flag) arr[count++] = i;
    }
    for (int i = 0; i < count; i++)System.out.println(arr[i]);
}

 

실행예제

public class Main{
	static void PrimeNumber(int k)
	{
		int count = 0;
		int[] arr = new int[k];

		arr[count++] = 2;
		arr[count++] = 3;

		for (int i = 5 ; i <= k; i += 2) {
			boolean flag = false;
			for (int j = 1; arr[j] * arr[j] <= i; j++) {
				if (i % arr[j] == 0) flag = true; break;
			}
			if (!flag) arr[count++] = i;
		}
		for (int i = 0; i < count; i++)System.out.println(arr[i]);
	}
	public static void main(String[] args) {
		PrimeNumber(1000);
	}
}
/*
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
*/

 

첫번째 알고리즘의 연산 횟수는 78022

두 번째 알고리즘의 연산 횟수는 14622

세 번째 알고리즘의 연산 횟수는 3774

Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다.

 

10진수를 n진수로 변환하는 방법을 모른다면 아래의 포스팅에서[10진수-n진수 변환] 부분을 읽고 오시는 것을 추천합니다.

2022.11.29 - [Math/이산수학] - 진수, 진법 변환, 보수

 

진수, 진법 변환, 보수

[진수] [10진수] 기수가 10인 수 0, 1, 2 ,3, 4, 5, 6 ,7, 8, 9 -> 10개 수로 표현 [2진수] 기수가 2인 수 0, 1 두개의 수로 표현 [8진수와 16진수] [8진수] 0~7까지 8개의 수로 표현 2진수 3자리는 8진수 1자리 2진수

rebugs.tistory.com


10진수를 2~36진수로 변환하는 알고리즘

static void cardConvR(int x, int r)
{
    char []d = new char[32];
    int digits = 0; //변환된 진수의 자릿수를 저장
    String dchar = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    do {
        d[digits++] = dchar.charAt(x % r); // r로 나눈 나머지를 저장
        x /= r;
    } while (x != 0);
    for(int i = digits-1; i>=0; i--) System.out.print(d[i]);
}
설명
위와 같은 결과로 이루어진 배열을 역순으로 출력하면
진수변환이 되는 것이다.
문자 추출 charAt() 메소드
charAt() 메소드는 매개값으로 주어진 인덱스의 문자를 리턴한다.
dchar.charAt(x % r)에서 x는 59 r이 16이라고 가정하면 59를 16로 나눈 후 나머지는 11이다
dchar배열의 인덱스 11은 B이므로 B가 리턴된다.

 

실행 예제

import java.util.Scanner;
public class Main{
	static void cardConvR(int x, int r)
	{
	    char []d = new char[32];
	    int digits = 0; //변환된 진수의 자릿수를 저장
	    String dchar = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	    do {
	        d[digits++] = dchar.charAt(x % r); // r로 나눈 나머지를 저장
	        x /= r;
	    } while (x != 0);
	    for(int i = digits-1; i>=0; i--) System.out.print(d[i]);
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.print("변환할 정수 입력 : ");
		int num = sc.nextInt();
		System.out.print("진수 입력 : ");
		int n = sc.nextInt();
		cardConvR(num,n);
	}
}
/*
변환할 정수 입력 : 59
진수 입력 : 2
111011
*/

 

 

자세한 계산과정을 출력하는 알고리즘

static void cardConvR(int x, int r)
{
    char []d = new char[32];
    int digits = 0; //변환된 진수의 자릿수를 저장
    String dchar = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    System.out.printf("%2d | %6d\n",r,x);
    System.out.println("   + -------");
    do {
        d[digits++] = dchar.charAt(x % r); // r로 나눈 나머지를 저장
        if((x/r) == 0) System.out.printf("     %6d ... %2c\n", x/r, dchar.charAt(x % r));
        else System.out.printf("%2d | %6d ... %2c\n", r, x/r, dchar.charAt(x % r));
        x /= r;
        if(x != 0) System.out.println("   + -------");

    } while (x != 0);
    System.out.print("변환된 값 : ");
    for(int i = digits-1; i>=0; i--) System.out.print(d[i]);
}

 

실행예제

import java.util.Scanner;
public class Main{
	 static void cardConvR(int x, int r)
    {
        char []d = new char[32];
        int digits = 0; //변환된 진수의 자릿수를 저장
        String dchar = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        System.out.printf("%2d | %6d\n",r,x);
        System.out.println("   + -------");
        do {
            d[digits++] = dchar.charAt(x % r); // r로 나눈 나머지를 저장
            if((x/r) == 0) System.out.printf("     %6d ... %2c\n", x/r, dchar.charAt(x % r));
            else System.out.printf("%2d | %6d ... %2c\n", r, x/r, dchar.charAt(x % r));
            x /= r;
            if(x != 0) System.out.println("   + -------");

        } while (x != 0);
        System.out.print("변환된 값 : ");
        for(int i = digits-1; i>=0; i--) System.out.print(d[i]);
    }
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.print("변환할 정수 입력 : ");
		int num = sc.nextInt();
		System.out.print("진수 입력 : ");
		int n = sc.nextInt();
		cardConvR(num,n);
	}
}
/*
변환할 정수 입력 : 59
진수 입력 : 8
 8 |     59
   + -------
 8 |      7 ...  3
   + -------
          0 ...  7
변환된 값 : 73
*/

Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다.


배열 비교

두 배열의 모든 요소의 값이 같은지를 판단하는 알고리즘

static boolean equals(int[] a, int[] b)
	{
		if(a.length != b.length) return false; //배열의 길이가 다르면 false 리턴
		
		for(int i = 0; i < a.length; ++i) if(a[i] != b[i]) return false; //요소의 값이 다르면 false 리턴
		
		return true; //배열의 길이가 같고, 모든 요소의 값이 같으면 true 리턴
	}

 

아래는 실행예제

public class Main{
	static boolean equals(int[] a, int[] b)
	{
		if(a.length != b.length) return false; //배열의 길이가 다르면 false 리턴
		
		for(int i = 0; i < a.length; ++i) if(a[i] != b[i]) return false; //요소의 값이 다르면 false 리턴
		
		return true; //배열의 길이가 같고, 모든 요소의 값이 같으면 true 리턴
	}
	
	public static void main(String[] args) {
		int[] array = {1,2,3,4,5,6,7};
		int[] array2 = {1,2,3,4,5,6};
		int[] array3 = {2,5,3,6,7,7,8};
		int[] array4 = {1,2,3,4,5,6,7};
		
		System.out.println(equals(array, array2));
		System.out.println(equals(array, array3));
		System.out.println(equals(array, array4));
		
	}
}
/*
false
false
true
*/

 

 

배열 복사

배열 a와 b를 매개값으로 받아서 배열b의 요소를 a배열로 복사하는 메소드를 작성

static void copy(int[] a, int[] b)
	{
		if(a.length < b.length) //b의 길이가 a보다 크면
		{
			System.out.println("배열의 길이가 모자릅니다.");
			return;
		}
		for(int i = 0; i < b.length; ++i) a[i] = b[i]; //배열 요소 복사
	}
아래의 코드는 a배열의 길이가 더 작아도 작은 길이 만큼만 복사하는 알고리즘
static void copy(int[] a, int[] b)
	{
		int num = a.length <= b.length ? a.length : b.length;
		for (int i = 0; i < num; i++) a[i] = b[i];
	}​

 

실행 예제

public class Main{
	static void copy(int[] a, int[] b)
	{
		if(a.length < b.length) //b의 길이가 a보다 크면
		{
			System.out.println("배열의 길이가 모자릅니다.");
			return;
		}
		for(int i = 0; i < b.length; ++i) a[i] = b[i]; //배열 요소 복사
	}
	static void printArray(int[] array) //배열 요소 출력
	{
		for(int i = 0; i < array.length; ++i)
		{
			if(i == array.length-1) {System.out.println(array[i]); break;}
			System.out.print(array[i] + ", ");
		}
	}
	
	public static void main(String[] args) {
		int[] array = {5,3,32,9,6,3,8};
		int[] array2 = {1,2,3,4,5,6,7};
		
		printArray(array);
		copy(array,array2); //array2를 array에 복사
		printArray(array);
	}
}
/*
5, 3, 32, 9, 6, 3, 8
1, 2, 3, 4, 5, 6, 7
*/

 

 

배열 역순으로 복사

배열 a와 b를 매개값으로 받아서 배열 b의 요소를 a배열로 역순으로 복사하는 메소드를 작성

static void rcopy(int[] a, int[] b)
	{
		if(a.length < b.length) //배열 b의 길이가 더 크면
		{
			System.out.println("배열의 길이가 모자릅니다.");
			return;
		}
		for(int i = 0; i < b.length; ++i) a[i] = b[b.length-i -1]; //배열 요소 복사
	}
아래의 코드는 a배열의 길이가 더 작아도 작은 길이 만큼만 복사하는 알고리즘
static void rcopy(int[] a, int[] b) {
		int num = a.length <= b.length ? a.length : b.length;
		for (int i = 0; i < num; i++)a[i] = b[b.length - i - 1];
	}​

 

실행예제

public class Main{
	static void rcopy(int[] a, int[] b)
	{
		if(a.length < b.length) //배열의 길이가 서로 다르면
		{
			System.out.println("배열의 길이가 모자릅니다.");
			return;
		}
		for(int i = 0; i < b.length; ++i) a[i] = b[b.length-i -1]; //배열 요소 복사
	}
	static void printArray(int[] array) //배열 요소 출력
	{
		for(int i = 0; i < array.length; ++i)
		{
			if(i == array.length-1) {System.out.println(array[i]); break;}
			System.out.print(array[i] + ", ");
		}
	}
	
	public static void main(String[] args) {
		int[] array = {1,2,3,4,5,6,7};
		int[] array2 = {10,11,12,13,14,15,16};
		
		printArray(array);
		rcopy(array,array2);
		printArray(array);
	}
}
/*
1, 2, 3, 4, 5, 6, 7
16, 15, 14, 13, 12, 11, 10
*/

 

위 알고리즘이 이해가 안간다면 아래의 글을 읽는 것을 추천합니다.

2023.01.21 - [Data Structure & Algorithm] - [JAVA] 배열 요소를 역순으로 정렬하는 알고리즘

Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다.


배열의 요소가 1, 2, 3, 4, 5, 6, 7 이렇게 7개 있다고 하면 역순으로 정렬하면 7, 6, 5, 4, 3, 2, 1이다.

 

 

그림에서 보는 것과 같이 요소들을 서로 바꿔주면 된다.

요소들을 바꿔주려면 먼저 swap함수를 정의해야한다.

static void swap(int[] arr, int a, int b) //배열의 요소 값을 스왑
	{
		int temp;
		temp = arr[a];
		arr[a]= arr[b];
		arr[b] = temp;
	}

매개변수 a와 b에 교환할 배열의 인덱스를 받고, 인덱스 a의 값과 인덱스 b의 값을 바꾼다.(swap)

 

이 swap 메소드를 응용해서 요소를 역순으로 정렬하는 알고리즘을 구현할 수 있다.

static void reverseArray(int[] arr) //배열 요소를 역순으로 정렬
	{
		for(int i = 0; i < arr.length/2; ++i)
		{
			swap(arr, i, arr.length - i-1);
		}
	}

arr.length(배열의 길이)가 홀수여도 상관없다. arr.length가 7이라고 가정하면 arr.length / 2 는 3이기 때문이다.(i는 int형 타입이기 때문에 3.5가 아니다.)

(arr.length(배열의 길이)가 짝수면 당연히 상관없음)

0부터 arr.length까지 반복을 진행하고, swap 메소드의 매개값에 배열, i, arr.length -i -1을 넘겨준다.

왜 이러한 매개값을 넘기는지는 아래와 같다.

  • 배열(arr) : 매개값으로 참조된 배열의 값을 정렬하기 위해
  • i : 배열(arr)의 i번째 인덱스의 값과 arr.length- i -1번째 인덱스의 값을 바꾸기 위해
  • arr.length -i -1 : 위와 동일

배열의 인덱스는 0부터 시작함을 염두하고 잘 생각해 보면 이해가 될 것이다.

 

위의 swap메소드와 reverseArray메소드를 합치면 아래와 같다.

static void reverseArray(int[] arr) //배열 요소를 역순으로 정렬
{
    for(int i = 0; i < arr.length/2; ++i)
    {
        int temp = arr[i];
        arr[i]= arr[arr.length - i-1];
        arr[arr.length - i-1] = temp;
    }
}

 

아래의 코드는 실행 예제이다.

public class Main{
	static void reverseArray(int[] arr) //배열 요소를 역순으로 정렬
	{
			
		for(int i = 0; i < arr.length/2; ++i)
		{
			int temp = arr[i];
			arr[i]= arr[arr.length - i-1];
			arr[arr.length - i-1] = temp;
		}
	}
	
	static void printArray(int[] array) //배열 요소 출력
	{
		for(int i = 0; i < array.length; ++i)
		{
			if(i == array.length-1) {System.out.println(array[i]); break;}
			System.out.print(array[i] + ", ");
		}
	}
	
	public static void main(String[] args) {
		int[] array = {1,2,3,4,5,6,7};
		printArray(array);
		reverseArray(array);
		printArray(array);
	}
}
/*
1, 2, 3, 4, 5, 6, 7
7, 6, 5, 4, 3, 2, 1
*/

 

좀 더 자세히 스왑과정을 보여주는 예제
public class Main{
	static void swap(int[] arr, int a, int b) //배열의 요소 값을 스왑
	{
		int temp;
		temp = arr[a];
		arr[a]= arr[b];
		arr[b] = temp;
		System.out.println("Index " + a + "와(과) " + b + "를 교환");
		printArray(arr);
	}
	
	static void reverseArray(int[] arr) //배열 요소를 역순으로 정렬
	{
		for(int i = 0; i < arr.length/2; ++i)
		{
			swap(arr, i, arr.length - i-1);
		}
	}
	
	static void printArray(int[] array) //배열 요소 출력
	{
		for(int i = 0; i < array.length; ++i)
		{
			if(i == array.length-1) {System.out.println(array[i]); break;}
			System.out.print(array[i] + ", ");
		}
	}
	
	public static void main(String[] args) {
		int[] array = {1,2,3,4,5,6,7};
		printArray(array);
		reverseArray(array);
		//printArray(array);
	}
}
/*
1, 2, 3, 4, 5, 6, 7
Index 0와(과) 6를 교환
7, 2, 3, 4, 5, 6, 1
Index 1와(과) 5를 교환
7, 6, 3, 4, 5, 2, 1
Index 2와(과) 4를 교환
7, 6, 5, 4, 3, 2, 1
*/​

Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다.


배열, 난수 사용, 최댓값 구하기

n명의 사람 수를 받아오고, 랜덤으로 사람키를 지정해서 최댓값 출력

import java.util.Random;
import java.util.Scanner;
public class Main{
    static int maxOf(int[] a) {
        int max = a[0];
        for (int i = 1; i < a.length; i++)
            if (a[i] > max)
                max = a[i];
        return max;
    }
		
    public static void main(String[] args) {
        Random rand = new Random();
        Scanner stdIn = new Scanner(System.in);
        System.out.print("사람 수 : ");
        int num = stdIn.nextInt();				// 배열의 요솟수를 입력 받음

        int[] height = new int[num];			// 요솟수가 num인 배열을 생성

        System.out.println("키 값은 아래와 같습니다.");
        for (int i = 0; i < num; i++) {
            height[i] = 100 + rand.nextInt(90);		// 요소의 값을 난수로 결정
            System.out.println("height[" + i + "]:" + height[i]);
        }

        System.out.println("최댓값은 " + maxOf(height) + "입니다.");
    }
}
/*
사람 수 : 18
키 값은 아래와 같습니다.
height[0]:145
height[1]:186
height[2]:129
height[3]:175
height[4]:136
height[5]:161
height[6]:111
height[7]:142
height[8]:181
height[9]:126
height[10]:178
height[11]:100
height[12]:113
height[13]:132
height[14]:122
height[15]:127
height[16]:106
height[17]:185
최댓값은 186입니다.
*/

 

1~100개의 데이터 수를 랜덤으로 생성한 후, 0~10000의 데이터를 랜덤으로 입력한 후 최댓값 출력

import java.util.Random;
public class Main{
    static int maxOf(int[] arr) {
        int max = arr[0];
        for(int i = 1; i < arr.length; ++i)
        {
            if(max < arr[i]) max = arr[i];
        }
        return max;
    }
		
    public static void main(String[] args) {
        Random rand = new Random();
        int num = rand.nextInt(1,101);
        int[] arr = new int[num];

        for (int i = 0; i < arr.length; i++) {
            arr[i] = rand.nextInt(10001);
            System.out.print(i + "번째 원소의 값 : ");
            System.out.println(arr[i]);
        }

        System.out.println("최댓값은 " + maxOf(arr) + "입니다.");
    }
}
/*
0번째 원소의 값 : 8929
1번째 원소의 값 : 5458
2번째 원소의 값 : 8705
3번째 원소의 값 : 1236
4번째 원소의 값 : 5730
5번째 원소의 값 : 5667
6번째 원소의 값 : 9866
7번째 원소의 값 : 946
8번째 원소의 값 : 9884
9번째 원소의 값 : 4317
10번째 원소의 값 : 1018
11번째 원소의 값 : 5090
12번째 원소의 값 : 306
13번째 원소의 값 : 3743
14번째 원소의 값 : 58
15번째 원소의 값 : 6879
16번째 원소의 값 : 5951
17번째 원소의 값 : 5974
최댓값은 9884입니다.
*/

Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 연습문제와 실습문제입니다.


곱셈표

일반 곱셈표

public class Test{
	public static void main(String[] args) {
		for(int i = 1; i<10; ++i)
		{
			for(int j = 1; j<10; ++j)
			{
				System.out.print(i*j + " ");
			}
			System.out.println();
		}
	}
}
/*
1 2 3 4 5 6 7 8 9 
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
4 8 12 16 20 24 28 32 36 
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81 
*/

 

보기 좋은 곱셈표

public class Test{
	public static void main(String[] args) {
		for(int i = 1; i<10; ++i)
		{
			for(int j = 1; j<10; ++j)
			{
				System.out.printf("%3d", i*j);
			}
			System.out.println();
		}
	}
}
/*
  1  2  3  4  5  6  7  8  9
  2  4  6  8 10 12 14 16 18
  3  6  9 12 15 18 21 24 27
  4  8 12 16 20 24 28 32 36
  5 10 15 20 25 30 35 40 45
  6 12 18 24 30 36 42 48 54
  7 14 21 28 35 42 49 56 63
  8 16 24 32 40 48 56 64 72
  9 18 27 36 45 54 63 72 81
*/
설명
C언어 계열에서 printf문법과 같다.
%3d는 총 자리수가 3이고 오른쪽 정렬을 한다는 뜻이다.
예를 들어 %d에 3을 넣으면 단순히 3이 출력되지만, %3d에 3을 넣으면 공백 2번 + 3이 출력된다.
반대로 %-3d에 3을 넣으면 3 + 공백 2번이 출력된다.

 

 

곱셈표 심화

위와 같이 |, -, + 를 사용하여 위쪽과 왼쪽에 곱하는 수가 있는 곱셈표를 출력하는 프로그램을 작성

public class Test{
	public static void main(String[] args) {
		for(int i = 0; i<11; ++i)
		{
			for(int j = 0; j<11; ++j)
			{
				if(i==0&&j==0) {System.out.print("   ");}
				if(i==1)
				{
					if(i==1&&j==1) {}
					else System.out.print("---");
				}
				if(i==0&&j>1) {System.out.printf("%3d", j-1);}
				if(j==0&&i>1) {System.out.printf("%3d", i-1);}
				if(i==1&&j==1) {System.out.print("+");}
				if(j==1)
				{
					if(i==1&&j==1) {}
					else System.out.print("|");
				}
				if(i>1&&j>1) {System.out.printf("%3d", (i-1)*(j-1));}
			}
			System.out.println();
		}
	}
}
/*
   |  1  2  3  4  5  6  7  8  9
---+---------------------------
  1|  1  2  3  4  5  6  7  8  9
  2|  2  4  6  8 10 12 14 16 18
  3|  3  6  9 12 15 18 21 24 27
  4|  4  8 12 16 20 24 28 32 36
  5|  5 10 15 20 25 30 35 40 45
  6|  6 12 18 24 30 36 42 48 54
  7|  7 14 21 28 35 42 49 56 63
  8|  8 16 24 32 40 48 56 64 72
  9|  9 18 27 36 45 54 63 72 81
*/

 

 

덧셈표

public class Main{
	public static void main(String[] args) {
		for(int i = 0; i<11; ++i)
		{
			for(int j = 0; j<11; ++j)
			{
				if(i==0&&j==0) {System.out.print("   ");}
				if(i==1)
				{
					if(i==1&&j==1) {}
					else System.out.print("---");
				}
				if(i==0&&j>1) {System.out.printf("%3d", j-1);}
				if(j==0&&i>1) {System.out.printf("%3d", i-1);}
				if(i==1&&j==1) {System.out.print("+");}
				if(j==1)
				{
					if(i==1&&j==1) {}
					else System.out.print("|");
				}
				if(i>1&&j>1) {System.out.printf("%3d", (i-1)+(j-1));}
			}
			System.out.println();
		}
	}
}
/*
   |  1  2  3  4  5  6  7  8  9
---+---------------------------
  1|  2  3  4  5  6  7  8  9 10
  2|  3  4  5  6  7  8  9 10 11
  3|  4  5  6  7  8  9 10 11 12
  4|  5  6  7  8  9 10 11 12 13
  5|  6  7  8  9 10 11 12 13 14
  6|  7  8  9 10 11 12 13 14 15
  7|  8  9 10 11 12 13 14 15 16
  8|  9 10 11 12 13 14 15 16 17
  9| 10 11 12 13 14 15 16 17 18
*/

 

 

정사각형 출력

입력 받은 수를 한 변으로 하는 정사각형을 * 기호로 출력

import java.util.Scanner;
public class Main{
	static void square(int n)
	{
		for(int i = 0; i < n; ++i){for(int j = 0; j < n; ++j) {System.out.print("*");}
		System.out.println();
		}
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.print("단 수 입력 : ");
		int n = sc.nextInt();
		square(n);
	}
}
/*
단 수 입력 : 5
*****
*****
*****
*****
*****
*/

 

 

직각 이등변 삼각형 출력

도움
안쪽 루프와 바깥쪽 루프의 선언부를 유심히 보면서 분석해야한다.
변수가 몇부터 시작하는지, 제어식과 증가식이 어떻게 다르게 설정해야 하는지, 조건문은 어떻게 설정할지
유심히 생각하고 봐야 한다.
밑에 나열된 4개의 직각 이등변 삼각형 문제는 대표적인 이중 for문 알고리즘 문제이다.
답지를 보진 않았지만 난 머리가 나빠서 오래 걸렸다.
결국 이 알고리즘들을 생각하지 못했더라도 좌절하지 말자
유명 강사분도 이 알고리즘들을 처음 접했을 때 결국 풀어내지 못했다고 한다.

 

왼쪽 아래가 직각인 이등변 삼각형

사용자로부터 단 수를 입력받고, 왼쪽 아래가 직각인 이등변 삼각형

import java.util.Scanner;
public class Test{
	static void triangleLB(int n)
	{
		for(int i = 0; i < n; ++i)
		{
			for(int j = 0; j <= i; ++j)
			{
				System.out.print("*");
			}
			System.out.println();
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int nc;
		do {
			System.out.print("단 수 입력 : ");
			nc = sc.nextInt();
		}
		while(nc<=0);
		
		triangleLB(nc);
	}
}
/*
단 수 입력 : 10
*
**
***
****
*****
******
*******
********
*********
**********
*/
답지 코드
static void triangleLB(int n) {
    for (int i = 1; i <= n; i++) { 				// i행 (i = 1, 2, … ,n)
        for (int j = 1; j <= i; j++) 			// i개의 '*'를 나타냄
            System.out.print('*');
        System.out.println(); 					// 개행(줄변환)
    }
}​

 

왼쪽 위가 직각인 이등변 삼각형

사용자로부터 단 수를 입력 받고, 왼쪽 위가 직각인 이등변 삼각형

import java.util.Scanner;
public class Test{
	static void triangleLU(int n)
	{
		for(int i = n; i > 0; --i)
		{
			for(int j = 0; j < i; ++j)
			{
				System.out.print("*");
			}
			System.out.println();
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int nc;
		do {
			System.out.print("단 수 입력 : ");
			nc = sc.nextInt();
		}
		while(nc<=0);
		
		triangleLU(nc);
	}
}
/*
단 수 입력 : 10
**********
*********
********
*******
******
*****
****
***
**
*
*/
답지 코드
static void triangleLU(int n) {
    for (int i = 1; i <= n; i++) { 				// i행 (i = 1, 2, … ,n)
        for (int j = 1; j <= n - i + 1; j++) 	// n-i+1개의 '*'를 나타냄
            System.out.print('*');
        System.out.println(); 					// 개행(줄변환)
    }
}​

 

오른쪽 위가 직각인 이등변 삼각형

사용자로부터 단 수를 입력 받고, 오른쪽 위가 직각인 이등변 삼각형

import java.util.Scanner;
public class Test{
	static void triangleRU(int n)
	{
		for(int i = 0; i < n; ++i)
		{
			for(int j = 0; j < n; ++j)
			{
				if(i<=j)System.out.print("*");
				else System.out.print(" ");
			}
			System.out.println();
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int nc;
		do {
			System.out.print("단 수 입력 : ");
			nc = sc.nextInt();
		}
		while(nc<=0);
		
		triangleRU(nc);
	}
}
/*
단 수 입력 : 10
**********
 *********
  ********
   *******
    ******
     *****
      ****
       ***
        **
         *
*/
답지 코드
static void triangleRU(int n) {
    for (int i = 1; i <= n; i++) { 				// i행 (i = 1, 2, … ,n)
        for (int j = 1; j <= i - 1; j++) 		// i-1개의 ' '를 나타냄
            System.out.print(' ');
        for (int j = 1; j <= n - i + 1; j++) 	// n-i+1개의 '*'를 나타냄
            System.out.print('*');
        System.out.println();					// 개행(줄변환)
    }
}​

 

오른쪽 아래가 직각인 이등변 삼각형

사용자로부터 단 수를 입력 받고, 오른쪽 아래가 직각인 이등변 삼각형

import java.util.Scanner;
public class Test{
	static void triangleRB(int n)
	{
		for(int i = 1; i <= n; ++i)
		{
			for(int j = 1; j <= n; ++j)
			{
				if(n-j < i)System.out.print("*");
				else System.out.print(" ");
			}
			System.out.println();
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int nc;
		do {
			System.out.print("단 수 입력 : ");
			nc = sc.nextInt();
		}
		while(nc<=0);
		
		triangleRB(nc);
	}
}
/*
단 수 입력 : 10
         *
        **
       ***
      ****
     *****
    ******
   *******
  ********
 *********
**********
*/
답지 코드
static void triangleRB(int n) {
    for (int i = 1; i <= n; i++) { 				// i행 (i = 1, 2, … ,ln)
        for (int j = 1; j <= n - i; j++) 		// n-i개의 ' '를 나타냄
            System.out.print(' ');
        for (int j = 1; j <= i; j++) 			// i개의 '*'를 나타냄
            System.out.print('*');
        System.out.println(); 					// 개행(줄변환)
    }
}​

 

 

피라미드

도움
피라미드의 최하단은 2n-1이다.
피라미드의 중심축은 n-1이다.
중심축을 따라서 단이 늘어날수록 왼쪽과 오른쪽의 공백을 줄여주면 된다.

 

일반 피라미드

import java.util.Scanner;
public class Test{
	static void spira(int n)
	{
		for(int i = 0; i < n; ++i)
		{
			for(int j = 0; j <= n+(n-1); ++j)
			{
				if(j<n-1-i) System.out.print(" ");
				else if(j>n-1+i) System.out.print(" ");
				else System.out.print("*");
			}
			System.out.println();
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int nc;
		do {
			System.out.print("단 수 입력 : ");
			nc = sc.nextInt();
		}
		while(nc<=0);
		
		spira(nc);
	}
}
/*
단 수 입력 : 10
         *          
        ***         
       *****        
      *******       
     *********      
    ***********     
   *************    
  ***************   
 *****************  
******************* 
*/
답지 코드
static void spira(int n) {
    for (int i = 1; i <= n; i++) { 					// i행 (i = 1, 2, … ,n)
        for (int j = 1; j <= n - i + 1; j++) 		// n-i+1개의 ' '를 나타냄
            System.out.print(' ');
        for (int j = 1; j <= (i - 1) * 2 + 1; j++) 	// (i-1)*2+1개의 '*'를 나타냄
            System.out.print('*');
        System.out.println(); 						// 개행(줄변환)
    }​

 

숫자 피라미드

import java.util.Scanner;
public class Test{
	static void spira(int n)
	{
		for(int i = 0; i < n; ++i)
		{
			for(int j = 0; j <= n+(n-1); ++j)
			{
				if(j<n-1-i) System.out.print(" ");
				else if(j>n-1+i) System.out.print(" ");
				else System.out.print((i+1) % 10);
			}
			System.out.println();
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int nc;
		do {
			System.out.print("단 수 입력 : ");
			nc = sc.nextInt();
		}
		while(nc<=0);
		
		spira(nc);
	}
}
/*
단 수 입력 : 10
         1          
        222         
       33333        
      4444444       
     555555555      
    66666666666     
   7777777777777    
  888888888888888   
 99999999999999999  
0000000000000000000 
*/
답지 코드
static void spira(int n){
    for (int i = 1; i <= n; i++) { 					// i행 (i = 1, 2, … ,n)
        for (int j = 1; j <= n - i + 1; j++) 		// n-i+1개의 ' '를 나타냄
            System.out.print(' ');
        for (int j = 1; j <= (i - 1) * 2 + 1; j++) 	// (i-1)*2+1개의 '*'를 나타냄
            System.out.print(i % 10);
        System.out.println(); 						// 개행(줄변환)
    }
}​​