728x90
기본 자료구조
- data structure
- 데이터 단위와 데이터 자체 사이의 물리적 또는 논리적인 관계
- 자료를 효율적으로 이용할 수 있도록 컴퓨터에 저장하는 방법
- 데이터 단위: 데이터를 구성하는 한 덩어리
배열
- 배열의 자료형 구분
각 요소의 자료형 = int, a[0]은 int형
자료형 = int[5], a는 int[5]형 - int a = new int[5]; 선언하면 배열 a는 a[0], a[1], a[2], a[3], a[4]로 총 5개의 int형 저장 공간을 차지함
- 배열의 구성 요소는 자동으로 0으로 초기화됨
그림 추가
배열의 복제
배열의 이름.clone();
package chap02_1;
import java.util.Arrays;
public class CloneArray {
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5};
int[] b = a.clone(); //b는 a의 복제를 참조
b[3] = 0;
System.out.println("a = " + Arrays.toString(a)); //a = [1, 2, 3, 4, 5]
System.out.println("b = " + Arrays.toString(b)); //b = [1, 2, 3, 0, 5]
}
}
그림 추가
배열 요소의 최댓값
package chap02_1;
import java.util.Scanner;
public class MaxOfArray {
static int maxOf(int[] a) { //배열 a의 최댓값을 구하여 반환
int max = a[0]; //맨 처음 max값을 배열의 첫번째 값
for(int i = 1; i < a.length; i++) { //배열의 길이만큼 반복
if(a[i] > max) { //현재 max값보가 a[i] 인덱스의 값이 더 클 때
max = a[i]; //max값에 a[i] 값 넣기
}
}
return max;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("키의 최댓값을 구함");
System.out.print("사람 수: ");
int num = scan.nextInt(); //배열의 요솟수를 입력 받음 = 배열의 길이
int[] heigth = new int[num]; //길이가 num인 int형 배열 height 생성
for(int i = 0; i < num; i++) { //배열의 값 넣어줘야 하므로 배열만큼 반복
System.out.print("height[" + i + "] = ");
heigth[i] = scan.nextInt(); //배열[인덱스값]에 scan.nextInt();로 값 넣어주기
}
//반복이 끝나면
System.out.println("최댓값은 " + maxOf(heigth) + "입니다."); //maxOf() 메서드 안에 height 배열 넣어서 최댓값 반환
}
}
머쓱이보다 키 큰 사람
https://school.programmers.co.kr/learn/courses/30/lessons/120585
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
3항 연산자 사용하자!!!!!!!!
for(int i: array){
answer += (i>height) ? 1 : 0;
}
배열 요소를 역순으로 정렬
그림 추가---
요소 개수가 n인 배열 요소를 역순으로 정렬하는 알고리즘
for(int i = 0; i < n/2; i++) {
//a[i]와 a[n-i-1]의 값을 교환
}
- 교환 횟수는 n/2로 중앙 전까지만 교환하면 됨
요소 개수가 홀수 - 가운데 요소 교환할 필요 x
배열 안의 두 값 교환
그림 추가---
배열 안의 두 요소를 교환하는 알고리즘
//배열 요소 a[idx1]과 a[idx2]의 값을 교환
static void swap(int []a, int idx1, int idx2) {
int t = a[idx1];
a[idx1] = a[idx2];
a[idx2] = t;
}
- 설명 설명
두 배열의 비교
package chap02_1;
import java.util.Scanner;
public class ArrayEqual {
static boolean equal(int[] a, int[] b) {
if(a.length != b.length) { //길이 확인
return false;
}
for(int i = 0; i < a.length; i++) { //내용물 확인
if(a[i] != b[i]) {
return false;
}
}
return true; //두 조건이 다 true이면 결과적으로 같은 배열임
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("a 배열의 요솟수: ");
int num1 = scan.nextInt();
int[] a = new int[num1];
for(int i = 0; i < num1; i++) {
System.out.print("a[" + i + "] = ");
a[i] = scan.nextInt();
}
System.out.print("b 배열의 요솟수: ");
int num2 = scan.nextInt();
int[] b = new int[num2];
for(int i = 0; i < num2; i++) {
System.out.print("b[" + i + "] = ");
b[i] = scan.nextInt();
}
//3항 연산자 사용
System.out.println("배열 a와 b는 " + (equal(a, b)? "같습니다." : "같지 않습니다"));
}
}
배열의 모든 요소를 복사
package chap02_1;
import java.util.Arrays;
import java.util.Scanner;
public class Quiz4 {
static void copy(int[] a, int[] b) {
if(a.length != b.length) System.out.println("두 배열의 길이가 같지 않습니다.");
for(int i = 0; i < a.length; i++) {
a[i] = b[i];
}
}
// 배열 b의 모든 요소를 배열 a에 복사 ▶ 여기서는 길이가 같은지는 중요하지 않음
//static void copy(int[] a, int[] b) {
// int num = a.length <= b.length ? a.length : b.length; //a길이가 작으면 a만큼만, b가 작으면 b만큼만
// for (int i = 0; i < num; i++)
// a[i] = b[i];
//}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("a의 요솟수는 :");
int num1 = scan.nextInt();
int[] a = new int[num1];
for (int i = 0; i < num1; i++) {
System.out.print("a[" + i + "] : ");
a[i] = scan.nextInt();
}
System.out.print("b의 요솟수는 :");
int num2 = scan.nextInt();
int[] b = new int[num2];
for (int i = 0; i < num2; i++) {
System.out.print("b[" + i + "] : ");
b[i] = scan.nextInt();
}
copy(a, b);
System.out.println("a배열 = " + Arrays.toString(a));
System.out.println("b배열 = " + Arrays.toString(b));
}
}
역순해서 복사
// 역순 복사
a[i] = b[b.length - i - 1];
배열 역순 할때는 배열길이 - i -1 사용
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]; //역순해서 복사
}
}
기수 변환
소수의 나열
소수
- 자신과 1 이외의 정수로 나누어떨어지지 않는 정수
- 2부터 n-1까지의 어떤 소수로도 나누어떨어지지 않음
n보다 작은 소수로 나눗셈 했을 경우 n-1까지 나누어떨어지는 수가 없으면 소수 (계산 시간을 줄일 수 있음)
↔ 합성수: 나누어떨어지는 정수가 하나 이상 존재하는 수
소수의 나열
package chap02_1;
public class PrimeNumber1 {
//1000이하의 소수를 열거
public static void main(String[] args) {
int counter = 0; //나눗셈의 횟수
for(int i = 2; i <= 1000; i++) {
int j;
for(j = 2; j < i; j++) {
counter++; //나눗셈을 할 때마다 count를 증가해 연산 횟수 계산
if(i % j == 0) { //나누어 떨어지면 소수x
break;
}
}
if(i == j) { //마지막까지 나누어 떨어지지 않음
System.out.println(i);
}
}
System.out.println("시행한 횟수: " + counter);
}
}
알고리즘 개선(1)
- 배열 prime에는 그 때까지 구한 소수를 넣음
- ptr은 배열에 저장한 소수의 개수를 나타내는 변수
prime[0] = 2 저장한 후 바로 다음의 ptr 값은 1 - 3 이상의 소수는 이중 for문으로 구함
안쪽의 for문은 i 값을 1부터 시작하여 ptr-1회 반복
package chap02_1;
//1000이하의 소수를 구하라
public class PrimeNumber2 {
public static void main(String[] args) {
int counter = 0; //나눗셈의 횟수
int ptr = 0; //찾은 소수의 개수, 소수 2가 저장되고 다음은 1이 나옴
int[] prime = new int[500]; //길이가 500인 소수를 저장하는 배열
prime[ptr++] = 2; //prime[0] = 2 저장, 2는 소수, 여기서 ptr = 1
for(int n = 3; n <= 1000; n += 2) { //2는 소수이고, 3부터 1000까지 홀수(+2씩)만 확인
int i;
for(i = 1; i < ptr; i++) { //처음의 i < ptr이 1 < 1이므로 for문을 반복 수행x
counter++; //나눗셈 횟수를 세고,
if(n % prime[i] == 0) { //나누어 떨어지면 멈춤(소수x)
break;
}
}
if(ptr == i) { //처음의 ptr == i는 1==1이므로 prime[1] = 3을 넣음
prime[ptr++] = n;
}
}
for(int i = 0; i < ptr; i++) {
System.out.println(prime[i]); //찾은 ptr개의 소수를 나타냄
}
System.out.println("나눗셈을 수행한 횟수: " + counter);
}
}
알고리즘 개선(2)
알고리즘 개선(3)
다차원 배열
int[ ][ ] x = new int [2][4];
//2행 4열
한 해의 경과 일 수를 계산하는 프로그램
- 그 해의 경과 일 수는 1월, 2월, 3월, ..., m-1월의 일 수의 합 + d
- 단, 2월의 평년은 28일, 윤년은 29일이므로 다차원 배열로 [0] = 평년, [1] = 윤년으로 잡아줘야 함
1년을 366일로 잡아도 정확하지 않으므로 평년 = 100으로 나눠지고, 400으로 나눠지지 않는 해 (윤년은 거꾸로)
//각 달의 일수
static int[][] mdays = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //평년 i=[0]
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //윤년 i=[1]
};
//서기 year년은 윤년인가? (윤년 = 1, 평년 = 0)
static int isLeap(int year) {
return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 1 : 0;
//4년에 한번은 윤년 && !(year%100 == 0 && year%400 != 0) 이 조건이 아닐 때 윤년
}
//서기 y년 m월 d일의 그 해 경과 일 수 구하는 메서드
static int dayOfYear(int y, int m, int d) {
int days = d; //일 수 먼저 넣고
for(int i = 1; i < m; i++) { //1월 ~ (m-1)월의 일 수를 더하기 ********i는 1부터 시작해야 [0]부터 나옴
days += mdays[isLeap(y)][i-1]; //isLeap로 평년이면 0, 윤년이면 1을 넣어서 행 구해주고, 열은 m-1이니까 i-1해서 일수 days에 넣기
}
return days;
}
- y년 i월의 일 수 = mdays[isLeap[y][i-1]
- 각 달의 일수를 다차원 배열로 나타내고, isLeap 메서드를 사용하여 28일인지 29일인지 선택
- dayOfYear로 일 수 구하기
//while문 사용하여 메서드 구현
static int dayOfYear(int y, int m, int d) {
while(--m != 0) { //--m; + m != 0; m에서 하나뺀 값이 0이 아닐때까지 반복, ex) 2월, 1월
d += mdays[isLeap(y)][m-1];
}
return d;
}
- 변수 days와 for문을 사용하지 않고, while문 이용
//그 해 남은 일 수 구하기
static int leftDayOfYear(int y, int m, int d) {
while(--m != 0) {
d += mdays[isLeap(y)][m-1];
} //그 년에서 지난 일 수 구해서
int result = 365 - d; //365일에서 빼기
return result;
}
while문에서 자주 쓰이는 조건식
--m != 0 ▶ --m; + m != 0;
m을 하나씩 줄이고, 그게 0이 아닌 경우
m-- > 0 ▶ m--; + m > 0;
m을 줄이는데(루프가 돌고 1을 줄임) 0보다 큰 경우
다차원 배열의 복제
- clone은 최상위의 1레벨만 수행 = 그 아래 레벨의 배열은 복제되지 않고 공유
향상된 for문
- 인덱스 자체의 값이 필요하지 않으면 그 스캔은 향상된 for문에 의해 구현
for(int i : arr) {
관련 수식
} ▶ 배열 arr안에 있는 int i, 배열이 int형임
Math.random() vs new Random
- 컴퓨터에서 진짜 랜덤 값은 없고, 수식에 의해 생성된 수식의 결과물을 랜덤값으로 사용
- seed * (수식) 으로 seed(컴퓨터의 현재 시간)에 의해 랜덤값이 변함
Math.random() | new Random |
import java.lang.Math | import java.util.Random; Random ran = new Random(); |
0.0 ~ 1.0 사이의 임의의 double형 난수 | boolean, int, long, float, double형 난수 |
seed(현재시간) 가 고정 | seed() 임의로 설정 가능 |
ran.setSeed(System.currentTimeMillis()); ran.setSeed(10); //동일 seed를 가지면 동일한 랜덤값 생성 |
- 실무적으로 Random 클래스를 더 많이 사용
- 암호화를 위한 난수 생성에는 rsa, sha256, sha512 등을 사용하여 복호화 어렵게 만듦
난수를 사용한 배열의 요솟값 설정 & 최댓값 --- 수정
package chap02_1;
import java.util.Random;
import java.util.Scanner;
public class MaxOfArrayRand {
//max값 구하는 메서드
static int maxOf(int[] a) {
int max = a[0];
for(int i = 1; i < a.length; i++) { //a[0]은 이미 max에 들어가있으니까 1부터
if(max < a[i]) max = a[i];
}
return max;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// int ran = ((int)Math.random() * 90 ) + 1;
Random ran = new Random(); //Random 클래스형의 변수(ran) 선언
System.out.println("키의 최댓값을 구합니다.");
System.out.print("사람 수: ");
int num = scan.nextInt();
int[] heigth = new int[num];
System.out.println("키 값을 아해와 같습니다.");
for(int i = 0; i < num; i++) {
heigth[i] = 100 + ran.nextInt(90); //0 <= nextInt(n) < n 이므로 0~89까지의 난수 생성
System.out.println("heigth[" + i + "] = " + heigth[i]);
}
System.out.println("최댓값은 " + maxOf(heigth) + "입니다.");
}
}
1. Random 클래스를 사용하기 위해 import 선언
2. Random 클래스형의 변수(ran)를 만들기 위한 선언
3. 변수 ran에 대한 난수를 생성하는 메서드 nextInt 호출
클래스
- 임의의 데이터형을 자유로이 조합하여 만들 수 있는 자료구조
- 여러 형의 요소를 조합하여 만든 자료구조
클래스의 배열
평균 키와 시력의 분포
더보기
package chap02_1;
import java.util.Scanner;
//신체검사 데이터용 클래스 배열에서 평균 키와 시력의 분포를 구함
public class PhysicalExamination {
static final int VMAX = 21; // 시력분포(0.0에서 0.1 단위로 21개)
static class PhyscData { // 필드 = 멤버변수
String name; // 이름
int height; // 키
double vision; // 시력
//생성자
//ctrl+shift+s
public PhyscData(String name, int height, double vision) {
super();
this.name = name;
this.height = height;
this.vision = vision;
}
}
//키의 평균값을 구함
static double aveHeight(PhyscData[] dat) { //데이터가 들어가 있는 배열
double sum = 0;
for(int i = 0; i < dat.length; i++) {
sum += dat[i].height;
}
return sum / dat.length;
}
//시력 분포를 구함
static void distVision(PhyscData[] dat,
int[] dist) { //무슨 배열인가..
int i = 0;
dist[i] = 0;
for(i = 0; i < dat.length; i++) {
if(dat[i].vision >= 0.0 && dat[i].vision < VMAX / 10.0)
dist[(int)(dat[i].vision * 10)]++;
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
PhyscData[] x = {
new PhyscData("박현규", 162, 0.3),
new PhyscData("함진아", 173, 0.7),
new PhyscData("최윤미", 175, 2.0),
new PhyscData("홍연의", 171, 1.5),
new PhyscData("이수진", 168, 0.4),
new PhyscData("김영준", 174, 1.2),
new PhyscData("박용규", 169, 0.8),
};
int[] vdist = new int[VMAX]; //시력분포
System.out.println("■ 신체검사 리스트 ■");
System.out.println("이름 키 시력");
System.out.println("---------------");
for(int i = 0; i < x.length; i++) {
System.out.printf("%-8s%3d%5.1f\n", x[i].name, x[i].height, x[i].vision); //개인 키, 시력
}
System.out.printf("\n평균 키: %5.1fcm\n", aveHeight(x)); //메서드 사용
distVision(x, vdist); //시력분포를 구함
System.out.println("\n시력 분포");
for(int i = 0; i < VMAX; i++) {
System.out.printf("%3.1f~%2d명\n", i / 10.0, vdist[i]);
}
}
}
시력 분포
0.0~ 0명
0.1~ 0명
0.2~ 0명
0.3~ 1명
0.4~ 1명
System.out.println("\n시력 분포");
for(int i = 0; i < VMAX; i++) {
System.out.printf("%3.1f~:", i / 10.0, vdist[i]); //0.1~2.0까지 써져있는 앞부분
for (int j = 0; j < vdist[i]; j++) //한 사람씩 반복하면서 *표시
System.out.print('*');
System.out.println(); //반복하나 끝나면 아래로 내리기 (이전의 \n과 같음)
}
시력 분포
0.0~:
0.1~:
0.2~:
0.3~:*
0.4~:*
Quiz 11
클래스 보충
- 본체에는 멤버(필드/메서드/중첩 클래스/중첩 인터페이스), 클래스초기화/인스턴스초기화, 생성자 선언 가능
- 필드/메서드/생성자 선언시 public/protected/private 지정 가능
- 메서드/생성자는 다중으로 정의(오버로드) 가능 = 형식은 다르고, 같은 이름
- final로 선언한 필두는 한 번만 값 대입 가능
- 생성자는 새로 생성한 인스턴스의 초기화를 위해 사용됨
2022.10.05 - [프로그래밍 언어/Java] - [Java] object(객체), class(클래스), 변수(멤버/지역), 생성자(constructor)
[Java] object(객체), class(클래스), 변수(멤버/지역), 생성자(constructor)
객체와 클래스 클래스 aka.공장 대량 생산을 위해 객체를 만들기 위한 틀 변수: 객체의 속성 메서드: 객체의 기능 객체생성 명령 ClassName instanceName(생산이름,임의) = new Constructor( ); // 클래스 안의
j-won950101.tistory.com
728x90
'Study > Data Structure&Algorithm' 카테고리의 다른 글
[자료구조&알고리즘] 재귀 알고리즘(팩토리얼, 유클리드 호제법), 하노이의 탑, N퀸 문제 / 백트래킹 (0) | 2023.05.08 |
---|---|
[자료구조&알고리즘] stack(스택), queue(큐) (0) | 2023.05.07 |
[알고리즘] 유클리드 호제법 (Euclidean algorithm), 약수, 배수 (0) | 2023.04.25 |
[자료구조&알고리즘] 검색(검색 알고리즘, 선형검색, 이진검색) (0) | 2023.04.25 |
[자료구조&알고리즘] 기본 알고리즘(알고리즘, 반복) (0) | 2023.04.09 |