코딩과 결혼합니다

230615 - 자료구조 요리 레시피 메모장 만들기 본문

2세/기타

230615 - 자료구조 요리 레시피 메모장 만들기

코딩러버 2023. 6. 15. 00:40
728x90

조건 & 예시

더보기

입력값

 

-저장할 자료구조명을 입력합니다. (List / Set / Map)

-내가 좋아하는 요리 제목을 먼저 입력합니다.

-이어서 내가 좋아하는 요리 레시피를 한문장씩 입력합니다.

-입력을 마쳤으면 마지막에 “끝” 문자를 입력합니다.

 

 출력값

 

-입력이 종료되면 저장한 자료구조 이름과 요리 제목을 괄호로 감싸서 먼저 출력 해줍니다.

-이어서, 입력한 모든 문장앞에 번호를 붙여서 입력 순서에 맞게 모두 출력 해줍니다.

 

 

 

내가 짠 코드 (List로 저장된 레시피)

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

        System.out.println("저장할 자료구조명을 입력해주세요. (List / Set / Map)");
        String listType = sc.nextLine();

         int num = 0;
         String inputText = "";

 

List / Set / Map 을 입력했을때, 입력한 자료구조의 방식으로 레시피를 저장해야 하므로 Switch문을 썼다.

switch (listType) {
     case "List": {
             System.out.println("요리 제목을 입력해주세요.");
             String title = sc.nextLine();

             System.out.println("레시피를 입력해 주세요.");
              ArrayList<String> strList = new ArrayList<>();

              do {
                      System.out.print("입 력 : ");
                       inputText = sc.nextLine();

                       if(inputText.equals("")) break;

                       strList.add(inputText);
               } while(true);

              System.out.println("입력받은 레시피를 모두 출력합니다.");

              System.out.println("-------------------------------");

              System.out.println("[" + listType + "으로 저장된 " + title + "]");
              for (int i = 0; i < strList.size() ; i++) {
                     System.out.println(++num + ". " + strList.get(i));
              }
              break;
}

자료 구조명(liteType)을 "List"로 입력 하였을 때 실행되도록 한 내용들이다.

1. 요리 제목 입력받기

2. 레시피는 "끝"을 입력하기 전까지는 계속 값이 저장되어야 하므로 크기가 가변적으로 늘어나는 동적배열인 ArrayList로 

    선언/생성해주었다. 

3. 위에 먼저 선언해준 String 타입의 inputText = ""; 에 sc.nextLine(); 로 사용자의 입력값을 받을 수 있게 한다.

4. while(true) -> "끝" 을 입력하지 않으면 계속 true이므로 do-while문을 반복하며 입력값을 받아 strList에 저장해준다.

5. if문 -> inputText.equals("") 일때는 break로 do-while 문을 나간다. 

6. "입력받은 레시피를 모두 출력합니다.", "---------------------------", "제목" 순으로 println을 한다.

7. for문으로 strList의 크기( =Size() ) 만큼 돌며 입력된 순서대로 strList.get(i) 하여 레시피를 출력한다.

8. ++num을 하여 1부터 나오도록 하였고, for문을 돌때마다 num값이 1씩 커진다.

9. break로 로직을 종료한다.

 

 

내가 짠 코드 (Set으로 저장된 레시피)

더보기
case "Set": {
        System.out.println("요리 제목을 입력해주세요.");
        String title = sc.nextLine();

        System.out.println("레시피를 입력해 주세요.");
        Set<String> strSet = new LinkedHashSet<>(); //LinkedHashSet .add() 한 순서대로 값이 저장된다

        do {
               System.out.print("입 력 : ");
               inputText = sc.nextLine();

               if(inputText.equals("")) break;
              strSet.add(inputText);
          } while(true);

          System.out.println("입력받은 레시피를 모두 출력합니다.");

          System.out.println("-------------------------------");

          System.out.println("[" + listType + "으로 저장된 " + title + "]");

          Iterator<String> iter = strSet.iterator();
          while (iter.hasNext()){
                 System.out.println(++num + ". " + iter.next());
           }
           break;
 }

자료 구조명(liteType)을 "Set"으로 입력 하였을 때 실행되도록 한 내용들이다.

위와 중복되는 내용은 넘어가겠다.

1.Set<String> strSet = new LinkedHashSet<>();

   Set은 순서가 없는 데이터의 집합이다. 따라서 입력한 레시피의 순서가 보장되지 않기 때문에 .add()를 한 순서대로 값을

   저장할 수 있는 LinkedHashSet 을 썼다.

2. while(true) -> "끝" 을 입력하지 않으면 계속 true이므로 do-while문을 반복하며 입력값을 받아 strSet에 저장해준다.

3. Set을 출력할때는 순서가 없기 때문에 배열(Array)이나 List 처럼 .get(인덱스)로 값을 가져올 수 없고 Iterator를 통해 가져와야 한다. 

4. strSet.iterator()로 strSet 값을 iterator에 담은 후 .next를 통해 하나씩 뽑아낸다.

 

++

Set 주요 메소드 

LinkedSet

- 다른 Set들과 동일하게 중복은 허용하지 않으나

.add() 한 순서대로 값이 저장된다

 

TreeSet

- 오름차순으로 값을 정렬해 가지고 있으며

다른 set보다 대량의 데이터를 검색할 시 훨씬 빠르다

 

Set에 값 추가하기

set명.add("값");

 

Set 크기 확인하기

set명.size();

 

Set 내용 출력할 수 있게 Iterator 안에 담기

Iterator<데이터타입> iterator명 = set명.Iterator();

 

Iterator 안에 담은 set 출력하기

Iterator명.next();

or

while(iterator명.hasNext()) {

iterator명.next(); // 값 없을때까지 계속 출력

}

 

참 : https://wakestand.tistory.com/111

 

자바 Set 사용법부터 출력까지

일단 자바의 Set을 알아보기에 앞서서 List를 알아두면 참 좋은데 List에 대해서는 아래 글을 참고해주면 된다 자바 List 정의부터 출력까지 List는 자바의 자료형 중 하나로 배열과 비슷하지만 결정

wakestand.tistory.com

 

 

내가 짠 코드 (Map으로 저장된 레시피)

더보기
case "Map": {
        System.out.println("요리 제목을 입력해주세요.");
        String title = sc.nextLine();

        System.out.println("레시피를 입력해 주세요.");
        ArrayList<String> strList = new ArrayList<>();


        Map<String, String> strMap = new LinkedHashMap<>();

        System.out.println("Key-레시피를 입력하세요.");
        System.out.println("레시피를 다 적었으면 끝 입력.");

Map 은 key-value 구조로 구성된 데이터를 저장할 수 있다. 따라서 Key - value 두 가지를 입력 받아야 한다.

나는 key와 value 값을 모두 String type으로 받을 것이다.


        String input = "";
        while (!input.equals("")) {

"input"이 "끝" 이 아닐때 while문을 반복한다.


               System.out.print("Key: ");
               String key = sc.nextLine();

               System.out.print("레시피: ");
               String value = sc.nextLine();

key와 레시피 값을 입력 받는다.



               System.out.println("더 입력하면 enter, 끝내려면 '' 을 입력해주세요.");
               strMap.put(key, value);

                input = sc.nextLine();
          }

strMap에 .put으로 (key,value) 값을 저장한다.

그리고 입력한 값이 "끝"이면 while문을 나온다.


          System.out.println("입력받은 레시피를 모두 출력합니다.");

          System.out.println("-------------------------------");

          System.out.println("[" + listType + "으로 저장된 " + title + "]");

          for (String key : strMap.values()) {
                System.out.println(++num + ". " +key);
          }

전체 value 조회 : strMap.values() 형태로 전체 value 값들을 조회


         sc.close();
         break;
     }
     default : System.out.println("잘못된 리스트 타입입니다.");
}

마지막으로 List / Set / Map 이외의 다른 단어가 listType에 입력되면 "잘못된 리스트 타입입니다."라고 알려준다.

 

 

++

Map의 기능들

  • 선언 : Map<String, Integer> intMap 형태로 Key타입과 Value타입을 지정해서 선언합니다.
  • 생성 : new HashMap<>(); 형태로 생성합니다.
  • 추가 : intMap.put({추가할 Key값},{추가할 Value값}) 형태로 Key에 Value값을 추가합니다.
  • 조회 : intMap.get({조회할 Key값}) 형태로 Key에 있는 Value값을 조회합니다.
  • 전체 key 조회 : intMap.keySet() 형태로 전체 key 값들을 조회합니다.
  • 전체 value 조회 : intMap.values() 형태로 전체 value 값들을 조회합니다.
  • 삭제 : intMap.remove({삭제할 Key값}) 형태로 Key에 있는 Value값을 삭제합니다.
  • HashMap : 중복을 허용하지 않고 순서를 보장하지 않음 , 키와 값으로 null이 허용
  • TreeMap : key 값을 기준으로 정렬을 할 수 있습니다. 다만, 저장시 정렬(오름차순)을 하기 때문에 저장시간이 다소 오래 걸림
  • LinkedHashMap : 큰 흐름에서는 HashMap과 동일하다. 하지만 Entry 내에 before, after Entry가 저장되어 있는 것이 특징이다.이를 통해 입력(put 메서드) 순서를 보장할 수 있게 된다.

알게 된 것

더보기

처음에 do-while 문이 아닌 while문으로 사용자의 입력값을 받아오려 했었다.

while (!(sc.nextLine().equals(""))) {
        strList.add(sc.nextLine());
        ++num;
}

하지만 아래 결과 값에서 보듯 (num은 둘째치고 ㅋㅋ) 레시피가 2,4,6,8 처럼 짝수번째만 나오는 것이다.

 

이유를 알려면 Scanner에 대한 제대로된 이해가 필요하다. 

Scanner sc = new Scanner(System.in);

 

 Scanner는 사용자에게 입력 장치로 입력을 받아 그 값을 변수에 저장하는 역할을 한다.

 System.in이 그 입력하는 것인데  키보드라고 생각하면 편하다.

 

inputText = sc.nextLine();

(System.in)키보드로 입력하면 그 값이 sc에 저장되고 그 다음 sc.nextLine()을 하여 내가 지정한 inputText라는 변수로 들어간다. .nextLine()은 뭐하는 애일까?

 

스캐너에서 받아온 현재 cusor 다음 줄을 읽어온다.

 

cusor는 코드를 실행시켰을때 터미널에서 입력을 기다리며 깜빡거리는 저 커서를 말한다.

엔터를 치면 아래와 같이 입력값 뒤에 \n 이 붙는다. (눈에 보이지는 않지만.)

(enter -> [ "\n" or "\r\n" ] 1) 어려워요.\n
저 커서 다음,  \n 의 안에 있는 값. 즉, 내가 키보드로 입력한  "어려워요."  값을 읽어온다. 

 

while (!(sc.nextLine().equals(""))) 

strList.add(sc.nextLine());

 

내가 적었던 코드를 보면 while문의 조건으로 이미 입력한 값이 "끝"과 같은지 비교를 하였다.(이미 엔터를 해서 읽음)그럼 그 다음의 .add(sc.nextLine)에서는 처음 적었던 그 입력 값이 아닌 두 번째로 적은 입력값이 저장 되고 있는 것이다.그래서 짝수번째의 레시피만 저장된 것이다.

 

이를 해결하기 위해서

do {
                      System.out.print("입 력 : ");
                       inputText = sc.nextLine();

 

                       strList.add(inputText);

 

do 에서 먼저 선행으로 입력한 값을 inputText에 넣어 strList에 저장하게 하였다.

 

if(inputText.equals("")) break;

 

다음 inputText에 "끝" 이있는지 비교하여 "끝"이 있다면 더 이상 입력을 받지 못하게 do-while문을 나간다.

결과

더보기

리스트 타입을 잘못 적었을때

 

List로 레시피 저장하기

 

 

Set으로 레시피 저장하기 

 

 

Map으로 레시피 저장하기

...생략