국비/Java

2023.02.24 22일차 Java

춘핑이 2023. 2. 24. 17:56

22일차
문자열(String) 배열
핵심 내용은 참조타입이 어떻게 저장되는가

5.참조타입

5.9 향상된 for문

for문으로 배열을 탐색한다. 기존의 for문이이 너무 복잡해서 생겨났다.
enhanced for (향상된 for), foreach
for문이 각 아이템을 기준으로 접근을 했다.
for (배열의 아이템타입 변수 : 배열)
배열의 아이템이 들어갈 변수
인덱스를 통해서 반복과 인덱스없이 반복하는 차이가 있다.
순서대로 전체탐색하겟다 향상된 for문 인덱스가필요하다 고전적 for문을 사용하자.

int[] arr1 = { 5, 6, 10, 9, 1, 2 };

for (int i = 0; i < arr1.length; i++) {
    System.out.println(arr1[i]);
}

//enhanced for (향상된 for), foreach
for (int n : arr1) {
    System.out.println(n);
}

5.9.1 확인문제 7번

어제푼 7번을 향상된 for문으로 보기

public class ex7_2 {
    public static void main(String[] args) {
        int[] array = {1,5,3,8,2};
        int max = array[0];
        for (int n: array) {
            if (n>max) {
                max = n;
            }
        }
        System.out.println(max);
    }
}

5.9.2 확인문제 8번

어제 푼 8번을 향상된 for문으로 보기

public class ex8_2 {
    public static void main(String[] args) {
        int[][] array = {
                { 95, 86 },
                { 83, 92, 96 },
                { 78, 83, 93, 87, 88 }
        };

        int totalNum = 0;
        int totalSum = 0;
        double avg = 0;

        for (int[] brray : array) {
            for (int n : brray) {
                totalSum += n;
                totalNum++;
            }
        }

        avg = (double) totalSum / totalNum;

        System.out.println("전체 합: " + totalSum);
        System.out.println("평균: " + avg);
    }
}

배열을 배열에서꺼내고 또 배열이니 또 for문돌리기

5.10 Arrays 내장메소드

5.10.1 toString(arr)

배열의 내장메소드 toString(arr)
배열을 문자열로 쉽게 볼수 있게 보여줌

public class C01ToString {
    public static void main(String[] args) {
        int[] arr1 = { 9, 8, 7, 1, 2 };

        for (int n : arr1) {
            System.out.println(n);
        }

        System.out.println(Arrays.toString(arr1)); //[9, 8, 7, 1, 2] 
    }
}

5.10.2 copyOf()

배열 복사 메소드 고전적으로는 for문으로 복사했다.

public class C03CopyOf {
    public static void main(String[] args) {
        int[] arr1 = { 3, 5, 9, 2, 1 };

        //Arrays.copyOf(원본배열, 타겟배열길이)
        int[] arr2 = Arrays.copyOf(arr1, arr1.length);

        System.out.println(Arrays.toString(arr1)); //[9, 8, 1, 2, 3]
        System.out.println(Arrays.toString(arr2)); //[9, 8, 1, 2, 3]
    }
}

5.10.3 ArrayCopy

System의 복사기능
책188쪽

public class C04ArrayCopy {
    public static void main(String[] args) {
        int[] origin = { 9, 8, 1, 2, 3 };
        int[] target = new int[origin.length];

        //System.arraycopy(원본배열, 원본배열시작 index, 타겟배열, 타켓배열시작index, 복사할 길이);
        System.arraycopy(origin, 0, target, 0, origin.length);
    }
}

5.10.4 2차원배열의 copyOf

얕은복사 (shallow copy)

public class C05Copy {
    public static void main(String[] args) {

        int[][] arr3 = {
                {3,4,5},
                {9,8,7}
        };

        int[][] arr4 = Arrays.copyOf(arr3, arr3.length);

        System.out.println(arr3.length); //2
        System.out.println(arr4.length); //2

        arr3[0][0] = 30;

        System.out.println(arr3[0][0]); //30
        System.out.println(arr4[0][0]); //3? 30? => 30
    }
}

copyOf는 값이 복사된다. 1차원배열일때는 값을 복사한것임.
2차원배열이면 arr[3][] 참조타입인 1차원배열에 참조타입인 배열을 저장함.
그래서 복사하면 참조타입안에 들어있는 아이템인 배열의 참조값 '주소'가 저장이됨
그래서 복사하면 arr2에 값을 복사하면 참조타입 '주소'를 복사해옴

5.10.5 DeepToString

깊은 복사 deep copy
그럼 배열의 배열은 어떻게 복사하나? 복사의 복사를 하면된다.
이렇게하면 원소의 원소까지 복사한것이니 바뀌지 않는다.
인스턴스 안의 인스턴스를 복사한것

public class C07CopyMatrix {
    public static void main(String[] args) {
        int[][] arr1 = {
                {5, 7, 9, 10},
                {3, 2, 1, 0}
        };

        int[][] arr2 = new int[arr1.length][];

        for (int i = 0; i < arr1.length; i++) {
            arr2[i] = Arrays.copyOf(arr1[i], arr1[i].length);
        }

        System.out.println(Arrays.toString(arr1[0]));
        System.out.println(Arrays.toString(arr1[1]));

        System.out.println(Arrays.toString(arr2[0]));
        System.out.println(Arrays.toString(arr2[1]));

        arr1[0][0] = 50;

        System.out.println(arr1[0][0]); //50
        System.out.println(arr2[0][0]); //5
    }
}

toString을 그냥 쓰면 얕은 탐색을 해서 안의 아이템 배열의 주소를 알려줌
그래서 배열안의 배열의 값을 탐색하고싶다면 DeepToString을 사용하면된다.

public class C08DeepToString {
    public static void main(String[] args) {
        int[][] arr2= {
                {7,8},
                {2,3}
        };

        System.out.println(Arrays.toString(arr2));
        //[[I@5ca881b5, [I@24d46ca6] == arr2[0] arr2[1]을 그냥보여준것임.

        System.out.println("for loop로 toString");
        for (int[] arr : arr2) {
            System.out.println(Arrays.toString(arr));
        } //[7, 8] [2, 3]

        System.out.println("deepToString 메소드 사용");
        System.out.println(Arrays.deepToString(arr2)); //[[7, 8], [2, 3]]
    }
}

5.10.6 sort 정렬

comparable인터페이스를 구현한 타입들은 정렬이 가능하다.

public class C09Sort {
    public static void main(String[] args) {
        // sort: 정렬
        int[] arr1 = { 9, 0, 2, 3, 8, -1 };

        System.out.println(Arrays.toString(arr1));

        //정렬 오름차순
        Arrays.sort(arr1);

        System.out.println(Arrays.toString(arr1));
        //[-1, 0, 2, 3, 8, 9]

        String[] arr2 = {"java", "hello", "html", "css", "Java", "Css"};

        //String은 유니코드 순으로 정렬
        System.out.println(Arrays.toString(arr2));
        Arrays.sort(arr2);
        System.out.println(Arrays.toString(arr2));
        //[Css, Java, css, hello, html, java]
    }
}

5.10.6.1 확인문제 7번

다시풀기

public class ex7_3 {
    public static void main(String[] args) {
        int[] array = {1,5,3,8,2};
        Arrays.sort(array);
        System.out.println(array[array.length-1]); //8
    }
}

5.10.6.2 삼각형의 완성조건 (1)

프로그래머스 문제 120889
선분 세 개로 삼각형을 만들기 위해서는 다음과 같은 조건을 만족해야 합니다.
가장 긴 변의 길이는 다른 두 변의 길이의 합보다 작아야 합니다.

public int solution(int[] sides) {
    int answer = 0;
    Arrays.sort(sides);
    if (sides[2] < sides[1] + sides[0]){
        answer = 1;
    } else {
        answer = 2;
    }
    return answer;
}

배열을 정렬하면 마지막값이 가장 큰값이다. 비교해서 만들기

5.10.6.2 문자열 정렬하기 2

영어 대소문자로 이루어진 문자열 my_string이 매개변수로 주어질 때,
my_string을 모두 소문자로 바꾸고 알파벳 순서대로 정렬한 문자열을
return 하도록 solution 함수를 완성해보세요.

내풀이

public String solution(String my_string) {
    String answer = "";
    String str = my_string.toLowerCase();
    char[] chars = str.toCharArray();
    Arrays.sort(chars);
    answer = new String(chars);
    return answer;
}

toCharArraychar배열로만들고 new String하면 String이됨
정수 배열 num_list와 정수 n이 매개변수로 주어집니다. num_list를 다음 설명과 같이 2차원 배열로 바꿔 return하도록 solution 함수를 완성해주세요.

강사님 풀이

public String solution(String my_string) {
        // 소문자로 바꾸기
        String lower = my_string.toLowerCase();
        // 배열로 쪼개기
        String[] chars = lower.split("");
        // 정렬
        java.util.Arrays.sort(chars);
        String answer = "";
        // 연결
        for (String c : chars) {
            answer += c;
        }
        return answer;
    }

5.11 toCharArray()

스트링은 char들의 집합이다.
toCharArray을 사용하면 char배열로 만들 수있다

public class C10ToCharArray {
    public static void main(String[] args) {
        String str1 = "hello world!";
        String[] arr1 = str1.split("");

        System.out.println(Arrays.toString(arr1));

        char[] arr2 = str1.toCharArray();

        System.out.println(Arrays.toString(arr2));
    }
}

두 배열은 값은 같지만 저장된 형식이 다르다.

5.11.1 가위바위보

프로그래머스 120839

public String solution(String rsp) {
    String answer = "";
    char[] arr = rsp.toCharArray();
     for (int i = 0; i < arr.length; i++){
        if (arr[i] == '2'){
            arr[i] = '0';
        } else if (arr[i] == '0'){
            arr[i] = '5';
        } else if (arr[i] == '5'){
            arr[i] = '2';
        }ㄴ
        answer += arr[i];      
    }
    return answer;
}

5.12 정규표현식 정규식

split 파라미터는 보통의 string이아니라 패턴이다.
이 패턴을 정규표현식이라고 한다.

regular expression응 정규식, 정규표현식, 정규식표현등으로 불린다.
어떤 패턴이다.

public class C01RegularExpression {
    public static void main(String[] args) {
        //regular expression
        //정규식, 정규표현식, 정규식표현

        String str = "java,css,html,spring";

        String[] arr1 = str.split(",");
        System.out.println(Arrays.toString(arr1));
        //[java, css, html, spring]

        String str2 = "java,  css,   html   ,   spring";
        String[] arr2 = str.split("\\s*,\\s*");
        //앞뒤 공백이 있고 중간에 ,가 있다는 표현이다
        System.out.println(Arrays.toString(arr2));
        //[java, css, html, spring]
    }
}

id가 어떤패턴인지 전화번호가 어떤 패턴인지 등을 검사할때 이 패턴을 사용한다.

정규표현식은 패턴을 표현하는 문자열이다.

5.12.1 matches

String의 matches()메소드는 정규식을 매개변수로 받는다. 파라미터로 패턴을 넣는다.
패턴에 맞으면 true 아니면 false를 리턴한다.

문자 하나 패턴
System.out.println("a".matches("a")); //true
System.out.println("b".matches("b")); //true

5.12.2 character class(문자분류)

[]안에 문자를 그룹으로 묶은 것
분류된 문자중 하나인가?

System.out.println("a".matches("[abc]")); //true
System.out.println("b".matches("[abc]")); //true
System.out.println("d".matches("[abc]")); //false

System.out.println("ab".matches("[abc][abc]")); //true
System.out.println("aa".matches("[abc][abc]")); //true
System.out.println("ac".matches("[abc][abc]")); //true

패턴이 맞냐를 구분하는 것임.

5.12.3 character class(문자분류)-2

소문자만 보고싶다.
System.out.println("a".matches("[abcdefghijklmlopqrstuvwxyz]"));
범위 : '-'로 표현한다
System.out.println("a".matches("[a-z]")); //true

System.out.println("Az".matches("[A-Z][a-z]")); //true
System.out.println("zA".matches("[A-Z][a-z]")); //false

여러 문자범위를 같이 나타내면 범위또는범위이다.
System.out.println("a".matches("[a-zA-Z]")); //true
System.out.println("A".matches("[a-zA-Z]")); //true

숫자범위는 0-9로 나타내면된다.
System.out.println("0".matches("[0-9]")); // true

영문 대소문자 숫자로 이루어진 3글자인가?
System.out.println("010".matches("[0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z]"));
System.out.println("abc".matches("[0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z]"));
System.out.println("aZ3".matches("[0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z]"));

5.12.4 negation(not)

^을 넣으면 된다.

숫자가 아니면 일치 [^0-9]
System.out.println("0".matches("[^0-9]")); //flase
System.out.println("a".matches("[^0-9]")); //true
System.out.println(" ".matches("[^0-9]")); //true

5.12.5 여러 글자 표현하기

quantifier (수량자)

숫자 3개인가? [패턴]{반복횟수}
직전패턴이 몇번 반복되는가?
System.out.println("010".matches("[0-9]{3}")); //true
System.out.println("12".matches("[0-9]{3}")); //false
System.out.println("ab0".matches("[0-9]{3}")); //false

확인해보기
010으로 시작 - 기호, 숫자4자리,-기호 숫자4자리

String pattern = "010-[0-9]{4}-[0-9]{4}";

System.out.println("010-9999-7777".matches(pattern)); //true
System.out.println("010-98767777".matches(pattern)); //false
System.out.println("010-9999-765".matches(pattern)); //false

5.12.6 범위

수량 범위 n~m : {n,m} n개이상 m개이하

a가 1~3번
String pattern = "a{1,3}";
System.out.println("a".matches(pattern)); //true
System.out.println("aa".matches(pattern)); //true
System.out.println(" ".matches(pattern)); //false
System.out.println("aaaa".matches(pattern)); //false
System.out.println("avc".matches(pattern)); //fasle

5.12.7 이상

수량 몇 개이상?
n개 이상 : {n,}

숫자 두개이상
String pattern = "[0-9]{2,}";
System.out.println("09".matches(pattern)); //true
System.out.println("123".matches(pattern)); //true
System.out.println("2".matches(pattern)); //false
System.outs.println("a12".matches(pattern)); //false

5.12.8 1개이상

수량 1개이상?
1개이상 : {1, } == +

String pattern1 = "[a-z]{1,}";
String pattern2 = "[a-z]+";

System.out.println("abc".matches(pattern1)); //true
System.out.println("abc".matches(pattern2)); //true

5.12.9 0개이상

0개이상 {0, } == *

String pattern1 = "[0-9]{0,}";
String pattern2 = "[0-9]*";

System.out.println("123".matches(pattern1)); //true
System.out.println("123".matches(pattern2)); //true

5.12.10 0또는 1개

0개 또는 1개 : {0,1} == ?

String pattern1 = "[0-9]{0,1}";
String pattern2 = "[0-9]?";

System.out.println("1".matches(pattern1)); //true
System.out.println("1".matches(pattern2)); //true
System.out.println("123".matches(pattern1)); //false
System.out.println("123".matches(pattern2)); //false

5.12.11 응용

변수 이름의 패턴을 만들어보자.
영문대소문자, $ , _, 숫자 / 단 숫자가 앞에 오면 안됨

String pattern = "[a-zA-Z$_]+[a-zA-Z0-9$_]*";

System.out.println("modelName".matches(pattern)); //true
System.out.println("$value".matches(pattern)); //ture
System.out.println("#name".matches(pattern)); //false

5.12.12 확인문제

5.12.12.1 모음제거

프로그래머스 120849
answer = my_string.replaceAll("[aeiou]","");

내풀이

  public String solution(String my_string) {
      String answer = "";
      String[] replace = {"a", "e" ,"i", "o", "u"};
      for(int i = 0; i<replace.length; i++) {
          if( my_string.contains(replace[i])) {
              answer = my_string.replaceAll(replace[i], "");
              my_string = answer;
          } else {
      answer =my_string;
      }
      }
      return answer;
  }

나도 몰랐지만 "a" "e"하나씩 넣으면서 정규표현식 검사를 했던 것이다.
-> 더 잘 사용하면 한줄로 가능하다.

answer = my_string.replaceAll("[aeiou]","");

2023.02.24 후기

ArrayCopy 책188쪽
책에 존재하는지 몰랐다. 책을 열심히 공부했다고 생각해도 다 까먹나보다.

정규표현식은 항상봐도 이해는 가지만 언제 어디서 사용할지 잘 모르겟다.
패턴? string matches가서 정규표현식들 보기 혹은 검색하기
https://regexlib.com/RETester.aspx정규표현식 테스트 사이트

패턴? string matches가서 정규표현식들 보기 혹은 검색하기
https://regexlib.com/RETester.aspx정규표현식 테스트 사이트

ArrayCopy 책188쪽
책에 존재하는지 몰랐다. 책을 열심히 공부했다고 생각해도 다 까먹나보다. 시발

정규표현식 배웟다.
항상봐도 이해는 가지만 언제 어디서 사용할지 잘 모르겟다.