2011년 7월 5일 화요일

[자료구조] 스택(Stack)과 큐(Queue)

<스택이란?>

  스택(Stack)이란 쌓아올린다는 의미다.

  따라서 스택 자료구조라는 것은 접시를 쌓듯이, 자료를 차곡차곡 쌓아올린 형태의 구조를 말한다.


<스택의 구조>

  흔히 스택을 FILO라고 한다. First In, Last Out이기 때문이다.

  먼저 들어간 데이터가, 가장 늦게 나오는 것이 스택의 특징이다.

  ■ top : 현재 메모리의 위치와 데이터의 overflow · underflow 파악

  ■ Pop() : top을 통한 데이터의 삭제를 말함
  ■ Push() : top을 통한 데이터의 삽입를 말함

  


  Pop이든 Push든 top이든, 이름은 관용적인 약속이다.

  꼭 정해져있는 것은 아니지만, 이 규칙에 따라 프로그램을 작성하는 것이 좋다.


<스택의 기본예제>

  #include<stdio.h>
  #include<stdlib.h> // system("cls"); 화면 청소를 위한 헤더파일
  #include<conio.h> // getch(); 를 위한 헤더파일
  void init_stack(void); // top의 초기 값을 설정한다  void print_stack(void); // stack을 출력할 때 사용된다
  int top; // overflow와 underflow를 판단하는 기준이 된다  int push(int t); // 데이터를 입력한다, 혹은 쌓는다  int pop(void); // 데이터를 삭제한다, 혹은 꺼낸다
  #define MAX 5 // 메모리는 최대 5개로 제한  int stack[MAX];

  void main()
  {
    int i,t;
    init_stack();
    printf("Input Data : %d개\n",MAX);
    for(i=0;i<MAX;i++) // 예제를 위해 만든 소스라, 메인 부분은 다소 억지스런 부분이 있다
    {
      scanf("%d",&t);
      push(t);
    }
    getch(); // 어느 문자든 입력받을 때까지 대기한다. 입력 데이터 확인을 위해 한번 넣어주었다
    print_stack();
  } 

  void init_stack(void)
  {
    top = -1;
  }

  int push(int t)
  {
    if(top>=MAX-1) // 4를 넘게되면 overflow이므로, 입력할 때 조건검사를 하게 된다
    {
      printf("stack overflow\n");
      return -1;
    }
    stack[++top] = t;
    return t;
  }

  int pop(void)
  {
    if(top<0) // 0보다 작게되면 underlfow이므로, 역시 조건검사를 실행한다
    {
      printf("stack underflow\n");
      return -1;
    }
    return stack[top--];
  }

  void print_stack(void)
  {
    int i;
    system("cls");
    printf("stack contents:top->bottom\n");
    if(top==-1)
      printf("[stack empty]\n");
    for(i=top;i>=0;i--)
    {
      printf("%d",stack[i]);
    }
    printf("\n");
  }


<큐란 무엇인가?>

  큐(Queue)란 입구와 출구가 다른 자료구조로서, 선입선출(First In, First Out)이라 하여 FIFO라고도 불린다.

  말 그대로 먼저 온 사람이, 먼저 일을 마치고 나가는 것이다.


<큐의 구조>

  ■ front : 맨 앞을 나타내는 위치
  ■ rear : 맨 뒤를 나타내는 위치

  ■ enQueue : rear에서 이루어지는 삽입 연산을 나타냄
  ■ deQueue : front에서 이루어지는 삭제 연산을 나타냄
  


  스택과 큐에서의 연산을 비교하자면 이렇다.



<큐의 기본예제>

  #include <stdio.h>
  #include <stdlib.h>
  #include <conio.h>
  #define MAX 10
  const int front = -1; // front는 변하지 않는 값이므로, const로 값을 고정시켜 놓았다
  
int rear;
  int queue[MAX];
  void init() // 초기 설정 부분, 위에서 초기화하지 않고 분리한 이유는 언제든 이 함수를 통해 초기화가 진행되도록 하기 위해서다
  
{
    rear = -1;
  }
  void enQueue()
  {
    if(rear==9) // 최대 값을 넘기면, 조건 검사를 통해 Overflow를 출력해준다
    
{
      printf("\nQueue is Overflow, You can't Input Data");
      getch();
    }
    else // 그렇지 않다면, 데이터를 입력한다
    
{
      printf("\nInput Data : ");
      scanf("%d",&queue[++rear]);
    }
  }
  void deQueue()
  {
    if(rear==front) // rear와 front가 같아지면, 데이터가 없는 것이므로 조건 검사를 실행
    
{
      printf("\nData Empty, Please Input Data");
      getch();
    }
    else // 아니면 rear의 위치를 감소시킨다
    
{
      --rear;
    }
  }
  void print() // 출력부분, 원래는 따로 있으나, 원활한 확인을 위해 입력과 삭제 부분에도 출력이 되도록 하였다
  
{
    int i;
    system("cls");
    for(i=front+1 ; i<=rear ; i++)
    {
      printf("%d\t",queue[i]);
    }
    printf("\n\nrear : %d\n",rear);
    printf("front : %d",front);
  }
  void main()
  {
    int sel;
    init();
    while(1)
    {
      printf("\n\n1.put  2.get  3.print \n\n");
      printf("Select Number : ");
      scanf("%d",&sel);
      switch(sel)
      {
        case 1:
          enQueue(); system("cls"); print(); break; // 원래는 print()가 없는 것이나
        
case 2:
          deQueue(); system("cls"); print(); break; // 예제의 확인을 위해 넣어놓았다
        
case 3:
          print(); break;
        default:
          system("cls");
          printf("Fail Your Number");
      }
    }
  }

[Tip] X-code 환결설정 : 보다 빠른 개발을 위한

그동안 파일을 찾고, 콘솔을 찾고 너무 귀찮은 과정이었을 것이다.

또한 빌드결과를 확인하는 과정도 마찬가지였을 것이다.

과연 이를 해결할 방법이 없겠는가?

물론 있다. 다만 따로 설정을 해야한다.

설정하기 전에, 모든 X-code 파일을 닫기 바란다. 


1. 상위의 X-code 버튼을 누른 후에, Preference를 누른다.

  


2. Preference를 누르면, 바로 General 탭이 열려있을 것이다.
   
    거기서 바로 'Layout'이 보이는가? default로 활성화 되있는 것을 'All-In-One'으로 바꾸자

  .


3. 자, 다시 X-code Project를 열게되면, 좌측상위와 가운데 상위에 새로운 것들이 생긴 것이 보일 것이다.
 

 
4. 왼쪽부터 보자. Project 버튼과 Debug 버튼이 보인다. 

    Project는 우리가 지금까지 작업한 창이고, 그동안 Console을 일일이 누를 필요없이 이 Debug 버튼을 누르면 된다.

    


5. 각각의 버튼에 대한 설명은 이렇다.

    

    Detail : 모든 파일을 볼 수 있다. Class나 Resource를 열기 귀찮다면, 이 곳을 통해 바로 클릭하자.

    Project Find : 프로젝트 내의 함수, 메소드 등 입력한 키워드가 어디에 있는지 모두 보여주고, 또 교체도 할 수 있다.

    SCM Results : Source Code Management의 약자로, 공동으로 개발할 경우에 사용되므로 지금 사용할 일은 없다.

    Build Results : Error나 Warning을 확인할 수 있다. Debug시 유용하게 쓰인다.


중요한 부분은 아니니, 각각의 기능이 무엇을 뜻하는지 알아야 할 이유도 의미도 없다.

All-In-One 설정을 함으로써 얻는 것은 Console에 쉽게 접근할 수 있다는 것과 Build Result를 메세지와 함께 볼 수 있다는 것이다.

이 2가지가 중요한 이유는 여러분이 개발을 하다가 앱이 죽거나 Error·Warning이 났을 경우 봐야할 것이 이 2가지이기 때문이다.

Console에 관한 내용은 다음 장에서 알아보도록 하고

Build Results는 Error나 Warning의 메시지가 친절하게 나오므로, 바로 위를 보면서 잘못된 부분을 바로 잡으면 된다.

이상으로 X-code 환경설정에 관한 부분을 마치도록 하겠다.

[Android] SOAP, ksoap2 라이브러리 이용해 파싱하기


SOAP

  여러분 안녕하십니까?

  오늘은 .NET 환경으로 구성된 WebService와 통신하는 방법을 알아보고자 합니다.


SOAP 정의

  Simple Object Access Protocol의 약자로서, SOAP에 대한 개념을 일단 검색을 통해 확인하시기 바랍니다.

  간단히 말하자면, Http 프로토콜로 통신하면서 표준규약인 XML을 주고 받자는게 골자입니다.

  그러나 일각에서는 Simple이라는 말이 무색할만큼, SOAP의 응용은 너무나 깊고 복잡하다는 뜻에서

  SOAP를 Service Oriented  Acchitecture Protocol이라고 부르기도 합니다.

  결론은 RSS처럼 특정 규악을 따른 XML에 불과하다고, 일단 그렇게 생각하시기 바랍니다.


SOAP 사용

  결과부터 먼저 얘기하자면 소스는 이렇습니다.

  주석 처리한 것은 없어도 무방합니다. 최소한의 소스를 위해 이렇게 했습니다.

  한 가지 주의하실 점은 NAMESPACE 뒤에 반드시 '/'를 잊지 말라는 겁니다.

  만약 그렇게 되면, WebService에 연결은 되나 Parameter가 전혀 연결되지 않는 현상이 일어나게 됩니다.

  주의하시기 바랍니다.



SOAP 방법

  먼저 Library를 다운 받으셔야 할 겁니다.

  'ksoap2'라는 것이 오늘 우리가 사용할 라이브러리입니다. Lite Version과 Full Version이 있습니다.

  개인적인 실험 결과, Full Version만 필요한 것이 아니라 Lite Version인 Core도 필요합니다.

  그래서 2개를 다 다운받자는 얘깁니다.


  Lite Version Link (Name : ksoap2-j2me-core-2.1.2.jar)

  Full Version Link (Name : ksoap2-j2me-full.jar)


  어떤 사이트에보니 mail.jar니 activation.jar가 필요하더라

  뭐 이런 얘기가 있던데, 다 필요없습니다. 이 2개만 받아주세요.


  자, 이제 받은 것은 연결해야겠죠?

  지금 만든 Project는 Java Project입니다.

  일단 안드로이드에 적용하기 전에 단위 테스트를 하는 것이 좋겠죠?

  이제 프로젝트를 우클릭 한 후, Properties를 선택합니다. 혹은 바로 Alt + Enter를 누르셔도 무방합니다.

  


  이렇게 Add External JARs를 통해, 라이브러리를 추가합니다.



  이제 소스 코드를 공개하도록 하겠습니다.

  package com.wapple.soap;
  import org.ksoap2.SoapEnvelope;
  import org.ksoap2.serialization.SoapObject;
  import org.ksoap2.serialization.SoapSerializationEnvelope;
  import org.ksoap2.transport.HttpTransportSE;

  public class SOAP {
    private final String SOAP_ACTION = "http://tempuri.org/UserLogin";   
    private final String METHOD_NAME = "UserLogin";    
    private final String NAMESPACE = "http://tempuri.org/"; // '/' Don't take out this !  
    private final String URL = "http://121.253.15.19/account.asmx";  

    public void ksoap2(){
 
      SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
      request.addProperty("userid", "asdf");
      request.addProperty("userpwd", "asdf");
      request.addProperty("udid", "1");
      SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
      envelope.setOutputSoapObject(request);
      envelope.dotNet=true;
 
      HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
      System.out.println(request); // Confirm Parameters
 
      try {
        androidHttpTransport.call(SOAP_ACTION, envelope);
        String result = envelope.getResponse().toString();
        System.out.println(result); // Confirm Result
      } catch (Exception e) {         
        e.printStackTrace();
      } 
    }

    public static void main(String[] args) {
      SOAP soap = new SOAP();
      soap.ksoap2();
    } 

  }

  이 코드는 이미 검증했기 때문에, 혹시 에러가 나게 된다면 다시 한 번 신중하게 코드를 분석하시기 바랍니다.

  envelope.dotNet=true;

  이 부분도 은근히 빠뜨리기 쉽습니다. 주의하시고 꼭 삽입하시기 바랍니다.


SOAP 정리

  물론 라이브러리를 사용하지 않고 .append 등을 통해 일일이 코딩할 수도 있습니다.

  그러나 굳이 있는 라이브러리를 버려둔 채, 하드 코딩을 할 필요는 없다고 생각합니다.

  하지만 개념은 알아야겠죠? SOAP의 개념에 대해 다시 한 번 확인하시기 바랍니다.

  그러니까 하드코딩을 하면 어떻게 될까요? 한마디로 XML을 만들어서 요청하면, XML이 오게되고 그것을 파싱하는거죠.

  마지막으로 안드로이드 코드는 이것을 바탕으로 응용하시기 바랍니다. 핵심 코드와 라이브러리만 복사하면 됩니다.

  이상으로 오늘은 마치도록 하겠습니다. 이상입니다. 

   *  혹시나 해서 Code를 포함한 Project와 jar파일을 첨부합니다.

[Spring] 스프링 게시판 만들기

앞서 내용을 보면서 설치가 다 끝났으리라 생각됩니다.

자, 이제 실행시켜 봅시다.


Loading이 되면서 toolSuite가 동작이 될 겁니다.


먼저, 게시판을 만들거니까 간단하게 Dynamic Web Project 하나 Click 해주세요.



물론 서버는 설치해 놓으셨겠죠?



그렇게 만든 다음에는 이제 본격적인 Spring 설정을 해둬야겠죠?

다시 New에서 Spring Bean Configuration File을 Click 해줍시다.



먼저, applicationContext.xml이라는 이름으로 생성해줄겁니다.


(이때, Finish를 누르시면 설정하는 화면이 나오지 않습니다. Next를 눌러주세요)

여기서 beans는 기본으로 설정되어 있구요. 이제 추가로 설정할 것은 선택해주어야 합니다.

먼저 Context를 눌러줍니다. 그리고 밑에 3.0을 선택합니다. 우리는 3.0을 가지고 놀거니까요.

이런 식으로, mvc · tx · task를 선택해줍니다.



잘 보면 http://www 맨 끝에 우리가 선택한 context · mvc · tx · task가 보일겁니다.

여기서 설정을 2줄만 해주면 됩니다.

<context:annotation-config></context:annotation-config>
<context:component-scan base-package="org.thinker.*"></context:component-scan>

여기서 base-package에는 여러분이 임의대로 설정하실 수 있습니다.

'component-scan'이라고 쓰여있는 걸 보니, 벌써 느낌이 오시죠?



이 applicationContext.xml은 src 밑에 두어야 합니다.

그런데 일반적인 Project Explorer로는 할 수가 없구요. Navigator를 통해야만 합니다.

Window - ShowView - Navigator를 눌러주시면 됩니다.



이렇게 Navigator에서 복사하면, src 밑에 applicationContext이 잘 붙게 됩니다.



이번에는 dispatcher-servlet.xml을 만들겁니다.



이번에는 context만 선택해주면 됩니다.



dispatcher-servlet.xml의 위치는 WEB-INF 밑에 위치해야 합니다.



이제 web.xml을 설정해줘야 합니다.


위의 이미지는 바로 이 코드입니다.

 <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
 </context-param>
 <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
 </servlet-mapping>

이 부분을 추가해주면 됩니다.


이제 Library를 추가해봅시다.

아까 설치할 때 받았던 zip 파일을 해제하고, lib 안에 있는 파일을 모두 추가해줍시다.

또한 commons-logging.jar도 추가해줍시다.


그 다음에는 이제 package와 class를 만들어주면 되는데요.

package는 우리가 아까 설정해둔 이름이 앞에 포함되어야 합니다.



기존에 web.xml에 ServletMapping을 길게 설정해야했던 것을

Spring에서는 이렇게 간단하게 설정할 수 있습니다.

@Controller 라고 걸어주어야, @RequestMapping을 찾을 수 있습니다.



이제 실제로 출력되는지 확인해봐야겠죠? (http://localhost:8080/SpringExample/project/add.do)

이렇게 SpringExample/project/add.do

한마디로 '프로젝트이름/클래스/메소드.do'라고 하면 됩니다.



잘 출력이 되고 있습니다.



잘 따라오셨는지요?

일단은 이해를 돕기 위해, WAR 파일을 첨부해두었습니다.


너무 사용법 위주의 설명이라 죄송합니다.

이론과 원리에 바탕한 기초를 설명해야 하는데, 아직 제가 Spring에 대한 이해가 높지 않습니다.

저도 다시 공부를 한 후에, 원리를 제대로 설명하도록 노력하겠습니다.


이외에도 Spring은 많은 기능을 담고 있습니다.

제가 공부하는대로 하나씩 소개하도록 하겠습니다.


이상입니다.