class ClassName {
// 필드(변수)
// 메서드(함수)
}
ClassName은 클래스의 이름으로, Java의 네이밍 컨벤션에 따라 각 단어의 첫 글자는 대문자로 시작한다.ex. 자바 클래스
public class Dog {
// 필드
String breed;
int age;
String color;
// 메서드
// 접근제한자 리턴타입 메소드명 (매개변수들..) {..구현..}
void bark() {
System.out.println("Woof!");
}
void displayInfo() {
System.out.println("Breed: " + breed + ", Age: " + age + ", Color: " + color);
}
}
ex. 객체 생성 및 사용
public class DogTest {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.breed = "Labrador";
myDog.age = 5;
myDog.color = "Brown";
myDog.bark();
myDog.displayInfo();
}
}
import java.util.Scanner;
public class ListPrimes {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("정수를 입력하세요: ");
int num = sc.nextInt();
int cnt = 0;
for (int i = 2; i <= num; i++){
boolean isPrime = true;
for (int j = 2; j < i ; j++){
cnt++;
if (i % j == 0){
isPrime = false;
break;
}
}
if(isPrime == true){
System.out.println(i);
}
}
System.out.println(cnt);
}
}
입력한 정수까지의 모든 수를 2부터 체킹하는 수-1까지의 모든 수로 나누어 소수인지 판별을 한다.
이러한 방식은 시간이 오래걸리는 단점이 있음.
입력한 정수까지 홀수만 체킹하며 소수를 찾는 방식
import java.util.Scanner;
public class ListPrimes2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("정수를 입력하세요: ");
int num = sc.nextInt();
int cnt = 0;
int arrCnt = 0;
int[] primes = new int[500];
primes[arrCnt++] = 2; // 2를 먼저 소수의 배열에 넣어준다.
for (int i = 3; i <= num; i+=2){
boolean isPrime = true;
for (int j = 3; j < i ; j++){
cnt++;
if (i % j == 0){
isPrime = false;
break;
}
}
if(isPrime == true){
System.out.println(i);
}
}
System.out.println(cnt);
}
}
2를 먼저 소수의 배열 primes에 넣어준다.
3부터 입력한 정수까지 홀수만 체킹을 하며 그 사이의 수로 모두 나누며 소수인지 판별한다.
위의 코드와 다르게 prime배열에 3을 먼저 넣어주고 5부터 판별해도 된다. (2, 3 모두 소수이기 때문)
1번째 방법
int[][] scores = new int[3][4];
2번째 방법
int[][] scores = {
{90, 80, 77, 60}, // 첫 번째 학생의 점수
{80, 70, 60, 50}, // 두 번째 학생의 점수
{70, 60, 50, 40} // 세 번째 학생의 점수
};
클래스는 기본적으로 도면이라고 생각하면된다.
클래스를 인스턴스화 하면 객체가 되는 것이다.
클래스 → 자동차를 만드는 도면
객체 → 도면을 가지고 만든 나의 자동차
public class Dog {
String breed;
int age;
String color;
public Dog() {
//기본 생성자
}
public Dog(String breed, int age, String color) {
this.breed = breed;
this.age = age;
this.color = color;
}
public Dog(String breed, String color) {
this.breed = breed;
this.color = color;
}
//메소드
//접근제한자 리턴타입 메소드명 (매개변수들...)
static void bark(){
System.out.println("Woof!");
}
void displayInfo(){
System.out.println("Breed: " + breed + " Age: " + age + " Color: " + color);
}
//getter, settter
public String getBreed() {
return breed;
}
public int getAge() {
return age;
}
public String getColor() {
return color;
}
public void setBreed(String breed) {
this.breed = breed;
}
public void setAge(int age) {
this.age = age;
}
public void setColor(String color) {
this.color = color;
}
}
강아지 클래스이다.
즉, 강아지를 만들 수 있는 도면을 만든 것이라고 생각하면 된다.
기본적으로 생성자를 만들지 않으면 자바에서는 기본 생성자를 제공해준다.
위의 코드에서는 “기본생성자”, “품종과 나이, 색깔이 모두 들어간 생성자”, “품종과 색깔만 들아간 생성자” 3 종류가 있다.
위의 메소드를 보면 bark()와 displayInfo()가 있다.
bark()는 static이 붙은 클래스 메소드이다.
displayInfo()는 static이 붙지 않은 인스턴스 메소드이다.
static이 붙은 클래스 메소드는 객체를 생성하지 않아도 사용이 가능하다.
하지만 static이 붙지 않은 인스턴스 메소드는 객체를 생성해야만 사용이 가능하다.
ex. 객체 생성 코드
public class DogTest {
public static void main(String[] args) {
Dog.bark();
Dog myDog = new Dog(); //Dog 타입의 myDog를 인스턴스화
myDog.setAge(3);
myDog.setBreed("말티즈");
myDog.setColor("흰색");
myDog.age=6;
myDog.displayInfo();
Dog myDog2 = new Dog("포메", 4, "검정색");
myDog2.displayInfo();
Dog myDog3 = new Dog("포메", "흰색");
myDog3.displayInfo();
}
}
위의 코드는 Dog클래스의 객체를 생성해서 사용하는 DogTest클래스이다.
bark() 메소드를 보면 객체를 생성하지 않고 Dog클래스에 바로 접근해서 사용이 가능하다.
위에서 언급했듯이 static 키워드가 붙은 클래스 메소드이기 때문이다.
하지만 displayInfo() 메소드는 객세를 생성한 후 객체에 접근해서 사용이 가능하다.
static이 붙지 않은 인스턴스 메소드이기 때문이다.
원하는 값을 찾기 위해서 배열의 첫번째 요소부터 마지막 요소까지 차례대로 모두 확인하는 방법
import java.util.Scanner;
public class SearchExam {
static int sequentialSearch(int[] arr, int key){
for (int i = 0; i < arr.length; i++) {
if (arr[i] == key)
return i; // 키와 일치하는 요소의 인덱스 반환
}
return -1; // 검색 실패 시 -1 반환
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("찾고자하는 정수를 입력하세요: ");
int key = sc.nextInt();
int[] arr = {1,3,5,33,56,2,44};
int index = sequentialSearch(arr, key);
if (index != -1){
System.out.println("당신이 찾는 데이터는 " +index+"번째 인덱스에 있습니다.");
}else {
System.out.println("당신이 찾는 데이터가 존재하지 않습니다.");
}
}
}
찾고자 하는 값을 입력하면 sequentialSearch() 메소드에서 배열의 첫번째 요소부터 마지막 요소까지 순차적으로 확인을 한다. 도중에 원하는 값을 찾으면 값이 위치하는 요소의 인덱스를 반환한다.
선형 검색 알고리즘을 개선한 방법
보초법(Sentinel Method)은 선형 검색에서 조건 검사의 횟수를 줄이기 위해 배열의 마지막에 검색하고자 하는 값을 “보초”로 추가하는 기법이다.
보초는 검색하고자 하는 키 값과 동일한 값을 배열의 맨 끝에 추가함으로써, 배열을 순회하는 동안 매번 배열의 끝에 도달했는지 확인하는 조건 검사를 생략할 수 있게 해준다.
선형 검색(보초법)의 작동 원리
장점
단점
import java.util.Scanner;
public class LinearSearchSentinel {
// 배열 arr에서 key와 일치하는 요소를 보초법을 사용하여 선형 검색
static int linearSearchSentinel(int[] arr, int size, int key) {
int i = 0;
arr[size] = key; // 보초 추가
while (true) {
if (arr[i] == key)
break;
i++;
}
return i == size ? -1 : i;
}
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.print("요소 개수: ");
int num = stdIn.nextInt();
int[] array = new int[num + 1]; // 요소 개수가 num + 1인 배열로, 마지막은 보초용
for (int i = 0; i < num; i++) {
System.out.print("array[" + i + "]: ");
array[i] = stdIn.nextInt();
}
System.out.print("찾을 값: "); // 찾고자 하는 값 입력
int key = stdIn.nextInt();
int index =linearSearchSentinel(array, num, key); // 배열 array에서 key를 검색
if (index == -1)
System.out.println("찾는 값의 요소가 없습니다.");
else
System.out.println("찾는 값은 array[" + index + "]에 있습니다.");
}
}
import java.util.Arrays;
import java.util.Scanner;
public class BinarySearchExam {
public static int binarySearch(int[] arr, int key){
int start = 0;
int end = arr.length - 1;
while(start <= end){
int mid = (start + end) / 2;
if (key == arr[mid]){
return mid;
} else if (key > arr[mid]) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return -1;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("찾고자하는 정수를 입력하세요: ");
int key = sc.nextInt();
int[] arr = {1,3,5,33,56,2,44};
Arrays.sort(arr); //Arrays의 sort메소드를 사용하여 정렬
System.out.println(Arrays.toString(arr));
int index =binarySearch(arr, key);
if (index != -1){
System.out.println("당신이 찾는 데이터는 " +index+"번째 인덱스에 있습니다.");
}else {
System.out.println("당신이 찾는 데이터가 존재하지 않습니다.");
}
}
}
O(log n) 의 시간 복잡도를 가지며, 큰 데이터 집합에서도 빠른 검색 속도를 보장한다.