2018년 9월 20일 목요일

java 문자열 안에 문자2개이상 존재 할 경우 출력하기

이번시간에는 자바로 문자열안에 문자의 갯수가 2개이상인것에 대해서 살펴보자.

`문자열안에 문자가 2개 이상 존재하는 문자의 갯수를 출력하기` 이 문장을보면,
우리는 이에맞는 알고리즘이 어떤것들이 있는지 떠올릴 수 있는가?

나는 이러한 알고리즘이 생각났다.

1) 문자열의 갯수만큼 문자열의 맨앞 문자 하나를 문자열 전체를 순환하며 비교
2) 비교하여 갯수들이 몇개있는지 확인하고 이 과정을 반복함

물론 위의 방법이 좋긴하지만, 우리는 더 효율적인 방법이 어떠한 것들이 있는지 잘 생각해보면, 다음과 같다.

1) 문자열의 갯수만큼 문자열안에 존재하는 문자하나를 기준으로 삼는다.
2) 기준이되는 문자를 문자열안에서 전부 제거한다. 그리고 그 제거한 갯수를 센다.
3) 문자열의 갯수만큼 문자열안에 존재하는 문자를 제거했으면, 비교할 데이터들이 줄어들었다. 즉, 문자열안에 문자들끼리 비교가 끝난 것은 제거하여 더 빠르고 복잡하지 않게 계산을 해주어야한다.

다음의 코드들을 살펴보자


예제) 문자열에 문자가 2개이상있는 문자들의 갯수를 출력하시오.
  1. package org.java.project.subproject1;
  2.  
  3. import java.util.Scanner;
  4.  
  5. class StrOverlap{
  6.     public static void StrCounting(String s) {
  7.         System.out.println("\n\"" + s+"\"");
  8.         char str;  // 기준점이 되는 문자
  9.         int i = 0;
  10.         int strExist = 0; // 중복되는 문자가 있는경우 0, 없는경우 -1
  11.         int currentLen;  // 중복된 문자가 있는경우 제거하기 전 길이
  12.         int duplicateCount = 0; // 중복된 문자의 갯수
  13.         String delStr = null;
  14.         while(s.length() != 0)
  15.         {
  16.             str = s.charAt(0);
  17.             System.out.println("\n"+ ++i +") Search : " + str);
  18.             s = s.substring(1, s.length());
  19.             strExist = s.indexOf(str); // 존재한다면 배열 인덱스값, 존재하지 않는다면 -1
  20.  
  21.             if(strExist != -1)
  22.             {
  23.                 currentLen = s.length();
  24.                 delStr = ""+str;
  25.                 s = s.replaceAll(delStr, ""); // 탐색할 문자가 존재하는 위치를 빈공간 즉 제거함.
  26.                 duplicateCount = currentLen - s.length() + 1; // 중복제거된 name.length()값이 몇개인지 세줌.
  27.                 System.out.println("\""+str + "\" is a duplicate of : " + duplicateCount);
  28.             }
  29.             else {
  30.                 System.out.println("Only one exists");
  31.             }
  32.         }
  33.     }
  34. }
  35. public class Exam {
  36.     public static void main(String[] args) {
  37.  
  38.         Scanner sc = new Scanner(System.in);
  39.         System.out.print("Input String  :   ");
  40.         String s = sc.next();
  41.  
  42.         StrOverlap.StrCounting(s);
  43.     }
  44. }
 
▶실행결과

Input String  :   Bananajoke

"Bananajoke"

1) Search : B
Only one exists

2) Search : a
"a" is a duplicate of : 3

3) Search : n
"n" is a duplicate of : 2

4) Search : j
Only one exists

5) Search : o
Only one exists

6) Search : k
Only one exists

7) Search : e
Only one exists

위 처럼 문자열 Bananajoke를 입력받으면 다음과 같이 결과가 나온다.

그래서 문자열들을 출력하고 계산시간까지 효율적으로 하기위해서는
하나의 문자를 전부다 탐색하고 이에 겹치는 문자들은 전부 제거하고 그다음 값을 비교하면서 찾아갈 수 있다.

2018년 9월 10일 월요일

네트워크 OSI 7계층과 프로토콜

이전시간에는 네트워크에 대해서 살펴보았다면, 이번시간에는 네트워크상에서 통신할때 알아야 할 필수적인 OSI7계층과 이 표준적인 통신규약에 해당하는 프로토콜에 대해서 살펴보겠다.

OSI7계층이란 무엇인가?
국제표준기구(ISO)에서 규정한 컴퓨터의 사이의 통신을 위한 약속이다.
그리고 이 약속에 해당하는 것을 프로토콜이라고 한다. 

수 많은 컴퓨터들간의 데이터를 주고 받기(송, 수신)위해서 표준 프로토콜을 따르며, 각 데이터는 OSI7계층에서 각 계층별로 데이터를 송, 수신하기 위한 형태로 맞게 변환해준다.

OSI7계층을 살펴보자,

















 위의 OSI7계층과 TCP/IP 프로토콜들의 모습을 보면, 계층간 서로 연관되어있는 형태를 띄고있다. "OSI7계층을 통해서 데이터를 송, 수신할때 TCP/IP계층 각 프로토콜들에 규격에 맞게 전송을 해야하며 이것들은 계층별로 서로 다른 규칙을 갖고있다" 라고 이해하면 된다.

그렇다면, 왜 이러한 표준화된 프로토콜을 사용해야 하는가?
이는 개발자들을 위해서이다. 만약에 프로토콜이 표준화 되어있지 않다면, 개발자들은 네트워크 상에서 데이터를 주고받을때, 통신프로토콜과 발생하는 모든 일들을 생각하여 프로그램에 포함시켜야한다. 하지만 표준화가 되어있는 통신프로토콜을 사용하게 되면 우리는 발생하는 모든 일들을 포함시킬 필요없이 각 계층별에 맞게 데이터를 쪼개거나 캡슐화시켜서 전송하면 된다. 그러면 개발자들은 편리하게 표준화된 프로토콜 규격을 따르면 된다.

각 OSI-7 계층별로 하는 역할은 다음과 같다.
 - 7계층 Application : 사용자 인터페이스 / 응용프로그램
 - 6계층 Presentation : 데이터 포멧 / 암호화
 - 5계층 Session : 연결유지
 - 4계층 Transport : 패킷생성 / 패킷 오류 관리
 - 3계층 Network : 논리적 주소(IP)관리 / 경로설정
 - 2계층 Data Link : 물리적 주소(MAC)관리
 - 1계층 Physical : 네트워크의 물리적 주소(케이블, 신호방식)

 각 TCP/IP 계층별 프로토콜은 다음과 같다.
 1. Physical : 실제로 데이터 전송방식을 정의함(네트워크가 무선인지 유선인지, 속도, 코딩방식 등)
 2. Data Link : 네트워크가 유선이든 무선이든, 1대 1 혹은 1대 N, AP(Wifi)에 연결된 단말기등을 구별하기 위한 규칙이 필요함. 그래서 다음과 같이 2가지로 나뉨
 - Data Link에서의 상위 : LLC (거의하는 역할이 없다.)
 - Data Link에서의 하위 : MAC (단말기 간의 고유 식별 번호도 포함되어 있어서 이를통해 제조업체를 알 수 있으며, 이는 이더넷이나 와이파이를 포함한 네트워크상에서의 주소로 사용된다.)
 3. Network : 1, 2계층에서 받은 패킷들을 올바른 주소로 잘 전달될 수 있도록 한다. (라우팅 되기 위한 목적) - 라우팅이란? 패킷들을 목적지로 전송하기 위해 경로를 설정하는 걸 의미한다.
또한 1~3계층까지는 Source IP라는 보내는 측의 IP가 이용되는데, 이후 4계층에서는 Destination IP 전송받는 측의 IP주소만 있으면 된다.
 4. Transport : TCP와 UDP로 나뉘며, 패킷의 손실 여부를 파악하며, 패킷을 순서대로 전송을 하는 역할을 한다.
 - TCP역할 : 깨진패킷 확인여부 및 시퀸스 넘버를 통해서 전송할 데이터를 순서대로 정렬하여 전송 가능하게 해준다. 데이터를 올바르게 전송하지 못했을경우, (response 측)재전송을 요청한다.
 - UDP역할 : 깨진패킷만 확인가능. 올바른 순서인지는 보장하지 않는다. 즉 올바르게 전송하지 못했다면, 재전송을 하지 않고 받고 끝낸다.


 패킷들의 데이터 송 수신방법
데이터를 전송하는 송신측(request)에서는 각 계층별로 패킷들을 쪼개어 필요한 데이터를 덧붙이거나 데이터 전송 형식에 맞게 송신한다. 
데이터를 받는 수신측(response)에서는 해당 쪼개어진 패킷들을 캡슐화 하여(원래대로 재정렬) 원상태로 복구 하여 데이터를 읽는다.































네트워크 - 네트워크에 대하여.

이번에는 네트워크 통신에 대하여 살펴보자.


 네트워크란 무엇인가?
: 다른 컴퓨터들과 데이터를 주고받기(송, 수신) 혹은 다른 장치들과의 데이터를 주고받는 행위 등 어떠한 연결을 통해서 정보들을 서로 공유하고 상호정보 교환을 수행하는 형태를 일컫는다. 다음 그림은 일반적인 네트워크 형태를 보여준다.


거대한 망을 이루어서 작업을 하는 모습처럼 보인다.
하지만 모든 네트워크는 위의 형태가 아니다. 여러 형태 중 하나를 표현한 것이며, 어떠한 통신을 하느냐에 따라서 다양한 형태를 갖으며, 그에 효율적인 통신방법에 맞게 설정해주면 된다.

그렇다면, 이 거대한 네트워크라는 망은 어떻게 통신을하느냐?
데이터를 어떠한 형태로 교환하느냐에 따라 통신방법이 달라지는데, 대표적으로 아래와 같다.
1) 회선교환망 (전화기)
2) 패킷교환망
3) 메시지 교환망


우리는 이 3가지 중에서 패킷교환망에 대해서 살펴보겠다.
그전에 네트워크와 인터넷의 차이를 알고있는가?
인터넷 : 데이터를 패킷교환망을 통해서 데이터를 주고받는 방법의 형태이다. 조건이 있다면, 이는 네트워크라는 거대한 망안에 통신하는 형태이다.















즉, 인터넷을 사용하는것은 네트워크안에서 다른 단말기간의 데이터를 송, 수신을 통해 상호작용하는것 같은 말이다.

다음시간에는 이러한 네트워크 통신을 할때 필요한 OSI7계층과 각 계층의 프로토콜들에 대해서 살펴보겠다.



[Java] N-I/O(Non-Blocking) 파일 읽기 쓰기 - GatheringByteChannel, ScatteringByteChannel, ByteBuffer 사용.

우리는 지금까지 다음과 같이 살펴보았다. 1.  InputStream / OutputStream : 입, 출력 스트림을 바이트로 처리하여 읽기, 쓰기. 2.  FileInputStream / FileOutputStream : 입, 출력 스트림을 ...