level 1. 나누어 떨어지는 숫자 배열 (java)

|

문제출처


문제

divisible 메소드는 int형 배열 array와 int divisor를 매개변수로 받습니다. array의 각 element 중 divisor로 나누어 떨어지는 값만 포함하는 새로운 배열을 만들어서 반환하도록 divisible에 코드를 작성해 보세요.

예를들어 array가 {5, 9, 7, 10}이고 divisor가 5이면 {5, 10}을 리턴해야 합니다.

풀이코드

  • ArrayList 에 조건에 맞는 값을 추가하고, 이를 다시 Array 로 변경하여 리턴하였다.
  • ArrayList 는 .toArray() 를 통해서 int[] 배열로 쉽게 변경되지 않는다. (Integer, int 의 차이 때문에)
  • 따라서 ArrayList 내부의 모든 element 를 int로 형변환 해야한다.
    이때 stream의 mapToInt 메소드를 활용하면 간단하게 처리 가능하다.
import java.util.Arrays;
import java.util.ArrayList;

class Divisible {
    public int[] divisible(int[] array, int divisor) {
      ArrayList<Integer> divArray = new ArrayList<Integer>();
      for(int i : array){
          if(i % divisor == 0){
          divArray.add(i);
        }
      }

      int[] ret = new int[divArray.size()];
      for(int i=0; i<ret.length; i++){
        ret[i] = divArray.get(i).intValue();      
      }

      return ret;
    }

    // 아래는 테스트로 출력해 보기 위한 코드입니다.
    public static void main(String[] args) {
      Divisible div = new Divisible();
      int[] array = {5, 9, 7, 10};
      System.out.println( Arrays.toString( div.divisible(array, 5) ));
    }
}

다른사람 코드

import java.util.ArrayList;
import java.util.Arrays;

public class Divisible {
    public int[] divisible(int[] array, int divisor) {
      ArrayList<Integer> ret = new ArrayList<>();
      for (int i = 0; i < array.length; i++) {
          if (array[i] % divisor == 0) {
              ret.add(array[i]);
          }
      }

      return ret.stream().mapToInt(i -> i).toArray();
    }

    // 아래는 테스트로 출력해 보기 위한 코드입니다.
    public static void main(String[] args) {
        Divisible div = new Divisible();
        int[] array = { 5, 9, 7, 10 };
        System.out.println(Arrays.toString(div.divisible(array, 5)));
    }
}
import java.util.Arrays;

class Divisible {
    public int[] divisible(int[] array, int divisor) {
        //ret에 array에 포함된 정수중, divisor로 나누어 떨어지는 숫자를 순서대로 넣으세요.
        return Arrays.stream(array).filter(factor -> factor % divisor == 0).toArray();
    }
    // 아래는 테스트로 출력해 보기 위한 코드입니다.
    public static void main(String[] args) {
        Divisible div = new Divisible();
        int[] array = {5, 9, 7, 10};
        System.out.println( Arrays.toString( div.divisible(array, 5) ));
    }
}

배운점

  • ArrayList 는 .add() 메소드를 통해서 요소를 추가할 수 있지만, Array는 array[0] 과 같이 index를 사용해야 한다.
  • Arrays.toString() 를 통해서 배열을 그대로 print 할 수 있다. (Returns a string representation of the contents of the specified array.)
  • .stream() 을 통해서 collections 를 좀 더 편리하게 처리할 수 있다. (API 문서, 참고 글)

level 1. 가운데 글자 가져오기 (java)

|

문제출처


문제

getMiddle메소드는 하나의 단어를 입력 받습니다.
단어를 입력 받아서 가운데 글자를 반환하도록 getMiddle메소드를 만들어 보세요. 단어의 길이가 짝수일경우 가운데 두글자를 반환하면 됩니다.
예를들어 입력받은 단어가 power이라면 w를 반환하면 되고, 입력받은 단어가 test라면 es를 반환하면 됩니다.

풀이코드

  • 인자로 주어진 stirng의 길이를 구하여, .length()
  • 홀수인 경우 문자열.charAt(위치)를 활용하여 가운데 글자를 char 자료형으로 가져온다.
    • 이 경우 함수의 리턴 자료형이 String 이기 때문에 오류가 발생한다.
    • char -> String 으로 변환하는 가장 효율적인 방법은 Character.toString(대상) 이다.
  • 짝수인 경우 문자열.substring(시작, 끝)으로 가운데 글자들을 String 자료형으로 가져올 수 있다.
class StringExercise{
    String getMiddle(String word){
    int len = word.length();
    if (len % 2 == 1){
      // return word.charAt(len/2)+"";
      // char > Stirng 형변환
      // Least efficient and most memory-inefficient, but common amongst beginners because of its simplicity
      return Character.toString(word.charAt(len/2)); //  Most efficient way
    }else{
      return word.substring(len/2-1, len/2+1);        
    }
  }
  // 아래는 테스트로 출력해 보기 위한 코드입니다.
  public static void  main(String[] args){
    StringExercise se = new StringExercise();
    System.out.println(se.getMiddle("power"));
  }
}

다른사람 코드

  • .substring() 메소드를 활용하면 Stirng 으로 리턴값을 받을 수 있다.
  • 3항 연산자를 활용한다.
class StringExercise{
    String getMiddle(String word){
      int length = word.length();
      int index = length / 2;
      return (length%2==0) ? word.substring(index-1, index+1) : word.substring(index, index+1);
    }
    // 아래는 테스트로 출력해 보기 위한 코드입니다.
    public static void  main(String[] args){
      StringExercise se = new StringExercise();
      System.out.println(se.getMiddle("power"));
  }
}

Self Number (python)

|

문제

어떤 자연수 n이 있을 때, d(n)을 n의 각 자릿수 숫자들과 n 자신을 더한 숫자라고 정의하자.
예를 들어
d(91) = 9 + 1 + 91 = 101
이 때, n을 d(n)의 제네레이터(generator)라고 한다. 위의 예에서 91은 101의 제네레이터이다.
어떤 숫자들은 하나 이상의 제네레이터를 가지고 있는데, 101의 제네레이터는 91 뿐 아니라 100도 있다.
그런데 반대로, 제네레이터가 없는 숫자들도 있으며, 이런 숫자를 인도의 수학자 Kaprekar가 셀프 넘버(self-number)라 이름 붙였다.
예를 들어 1, 3, 5, 7, 9, 20, 31 은 셀프 넘버 들이다.
1 이상이고 5000 보다 작은 모든 셀프 넘버들의 합을 구하라.

풀이코드

def self_number():
    li = []
    for i in range(1,5001):
        li.append(i + sum([int(j) for j in str(i)]))

    return sum(set(range(1,5001)) - set(li))

다른사람 코드

sum(set(range(1, 5000)) - {x + sum([int(a) for a in str(x)]) for x in range(1, 5000)})

level 1. 최대값과 최소값 (Java, Python)

|

문제출처

Java 공부를 시작하고 처음 풀어본 간단한 알고리즘 문제이다.
문자열을 배열로 만드려면 어떻게 하지? 오름차순 정렬은 어떻게 하지?
아직 모르는 것이 많지만 이렇게 하나씩 찾아가면서 익히는게 재미있기도 하고 기억에도 잘 남는 것 같다.

파이썬을 처음 공부하고 알고리즘 문제를 풀기 시작했을 때가 생각난다.
리스트 원소의 합을 구하는 sum() 함수를 찾아보고 메모해둔 글을 다시 읽었는데,
이렇게 간단한걸 모르던 때도 있었구나 싶었다. (옛날 같은데 그게 겨우 3개월 전이라니!)

그래도 다행인건 간단한 문제라면 어떻게 접근해서 해결해야겠다는 그림이 그려진다는 것이다.
그다음에 해야 하는건 원하는 걸 구현하려면 Java의 무슨 메소드, 패키지를 사용해야 하는지 찾아보는 것
그리고 codility 덕분에 시간복잡도에 대한 고민을 한번 더 할 수 있게 된 것 같다.

처음이라 약간 막막한 느낌이 들기는 하지만
이것도 금방 지나가겠지!

문제

getMinMaxString 메소드는 String형 변수 str을 매개변수로 입력받습니다. str에는 공백으로 구분된 숫자들이 저장되어 있습니다. str에 나타나는 숫자 중 최소값과 최대값을 찾아 이를 “(최소값) (최대값)”형태의 String을 반환하는 메소드를 완성하세요. 예를들어 str이 “1 2 3 4”라면 “1 4”를 리턴하고, “-1 -2 -3 -4”라면 “-4 -1”을 리턴하면 됩니다.

풀이코드

Java

접근

  • 문자열을 배열로 변경한다. (.split() 메소드 활용)
  • 배열의 각 요소를 정수로 변경하여 새로운 배열(arrayInt)에 담는다. (Integer.parseInt() 활용)
  • 배열을 오름차순으로 정렬한다. (Arrays.sort() 활용)
  • 맨 처음 요소(최소값) 맨 마지막 요소(최대값)을 문자열로 리턴한다.

고민

  • sorting 을 하려면 최소 O(N LogN)의 시간복잡도가 발생한다.
  • 차라리 배열을 순회하면서 최대값, 최소값을 찾는게 효율적일 것 같다.
import java.util.Arrays;

public class GetMinMaxString2 {
	public String getMinMaxString(String str) {
		String[] array = str.split(" ");
		int[] arrayInt = new int[array.length];

		for (int i = 0; i < arrayInt.length; i++) {
			arrayInt[i] = Integer.parseInt(array[i]); // 배열의 각 요소를 정수로 변경
		}

		Arrays.sort(arrayInt); // 최소 O(N LogN)의 시간복잡도
		String result = arrayInt[0] + " " + arrayInt[arrayInt.length - 1];

		return result;

	}

	public static void main(String[] args) {
		String str = "1 2 3 4";
		GetMinMaxString2 minMax = new GetMinMaxString2();
		System.out.println("최소값과 최대값은?" + minMax.getMinMaxString(str));
	}
}

Python

  • min, max 함수를 사용해서 간단하게 구현 가능하다.
def solution(str):
    li = str.split(' ')
    return print("최소값과 최대값은", min(li), max(li))

다른사람 풀이

public class GetMinMaxString {
	public String getMinMaxString(String str) {
		String[] tmp = str.split(" ");
		int min, max, n;
		min = max = Integer.parseInt(tmp[0]);
		for (int i = 1; i < tmp.length; i++){
			n = Integer.parseInt(tmp[i]);
			if (min > n) min = n;
			if (max < n) max = n;
		}

		return min + " " + max;

	}

	public static void main(String[] args) {
		String str = "1 2 3 4";
		GetMinMaxString minMax = new GetMinMaxString();
		System.out.println("최대값과 최소값은?" + minMax.getMinMaxString(str));
	}

}

170605-0611_TIL

|

6월 11일 (일)

오늘 한 일

  • tryhelloworld java 강의를 들었다. 같은 개념에서 대해서 생활코딩, 점프투자바와는 다르게 설명하는 부분이 있어서 도움이 되었다. 특히 String 클래스의 인스턴스 생성방식에 따라서 사용하는 메모리 영역이 다르다는 부분이 새로웠다. 관련 자료를 찾아서 공부하면서 자바의 메모리 사용방식에 대해서도 알 수 있었다.
    • 리터럴 방식 (ex. String str1=”hello”) : heap 메모리 영역의 string constant pool 을 사용
    • 일반적인 new 연산자를 통한 방식 (ex. String str2= new String(“hello”)) : heap 메모리 영역 사용
  • java를 사용하여 간단한 알고리즘 문제를 풀었다.

6월 10일 (토)

오늘 한 일

  • 여자개발자모임 10주년 세미나에 참석했다.
    • 오랜 시간 개발을 해오신 여자 개발자 분들의 이야기를 들을 수 있어서 좋았다. 개발자로 커리어를 바꾸기로 결심했을 때, 앞으로 계속 일을 하고싶다 는 이유가 컸다. (물론 가장 큰 이유는 재미) 현업에서 10년 이상 개발자로 일하시는 분들을 만나는 것만으로 용기를 얻는 기분이 들었다.
    • 요즘 꼭 읽고 싶은 알고리즘 책이 있었는데 (Hello Coding 그림으로 개념을 이해하는 알고리즘) 마침 세미나에서 선물로 받았다! 야호!

image_uploaded_from_ios_1024


6월 9일 (금)

오늘 한 일

  • 점프투자바를 읽고 실습했다.
  • 간단한 알고리즘 문제를 풀었다.

6월 8일 (목)

오늘 한 일

  • 생활코딩 Java 강의를 완주했다. 야호!
    • 총 5일이 걸렸다. 전체를 빠르게 보고 나중에 실습을 천천히 하라는 조언대로 자바의 문법을 빠르게 훑어본다는 목표로 강의를 들었다. (하지만 실습을 안하고 영상만 보는건 참으로 지루하다..)
    • 언어 소개부터 Collections Framework 까지를 다룬 강의를 통해서 받은 Java에 대한 인상은 아래 3가지 정도인 것 같다.
      • 1) 엄격하다 (데이터 타입, 리턴 값, 매개변수의 갯수, 접근제어자)- javascript, python과 Java의 가장 큰 차이점 중 하나라고 생각한다.
      • 2) 자료구조를 알면 더 잘 이해할 수 있는 언어구나 - 자료구조 학습에 대한 필요성은 python 사용자 보다 Java 사용자에게 훨씬 더 클 거라는 생각이 들었다. (특히 Collections Framework를 잘 사용하기 위해서라도)
      • 3) 객체지향 객체지향!! (인터페이스, 추상화, 다형성, 제너릭, 오버로딩, 오버라이딩) - 컴퓨터 공학 수업에서 막연하게 느껴졌던 것들이 여기서 구체적으로 다가왔다.
    • Java를 언젠가는 공부해야 한다는 마음의 부채감이 아주 조금은 덜어진 것 같다. 이제 점프투자바 를 읽으면서 실습을 해보려고 한다.
  • 점프투자바를 읽고 실습했다.
    • 자료형, 제어문

6월 7일 (수)

오늘 한 일

  • 생활코딩의 Java 강의를 들었다.

6월 6일 (화)

오늘 한 일

  • 생활코딩의 Java 강의를 들었다.
    • 파이썬을 통해서 객체지향의 개념을 배웠을 때 쉽게 공감이 되지 않았던 부분이 있었다. (abstract, Interface, polymorphism, overriding, overloading 등) 자바는 객체지향을 강제하고 엄격한 언어라서 그럴까? 생활코딩 수업을 들으면서 막연하게 느껴졌던 개념들이 좀 더 구체적으로 다가오는 인상을 받았다.
  • 자바를 활용해서 간단한 알고리즘 문제를 풀어보았다.

6월 5일 (월)

오늘 한 일

  • 생활코딩의 Java 강의를 들었다.
    • 엄격한 문법 덕분에 byte, int, double, float, char 등 다양한 데이터 타입과 각각의 메모리 크기에 대해서 공부할 수 있었다.
    • javascript, python에도 객체지향의 개념은 있지만, java에서의 객체지향은 더 크고 특별한 의미를 가진 것 같다. java를 공부하면서 객체지향에 대해서 더 잘 이해할 수 있지 않을까 기대해본다.
  • java를 활용해서 간단한 알고리즘 문제를 풀어보았다.