* 유진호님 감사합니다. =)
출처 : http://www.csharpstar.com/top-20-googl ··· tions%2F

알고리즘 문제 Top20개인데, 풀이 결과는 별거 없는데... 용어가.. 좌절스럽습니다.
일단 문제 옮겨 놓고 용어부터 풀어야 겠네요.

1. Given an unsorted array which has a number in the majority (a number appears more than 50% in the array), find that number?
2. How to detect a cycle in singly linked list?
3. How to merge two sorted linked list, write a program in your favorite programming language i.e. Java,C#
4. Write a Program which checks if two Strings are Anagram or not?
5. How to swap two numbers without using a temp variable, write code which is free from Integer overflow?
6. How to find all pairs of elements in an integer array, whose sum is equal to a given number?
7. Write a function to print nth number in Fibonacci series?
8. Write a function to count a total number of set bits in a 32 bit Integer?
9. Write a function to remove duplicate characters from String?
10. How to find the 3rd element from end, in a singly linked, in a single pass?
11. How to calculate factorial using recursion in C#?
12. C# program to check if a number is Armstrong number or not?
13. Algorithm to check if a number is Prime or not?
14. Algorithm to check if a number is Palindrome?
15. Algorithm to find if Array contains duplicates?
16. Write code to reverse a linked list, if you able to do it using loops, try to solve with recursion?
17. How to rotate an array by a given pivot ?
18. How to remove duplicates from a sorted linked list?
19. How to find sum of digits of a number using Recursion?
20. Sorting an Array using Selection Sort

흐미... -_-;; 용어 몰라서 문제 못풀뻔 했네요.
(물론 불러줘야 인터뷰를 볼 수 있겠지만....)

용어정의부터 
* a number in the Majority : 50%이상을 차지하는 수입니다. 
예를 들면, {1,2,3,4,5,2,2,2,2} 에서 2가 Majority 수가 되겠군요. 간단히 Linq로 해결할 수 있을거 같네요.

* cycle in singly linked list 는 순환 연결리스트 같네요.

* Anagram은 이전에서 다뤘던 앞으로 읽어도 뒤로 읽어도 같은 문자입니다.

* Fabonacci 수열이 있네요. 
파보나치 수열은 간단히 예로 들면 0, 1, 1, 2, 3, 5, 8, 13... 과 같이 바로 앞의 숫자와 현재 숫자를 더한 결과입니다.

* Factorial 을 계산하라네요. 팩토리얼은 예를 들어 3i = 3*2*1 = 6 (고딩때 수학이... 으으으)

* 암스트롱 넘버는 의외인데, 찾아보니 153 = 1^3 + 5^3 + 3^3 = 153 처럼 abc = a^n + b^n + c^n = x 로 n은 자릿수입니다.

* Prime number 는 영원한 수학계의 숙제인 자신외에는 나눌 수 있는 수가 없는 소수입니다. 

* Palindrome number는 anagram하고 똑같이 숫자 131, 121,  22, 11 같은 수로 꺼꾸로 읽어도 같은 수가 됩니다. 
만드는 공식은 "처음수+꺼꾸로한수"로 72 + 27 = 99 가 되는 수입니다.

* Selection Sort는 지난 포스팅에서 했던 배열 정렬 방법중 하나인데, 선택정렬이군요. 

1. {1,2,3,4,5,2,2,2,2} 이 주어졌을때 2가 나오면 되는거네요.
static void Main(string[] args)
{
     int[] _x = new int[]{ 1, 2, 4, 6, 5, 2, 2, 2, 2 };
     var query = _x.GroupBy(x => x).Select(x => new { Key = x.Key, count = x.Count() }).ToList(); //Linq로 먼저 Groupby해서 카운트를 구합니다.
     var isMajority = query.Find(x => x.count >= _x.Length / 2); //배열의 길이의 50%가 넘게 차지하는 수를 찾습니다.
     string result = (isMajority == null) ? "Not Found" : isMajority.Key.ToString();
     Console.WriteLine(result);
     Console.ReadLine();
}



2. 싱글 링크드 리스트에서 순환되는 링크드 리스트를 찾으란 말인즉슨 Child node 가 null이 있으면 순환이 아니고, null이 없으면 Loop돈다는 뜻입니다.
따라서, Linked class를 만들어서 확인해보면 되겠네요.

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace TestCode
{
    class Program
    {
        static private Node head;
        static void Main(string[] args)
        {
            List<Node> _LinkedList = new List<Node>();
            MakeLinkedList(ref _LinkedList, 0);
            MakeLinkedList(ref _LinkedList, 1);
            MakeLinkedList(ref _LinkedList, 2);
            MakeLinkedList(ref _LinkedList, 3);

            SetCheck(_LinkedList); //정작 사용하는건 요거 하나 입니다. -_-;;

            MakeLoopList(_LinkedList);

            SetCheck(_LinkedList);
            Console.ReadLine();
        }

        static void SetCheck(List<Node> _LL)
        {
             var result = _LL.Find(a => a.Child == null);
             if (result == null) Console.WriteLine("Loop Linked List : True"); else Console.WriteLine("Loop Linked List : false");
        }

        #region for Make Linked List 
        static void MakeLinkedList(ref List<Node> _LL, int value)
        {
             if (head == null) AddFirst(ref _LL, value);
             else
             {
                Node _node = new Node { value = value, Child = null };
                _LL.Add(_node);
                Node _current = head;
                while (_current.Child != null)
                {
                     _current = _current.Child;
                }
                _current.Child = _node;
             }
        }

        static void AddFirst(ref List<Node> _LL, int value)
        {
            Node _Head = new Node { value = value, Child = null };
            _LL.Add(_Head);
            head = _Head;
        }
        #endregion 

        static void MakeLoopList(List<Node> _LL)
        {
            _LL.Find(a => a.value == 3).Child = head;
        }

        public class Node
        {
            public int value;
            public Node Child;
        }
    }
}



3번은 좀 멘붕이네요. 2개의 Sort된 Linked List를 Merge하라니... OTL... 뭐 암튼 이건 2번 문제 응용으로 Value를 비교하여 Node를 연결하면 해결되지 않을까? 합니다.
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace TestCode
{
    class Program
    {
        static private Node head;
        static void Main(string[] args)
        {
            //Linked list를 먼저 만듭니다.
            List<Node> _LinkedListA = new List<Node>();
            MakeLinkedList(ref _LinkedListA, 0);
            MakeLinkedList(ref _LinkedListA, 1);
            MakeLinkedList(ref _LinkedListA, 2);
            MakeLinkedList(ref _LinkedListA, 3);

            List<Node> _LinkedListB = new List<Node>();
            MakeLinkedList(ref _LinkedListB, 1);
            MakeLinkedList(ref _LinkedListB, 3);
            MakeLinkedList(ref _LinkedListB, 5);
            MakeLinkedList(ref _LinkedListB, 6);
            
            //Merge할 List를 만들고,
            List<Node> _MergeList = new List<Node>();
            //Merge합니다.
            MergeLinkedList(_LinkedListA, _LinkedListB, ref _MergeList);
            Console.ReadLine();
         }

         //하나로 모아서 Sort한 뒤에 LinkedList를 생성합니다.
         static void MergeLinkedList(List<Node> _A, List<Node> _B, ref List<Node> _C)
         {
              ArrayList A = new ArrayList();
              foreach(Node x in _A) A.Add(x.value);
              foreach (Node x in _B) A.Add(x.value);
              A.Sort();
              foreach (int x in A) MakeLinkedList(ref _C, x);
          }

          #region for Make Linked List 
          static void MakeLinkedList(ref List<Node> _LL, int value)
          {
               if (head == null) AddFirst(ref _LL, value);
               else
               {
                   Node _node = new Node { value = value, Child = null };
                   _LL.Add(_node);
                   Node _current = head;
                   while (_current.Child != null)
                   {
                        _current = _current.Child;
                   }
                   _current.Child = _node;
                }
           }

           static void AddFirst(ref List<Node> _LL, int value)
           {
                Node _Head = new Node { value = value, Child = null };
                _LL.Add(_Head);
                head = _Head;
           }
           #endregion 

           static void MakeLoopList(List<Node> _LL)
           {
                _LL.Find(a => a.value == 3).Child = head;
           }

           public class Node
           {
                public int value;
                public Node Child;
           }

    }
}



4. Anagram 문자열 비교는 이전 포스팅 http://www.wolfpack.pe.kr/920 문제 5번과 동일합니다.

5. 2개의 숫자를 바꾸는 것인데, 임시 변수 사용하지말고 하라니 쬐끔 황당하긴하네요.
만약 A=200 이고 B=100이라면 2개 수의 합은 300이 됩니다. 300을 A에 저장해놓고, A에서 B를 빼면 200, 이걸 B에 할당한뒤에 다시 300에서 B를 빼면 100 올ㅋ~
따라서, 공식은 

A = A + B;
B = A - B;
A = A - B;

static void Main(string[] args)
{
    int A = 100;
    int B = 200;
    A = A + B;
    B = A - B;
    A = A - B;
    Console.WriteLine(A.ToString());
    Console.WriteLine(B.ToString());
    Console.ReadLine();
}


6. 쉬운 단어들 조합인데 해석이 제대로 안되서 까다로운 문제네요. 주어진 값이 나올수있는 배열안 2개의 원소 합을 구하라는 건데.. 간단히 TEST CASE를 작성하면,
{1,2,3,4} 라는 배열이 있다면 5가 나오는 합은 1, 4 / 2, 3 입니다. 6이 나오는 합은 2, 4가 되겠지요?
그냥 For 문 노가다입니다.

static void Main(string[] args)
{
    int[] arrayInt = new int[] { 1, 2, 3, 4, 5 };
    Console.WriteLine(SearchElement(arrayInt, 3));
    Console.ReadLine();
}

static bool SearchElement(int[] _arr, int x)
{
    for (int i = 0; i < _arr.Length; i++)
    {
        for (int y = 0; y < _arr.Length; y++)
        {
            if (i == y) continue;
            if (i + y == x) return true;
        }
    }
    return false;
}


7. 파보나치 수열은 위에 용어정의에서 이미 터치하고 왔습니다. 뭐.. 이것도 별건 없습니다. x = n-1 + n-2 단, 0과 1은 그대로 찍어주면 될 일 같습니다.
Arraylist로 간단히 해결가능할 거 같네요.

static void Main(string[] args)
{
    ArrayList _ar = new ArrayList();
    SetFibonacci(_ar, 12);
    foreach (int x in _ar)
    Console.Write(x + " ");
    Console.ReadLine();
}

static void SetFibonacci(ArrayList ar, int x)
{
    for (int i = 0; i < x; i++) {
        if (ar.Count < 1) { ar.Add(i); continue; }
        if (ar.Count < 2) { ar.Add(i); continue; }
        ar.Add((int)ar[i-2] + (int)ar[i-1]);
    }
}


8.번 문제는 32비트 int형의 bit 카운트 하라는 것같습니다. =)
이건 간단하게 10진수를 2진수로 변환하고나서 1의 갯수를 세면 bit 카운트가 됩니다. -_-;; 
static void Main(string[] args)
{
    int x = 512;
    string bit = Convert.ToString(x, 2); //int.MaxValue 로 대체하면 31이 나와야 합니다. 32비트 int형이니까요...
    int cnt = 0;
    for (int i =0; i < bit.Length; i++)
    {
        if (bit[i].ToString() == "1") cnt++;
    }
    Console.WriteLine(cnt);
    Console.ReadLine();
}


9.번은 스트링에서 중복되는 문자열을 제거하는 겁니다. Linq로 간단히 합의 볼 수 있는 수준입죠.
static void Main(string[] args)
{
    string x = "aabcded"; //기대결과값은 abcde
    var result = x.Distinct().ToArray();
    Console.WriteLine(new string(result));
    Console.ReadLine();
}


10번은 끝에서 3번째 Element를 찾는 문제네요. 이제 슬슬 LinkedList는 지겨워 지려합니다. 2번 코드 재활용해서 만들어 볼께요.
그런데 끝은 어떻게 찾느냐? 간단히 child가 null인 녀석을 찾고 그 걸 child로 가지고 있는걸 찾고, 다시 그걸 child로 가진걸 찾고... 3번 반복하면 되겠네요.

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace TestCode
{
    class Program
    {
        static private Node head;
        static void Main(string[] args)
        {
            List<Node> _LinkedList = new List<Node>();
            MakeLinkedList(ref _LinkedList, 0);
            MakeLinkedList(ref _LinkedList, 1);
            MakeLinkedList(ref _LinkedList, 2);
            MakeLinkedList(ref _LinkedList, 3);

             //마지막 노드 찾는건 Lambda 함수로 Child가 null인 걸 찾으면 끝!
            Node LastNode = _LinkedList.Find(x => x.Child == null);
            Node findedNode;
            FindNode(_LinkedList, LastNode, 2, out findedNode);
            Console.Write(findedNode.value);
            Console.ReadLine();
        }

         //여기서 재귀함수 Recursive 로 돌려주면서 1씩 까나갑니다.
        static void FindNode(List<Node> LL, Node current, int n, out Node finded)
        {
            if (n == 0) { finded = current; return; }
            Node parent = LL.Find(x => x.Child == current);
            FindNode(LL, parent, n - 1, out finded);
        }

#region for Make Linked List 
static void MakeLinkedList(ref List<Node> _LL, int value)
{
if (head == null) AddFirst(ref _LL, value);
else
{
Node _node = new Node { value = value, Child = null };
_LL.Add(_node);
Node _current = head;
while (_current.Child != null)
{
_current = _current.Child;
}
_current.Child = _node;
}
}

static void AddFirst(ref List<Node> _LL, int value)
{
Node _Head = new Node { value = value, Child = null };
_LL.Add(_Head);
head = _Head;
}
#endregion

        static void MakeLoopList(List<Node> _LL)
        {
            _LL.Find(a => a.value == 3).Child = head;
        }

        public class Node
        {
            public int value;
            public Node Child;
        }
    }
}



11번 문제는 재귀함수로 팩토리얼 구하는 문제입니다. 3i이라면 3*2*1 = 6 이 나오면 되는 문제입니다.

static void Main(string[] args)
{
    Console.WriteLine(Factorial(4));
    Console.ReadLine();
}

static int Factorial(int x)
{
    if (x == 1) return x;
    return Factorial(x - 1) * x;
}



12번 문제는 암스트롱 수가 맞는지 확인하는거 같네요. 공식을 대입하면 abc = a^n + b^n + c^n = abc 가 나와야 합니다.
따라서, 입력한 값을 위 공식을 적용해서 테스트해보고 비교하면 올ㅋ~

static void Main(string[] args)
{
    Console.WriteLine(GetCalator(154));
    Console.ReadLine();
}

static bool GetCalator(int x)
{
    //자르기 편하게 string으로 변환부터
    string _x = x.ToString();
    //자릿수 n을 구합니다.
    int n = _x.Length;
    double y = 0;
    for (int i = 0; i < n; i++)
    {
        //C#은 C처럼 ^연산자는 2진수 계산을 하는군요. VB는 그냥 제곱인데.. 쩝..
        y += Math.Pow(int.Parse( _x[i].ToString()), n);
    }
    if (x == y) return true;
    return false;
}



13번 문제는 수학계의 영원한 숙제인 소수찾기입니다. 소수는 자기외에 나눌수 없는 성질을 가지고 있기 때문에 테스트 케이스를 작성하면,
1 소수
2 소수
3 소수
4 소수아님 (4%2==0)
5 소수 

1을 제외하면 for문으로 주어진 2~n-1까지 수로 나눠서, 그과정에서 나머지가 없으면 소수가 아닌걸로 판정하면 올ㅋ

static void Main(string[] args)
{
    Console.WriteLine(isPrime(7));
    Console.ReadLine();
}

static bool isPrime(int x)
{
    for (int i = 2; i < x; i++)
    {
        if (x % i == 0) return false;
    }
    return true;
}


14번 문제는 이전 포스팅에서 아나그람으로 다뤘지만, 조금 다른방식으로 처리해보면, Array.Reserve로 뒤집어 놓고 비교하면 더 간단하겠네요. =)

static void Main(string[] args)
{
    Console.WriteLine(isPalindrome(78));
    Console.ReadLine();
}

static bool isPalindrome(int x)
{
    char[] _x = x.ToString().ToCharArray();
    Array.Reverse(_x);
    if (x.ToString() == new string(_x)) return true;
    return false;
}



15번은 배열안에 중복되는 인자가 있는지 확인하는건데 이것도 걍 Linq한방이면 되겠네요! (1번 문제 응용이네요)
static void Main(string[] args)
{
    int[] _array = new int[] { 1, 2, 3, 3, 5 };
    var result = _array.GroupBy(x => x).Select(x => new { key = x.Key, count = x.Count() }).ToList();
    if (result.Find(x=>x.count >= 2) == null) Console.WriteLine("cant find Duplicated element");
    else Console.WriteLine("Find Duplicated element");
    Console.ReadLine();
}



16번은... 양키 형님들은 진짜 Linked List를 사랑하는거 같아요. -_-;; 
Linked List를 가능하다면 재귀함수 써서 뒤집으라 하십니다. 2번 소스 응용해서 만들어 보겠습니다.

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace TestCode
{
    class Program
    {
        static private Node head;
        static void Main(string[] args)
        {
            List<Node> _LinkedList = new List<Node>();
            MakeLinkedList(_LinkedList, 0);
            MakeLinkedList(_LinkedList, 1);
            MakeLinkedList(_LinkedList, 2);
            MakeLinkedList(_LinkedList, 3);

            List<Node> _ReservedList = new List<Node>();

            SetReserve(_LinkedList, _ReservedList, _LinkedList.Count()-1);
            foreach (Node v in _ReservedList)
            {
                 Console.WriteLine(v.value);
            }

            Console.ReadLine();
         }

         static void SetReserve(List<Node> linked, List<Node> Reserved, int idx)
         {
              if (idx < 0) return;
              MakeLinkedList(Reserved, linked[idx].value);
              SetReserve(linked, Reserved, idx-1);
         }


#region for Make Linked List 
static void MakeLinkedList(List<Node> _LL, int value)
{
if (head == null) AddFirst(ref _LL, value);
else
{
Node _node = new Node { value = value, Child = null };
_LL.Add(_node);
Node _current = head;
while (_current.Child != null)
{
_current = _current.Child;
}
_current.Child = _node;
}
}

static void AddFirst(ref List<Node> _LL, int value)
{
Node _Head = new Node { value = value, Child = null };
_LL.Add(_Head);
head = _Head;
}
#endregion 

      public class Node
      {
           public int value;
           public Node Child;
      }
   }
}


17번 문제는 의미를 몰라서 뒤져봤습니다.
찾아 봤더니 다른 의미가 아니라, 테스트 케이스로 보면, {1,2,3,4,5}라는 배열이 있다면, 3을 주면,
-1번-> {2,3,4,5,1} -2번-> {3,4,5,1,2} -3번-> {4,5,1,2,3}
결국 {4,5,1,2,3}이 나와야 하는거네요. 이건 string으로 변환해서 맨 앞에 녀석을 뒤로 가져다 붙이기를 몇번 하느냐 하는 문제 같군요!

* 그런데, 이거 예전에 한 20여년 전에 테트리스 블록 회전하기 했었을때 알고리즘 같은데.. 풀이는 좀 다르게 되어 있네요. 뭐 암튼 재귀함수와 ref 로 간단히 해결됩니다.
(C는 포인터로...)

static void Main(string[] args)
{
    int[] _array = new int[] { 1, 2, 3, 4, 5 };
    SetPivot(ref _array, 3);
    Console.ReadLine();
}

static void SetPivot(ref int[] _arr, int cnt)
{
    if (cnt < 1) return;
    int[] _cpyarray = new int[_arr.Length];
    int tmp = _arr[0];
    for (int i = 1; i < _arr.Length; i++)
    {
         _cpyarray[i - 1] = _arr[i];
    }
    _cpyarray[_arr.Length-1] = tmp;
    _arr = _cpyarray;
    SetPivot(ref _arr, cnt - 1);
}



18. 중복되는 Linked list 값을 제거하랍니다. 
Linked list merge소스를 조금 응용하면 되겠네요.

 class Program
 {
    static private Node head;
     static void Main(string[] args)
     {
        List<Node> _LinkedListA = new List<Node>();
         MakeLinkedList(ref _LinkedListA, 0);
         MakeLinkedList(ref _LinkedListA, 1);
         MakeLinkedList(ref _LinkedListA, 2);
         MakeLinkedList(ref _LinkedListA, 3);
         MakeLinkedList(ref _LinkedListA, 2);

         //Merge할 List를 만들고,
         List<Node> _UniqueList = new List<Node>();
         //Merge합니다.
         RemoveDuplicatedLinkedList(_LinkedListA, ref _UniqueList);
         Console.ReadLine();
    }

         //하나로 모아서 Sort한 뒤에 LinkedList를 생성합니다.
    static void RemoveDuplicatedLinkedList(List<Node> _A, ref List<Node> _C)
    {
         ArrayList A = new ArrayList();
         foreach (Node x in _A) A.Add(x.value);
         var _x = A.ToArray().Distinct().ToArray();
         foreach (int x in _x) MakeLinkedList(ref _C, x);
    }

 #region for Make Linked List 
 static void MakeLinkedList(ref List<Node> _LL, int value)
 {
 if (head == null) AddFirst(ref _LL, value);
 else
 {
 Node _node = new Node { value = value, Child = null };
 _LL.Add(_node);
 Node _current = head;
 while (_current.Child != null)
 {
 _current = _current.Child;
 }
 _current.Child = _node;
 }
 }

 static void AddFirst(ref List<Node> _LL, int value)
 {
 Node _Head = new Node { value = value, Child = null };
 _LL.Add(_Head);
 head = _Head;
 }
 #endregion

    static void MakeLoopList(List<Node> _LL)
    {
        _LL.Find(a => a.value == 3).Child = head;
    }

    public class Node
   {
        public int value;
        public Node Child;
    }
}



19. digits of the number 의 합을 재귀함수로 구하라고 하는건데, 말이 어렵네요... 간단하게 테스트 케이스를 만들어 보면 123 => 6 다시 말해 자릿수에 있는 0~9까지의 수를 다 더하란 이야기 입니다.
static void Main(string[] args)
{
    int x = 158; //14가 나와야 함.
    int result = 0;
    GetSum(x, ref result, x.ToString().Length - 1);
    Console.WriteLine(result);
    Console.ReadLine();
}

static void GetSum(int _x, ref int _result, int _digit)
{
    if (_digit >= 0)
    {
        _result = _result + int.Parse(_x.ToString().ToCharArray()[_digit].ToString());
        GetSum(_x, ref _result, _digit - 1);
    }
}


20. 마지막문제는 선택정렬하라 입니다.
지난번 포스팅에서 버블소트 다뤘는데, 선택정렬의 테스트 케이스는 다음과 같습니다.
{9,2,5,1,4,6} 가 있다면 n+1~m까지 중에 가장 작은 수를 찾아 비교한후 뒤에 숫자가 더 작다면 Swap합니다.
2번째 루프에서는 2번째 자리의 수를 기준으로 n+2~m까지 수중 가장 작은 수와 비교합니다.
버블소트가 마구마구 치환하는데 비해 이건 선택한 자리수의 수를 가지고 비교하기입니다.

static void Main(string[] args)
{
    int[] x = new int[]{ 9, 2, 5, 1, 4, 6 };
    foreach(int i in SetSort(x))
        Console.WriteLine(i);
    Console.ReadLine();
}

static int[] SetSort(int[] _x)
{
    for (int i = 0; i < _x.Length; i++)
    {
        for (int j = i+1; j < _x.Length; j++)
        {
            if (_x[i] > _x[j])
            {
                _x[i] = _x[i] + _x[j];
                _x[j] = _x[i] - _x[j];
                _x[i] = _x[i] - _x[j];
            }
        }
     }
     return _x;
}



2016/03/06 20:58 2016/03/06 20:58
C# 알고리즘 연습용입니다.

문제1. 임의의 문자열을 입력받아 유일한지 검사하라.
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace TestCode
{
    class Program
    {
        static Hashtable _UniqueTable;

        static void Main(string[] args)
        {

            string _InputString = Console.ReadLine();
            _UniqueTable = new Hashtable();

            for (int i=0; i < _InputString.Length; i++)
            {
                AddTable(_InputString[i]);
            }
            CheckTable();
            Console.ReadLine();
        }

        static void AddTable(char _x)
        {
            if (_UniqueTable != null && _UniqueTable.Contains(_x))
                _UniqueTable[_x] = (int)_UniqueTable[_x] + 1;
            else
                _UniqueTable.Add(_x, 1);
        }

        static void CheckTable()
        {
            foreach (DictionaryEntry _dt in _UniqueTable)
            {
                if ((int)_dt.Value > 1) Console.WriteLine("Error! No unique key found! {0}, Count {1}", _dt.Key, _dt.Value);
            }

        }
    }
}


결과는 Count가 2개 이상인 경우 문자메시지를 출력합니다.

Crack
1. 입력받은 문자열을 Char로 변환하여 HashTable에 넣는게 관건.
2. 이때 중복되는 키가 있으면 Value증가시킴
3. 중복되는 키가 없으면 Add시킴
4. 모든 입력과정 종료후 DictionaryEntry형으로 변환하여 Foreach날림

만약 C#의 Linq를 사용한다면 더 짧게 코딩이 가능합니다.
        static void Main(string[] args)
        {
            string InputString = "cvdss";
            Console.WriteLine(GetSameUniqueText(InputString).ToString());
            Console.ReadLine();
        }

        static bool GetSameUniqueText(string _x)
        {
            char[] ArrayChar = _x.ToCharArray();
            Array.Sort(ArrayChar);
            var Result = (from x in ArrayChar select x).Distinct().OrderBy(x => x).ToArray();
            if (new string(ArrayChar) == new string(Result)) return true;
            return false;
        }



문제2. 임의의 문자열을 받아서 역순으로 배열하여 출력하라.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace TestCode
{
    class Program
    {
        static void Main(string[] args)
        {
            string _TempString = "";
            string _InputString = Console.ReadLine();

            for (int i= _InputString.Length; i > 0; i--)
            {
                _TempString += _InputString[i-1];
            }
            Console.WriteLine(_TempString);
            Console.ReadLine();
        }

    }
}


Crack. 이건 간단해서 패스...
만약 C#이라면 역시 Linq로...
        static void Main(string[] args)
        {
            string InputString = "cvdss";
            Console.WriteLine(SetReverse(InputString));
            Console.ReadLine();
        }

        static string SetReverse(string _x)
        {
            char[] ArrayChar = _x.ToCharArray();
            var Result = (from x in ArrayChar select x).Reverse().ToArray();
            return new string(Result);
        }



문제3. 임의의 문자열을 입력받아 공백을 %20으로 교체하라.
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace TestCode
{
    class Program
    {
        static void Main(string[] args)
        {
            string _InputString = Console.ReadLine();
            Console.WriteLine(_InputString.Replace(" ", "%20"));
            Console.ReadLine();
        }
    }
}


Crack : 이것도 간단해서 생략

문제4. 반복되는 임의의 문자열 예를 들어 "aaaabbbccaa"를 입력받으면 "a4b3c2a2"로 압축하라.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace TestCode
{
    class Program
    {
        static void Main(string[] args)
        {
            char _OldChar = '\x0000';
            string _OutputStr = "";
            string _InputString = Console.ReadLine();

            int _count = 0;
            for (int i = 0; i < _InputString.Length; i++)
            {
                char _NewChar = _InputString[i];
                if (_NewChar == _OldChar) {
                    if (_count < 2) _OutputStr += _NewChar.ToString();
                    _count++;
                } 
                else
                {
                    if (_count > 0) _OutputStr += _count.ToString();
                    _OldChar = _NewChar;
                    _count = 1;
                }
            }

            Console.WriteLine(_OutputStr + _count.ToString());
            Console.ReadLine();
        }
    }
}


Crack : 이것도 간단해서 패스

문제5. 앞으로 읽어도 뒤로 읽어도 똑같은 문자열인지 Bool값으로 리턴하라. 단, Letter만 확인하라.
using System;
using System.Text.RegularExpressions;

public class Palindrome
{
     public static bool IsPalindrome(string str) {
          //먼저 소문자로 치환하고 특수문자는 제거합니다.
          string _x = JustLetter(str);
          //만약 3글자라면 1번만, 4글자라면 2번만 루프돌면서 가운데를 기준으로 대칭에 있는 문자열을 비교합니다.
          //만약 틀리면 false 를 리턴하고 빠집니다.
           int lastidx = _x.Length - 1;
           for (int i = 0; i < _x.Length / 2; i++){
                     if (_x[i] != _x[lastidx]) return false;
                     lastidx--;
           }
          //아무런 문제가 없으면 true;
           return true;
     }

     public static string JustLetter(string _str)
     {
           string _x = "";
           string returnVal = _str.ToLower();
           string pattern = @"[a-z]";

          //요부분이 좀 애먹은 부분인데 C#의 정규표현식으로 MatchCollection을 만든다음에 한글자씩 따는 부분입니다.
           MatchCollection matches = Regex.Matches(returnVal, pattern);
           foreach (Match match in matches)
                     _x += match.Value;
           return _x;
      }

     public static void Main(string[] args)
     {
           Console.WriteLine(IsPalindrome("Level."));
     }
}


Crack.
1. 글자를 비교할 수 있도록 표준화하는게 관건
   - 소문자로 만들기
   - 특수문자제거
2. 처음과 끝에서 부터 한단계씩 비교

문제 6. momdad와 dadmon은 단어의 순서가 바뀐 문자열이다. 이처럼 순서가 바뀐 단어가 있으면 true, 아니라면 false를 반환하라.

using System;

public class AreAnagrams
{
    public static bool AreStringsAnagrams(string a, string b)
    {
        if (CharSort(a) == CharSort(b)) return true;
        return false;
    }
    
    public static string CharSort(string _x)
    {
        char[] x = _x.ToCharArray();
        Array.Sort(x);
        return new string(x);
    }

    public static void Main(string[] args)
    {
        Console.WriteLine(AreStringsAnagrams("momdad", "dadmom"));
    }
}


Crack.
1. 두개의 단어가 정확하게 쓰여졌다는 가정하에 2개의 문자열을 Char로 치환후 Sort하면 동일한 결과를 얻을 수 있어야 합니다.
2. 따라서, string을 char로 변환후 sort해서 비교하는 루틴으로 간단하게 처리됩니다.


*문제7. Linked list Class를 만들고 특정 문자열을 지우면 나머지 단계도 삭제되는 루틴을 만드시오.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
 
namespace TestCode
{
    class Program
    {
        static void Main(string[] args)
        {
            List<NodeClass> _LinkedNode = new List<NodeClass>();
            SetNode(_LinkedNode);
            #region For Debug (Input data check)
            //foreach (NodeClass _n in _LinkedNode)
            //    Console.WriteLine("Parent:{0}, Value:{1}",_n._Parent, _n._value);
            #endregion
 
            RemoveValue(_LinkedNode, "A");
 
            #region For Debug (Input data check)
            foreach (NodeClass _n in _LinkedNode)
                Console.WriteLine("Parent:{0}, Value:{1}", _n._Parent, _n._value);
            #endregion
            Console.ReadLine();
        }
 
        static void SetNode(List<NodeClass> _LinkedNode)
        {
            string[] _Values = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
            foreach (string _value in _Values)
                _LinkedNode.Add(new NodeClass
                {
                    _Parent =
                    ((_value == "B") ? "A" :
                    (_value == "C") ? "A" :
                    (_value == "D") ? "A" :
                    (_value == "E") ? "B" :
                    (_value == "F") ? "C" :
                    (_value == "G") ? "C" :
                    (_value == "H") ? "D" :
                    (_value == "I") ? "F" :
                    (_value == "J") ? "F" :
                    ""),
                    _value = _value
                });
 
        }
        static void RemoveValue(List<NodeClass> _LinkedNode, string _X)
        {
            foreach (NodeClass _n in _LinkedNode)
            {
                if (_n._value == _X) _n._value = "";
                if (_n._Parent == _X) RemoveValue(_LinkedNode, _n._value);  
            }
        }
    }
 
    public class NodeClass
    {
        public string _Parent { get; set; }
        public string _value { get; set; }
    }
 
}


Crack.
1. 클래스 생성은 Parent와 value구조만 있으면 문제가 없습니다. 만약 node 탐색이 들어간다면 또 다른 이야기가 되겠지만, 현재 Tree구조로는 해당 문제를 푸는데 문제없습니다.
2. 먼저 노드를 생성합니다. SetNode
3. 임의의 문자를 입력하여 하위 노드를 삭제합니다. 이때 재귀함수 (Recursion Function)을 사용해서 하위레벨도 삭제되도록 합니다.

추가로 노드를 삭제하려면 아래의 메소드를 호출해주면 되겠습니다.
static void TruncItem(ref List<NodeClass> _LinkedNode) {
     _LinkedNode = _LinkedNode.FindAll(x => x._value != "");
}
ref 키워드이니까, 당연히 TruncItem(ref _LinkNode); 로 호출해야 겠죠?


문제8. 임의의 배열이 주어졌을때 이를 Sort하라.

using System;
using System.Linq;

namespace TestCode
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] arrays = new int[] { 1, 5, 6, 2, 4, 7, 9 };
            for (int i = 0; i < arrays.Count(); i++)
            {
                for (int y = 0; y < arrays.Count() - 1; y++)
                {
                    if (arrays[y] <= arrays[y + 1]) continue;
                    int x = arrays[y];
                    arrays[y] = arrays[y + 1];
                    arrays[y + 1] = x;
                }
            }

            foreach (int z in arrays)
                Console.WriteLine(z);
            Console.ReadLine();
        }
    }
}


Crack.
1. 간단한 Bubble sort입니다.
2. x개의 원소가 주어졌을 때, 총 x * (x-1)번의 Loop를 돌면서 맨 앞에서부터 차례로 데이터를 Swap 합니다.

보다 C#에 가깝게 고치면 ref 키워드를 사용해서 값 참조합니다.
using System;
using System.Linq;

namespace TestCode
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] arrays = new int[] { 1, 5, 6, 2, 4, 7, 9 };
            for (int i = 0; i < arrays.Count(); i++)
            {
                for (int y = 0; y < arrays.Count() - 1; y++)
                {
                    if (arrays[y] <= arrays[y + 1]) continue;
                    SwapInt(ref arrays[y], ref arrays[y + 1]);
                }
            }
            foreach (int z in arrays)
                Console.WriteLine(z);
            Console.ReadLine();
        }

        public static void SwapInt(ref int _x, ref int _y)
        {
            int x = _x;
            _x = _y;
            _y = x;
        }
    }
}


ref 키워드와 비슷한 녀석이 out 키워드인데, ref는 반드시 선언되고 정의되어야 하지만, out은 선언만 되면 사용이 가능합니다.
만약, 여러개의 인자를 한번에 정의하려면 out 키워드가 더 적합합니다.
using System;

namespace TestCode
{
    class Program
    {
        static void Main(string[] args)
        {
            string a, b;
            SetString(out a, out b);

            Console.WriteLine(a);
            Console.ReadLine();
        }

        static void SetString(out string x, out string y)
        {
            x = "A";
            y = "B";
        }
    }
}


하지만, 역시 Just C#이라면....
        static void Main(string[] args)
        {
            int[] arrays = new int[] { 1, 5, 6, 2, 4, 7, 9 };
            Array.Sort(arrays);
            foreach (int _x in arrays) {
                Console.WriteLine(_x.ToString());
            }
            Console.ReadLine();
        }

역순으로 Sort하는건, Sort 한뒤에 Method 하나더 불러줍니다.
 Array.Sort(arrays);
 Array.Reverse(arrays); //추가


문제 9.abcdefg 라는 문자열이 주어졌을때 n = 4 라고 할때
a c e g 
b d f
로 출력하시오.
Crack First. 이건 순열 문제로 문제의 의도를 파악하기 힘들군요. 만약 피시험자였다면 출제자에게 더 자세히 물어봤겠지만, 인터넷에 있는 후기를 퍼온 덕에 추가 정보를 얻을 수 없습니다만. 일단 기대값을 볼때 2자리마다 끝어서 출력하면 되지 않을까 싶네요.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace TestCode
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 4;
            string InputStr = "abcdefg";
            string[] Row = new string[2];

            char[] ArrayChar = InputStr.ToCharArray();

            int indexNum = 0;
            foreach (char c in ArrayChar)
            {
                if (indexNum % (n / 2) == 0) Row[0] += ArrayChar[indexNum];
                else Row[1] += ArrayChar[indexNum];
                indexNum++;
            }

            foreach (string s in Row)
            {
                Console.WriteLine(s);
            }

            Console.ReadLine();
        }
    }
}





문제 10. 예를들어 ccbbdddbcccaabbaaeeefff 가 주어졌을때 -> cbdaef 처음으로 등장한 알파벳만 모아서 보여주시오. 
using System;
using System.Linq;

namespace TestCode
{
     class Program
     {
          static void Main(string[] args)
          {
               string _x = "ccbbdddbcccaabbaaeeefff";
               char[] _arrChar = _x.ToCharArray();
               var query = (from x in _arrChar select x).Distinct().ToArray();
               Console.WriteLine(new string(query));
               Console.ReadLine();
          }
     }
}


Crack. 

간단한 Linq 문제입니다. =)



문제 11. 2개의 임의의 배열이 주어졌을때, Merge하고 Sort하라 

using System;
using System.Linq;

namespace TestCode
{
     class Program
     {
          static void Main(string[] args)
          {
               int[] One = new int[] { 1, 4, 6, 3, 9 };
               int[] Two = new int[] { 8, 2, 5 };
               int[] Merge = new int[One.Count() + Two.Count()];

               SetMerge(ref One, ref Two, ref Merge);
               Array.Sort(Merge);

               foreach(int x in Merge)
               {
                    Console.WriteLine(x);
               }
               Console.ReadLine();
          }

          static void SetMerge (ref int[] _x, ref int[] _y, ref int[] Result)
          {
               int MergeIdx = 0;
               for (int i = 0; i < _x.Count(); i++)
               {
                    Result[MergeIdx] = _x[i];
                    MergeIdx++;
                }
                for (int i = 0; i < _y.Count(); i++)
                {
                    Result[MergeIdx] = _y[i];
                    MergeIdx++;
                }
           }
     }
}

Crack. 
전통적인 방법으로는 위와 같이 배열 2개를 합한 크기의 배열을 만들고 For문 2번 돌려서 합치겠지만, C# 이라는 Linq가 있습니다.

using System;
using System.Linq;

namespace TestCode
{
     class Program
     {
          static void Main(string[] args)
          {
               int[] One = new int[] { 1, 4, 6, 3, 9 };
               int[] Two = new int[] { 8, 2, 5 };
               int[] Merge = new int[One.Count() + Two.Count()];

               SetMerge(ref One, ref Two, ref Merge);

               foreach (int x in Merge)
               {
                    Console.WriteLine(x);
               }
               Console.ReadLine();
           }

          static void SetMerge (ref int[] _x, ref int[] _y, ref int[] Result)
          {
               Result = _x.Concat(_y).OrderBy(x => x).ToArray(); //바로 이렇게 한방에 처리항 수 있습니다.
          }
     }
}



문제 12. 사용자 input 을 문자열로 받아서 숫자로 인식하는 프로그램을 만들어라.input에는 어떤 문자든지 올 수 있고, 어떤 규칙까지 허용하고 어떤 숫자까지 지원할지는 자유이다. 
Crack.
실제 MS사에서 면접 보신분의 후기에서 가져온 문제입니다. 이 경우 저라면 Hash 테이블에 단어장을 먼저 만들겠습니다.
먼저 필요한 테이블은 숫자만 카운팅 하는 테이블
1-one, 2-two, 3-three, 4-four, 5-five, 6-six, 7-seven, 8-eight, 9-nine, 10- ten, 11- eleven, 12-twelve, 13-thirteen, 14-fouteen, 15-fivteen .... 999-ninehundredniteennine
그리고 자릿수 3자리씩 잘라서 인식할 테이블을 만듭니다.
1000-thousand, 1000000-million, 1000000000-billion, 1000000000000-trillion
linq lambda 식으로 조회합니다.

//코드는 나중에 정리 예정.



문제 13.  두번째 문제는 Binary Tree가 있다고 가정하고 그 트리에 있는 숫자를 root에서 leaf까지 해서 도달하는 숫자의 합을 구하시오.
1
/ \
2  3
/\ /
4 5 6
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace TestCode
{
     class Program
     {
          static void Main(string[] args)
          {
               BinaryTree<int> broot = new BinaryTree<int>();
               broot.Root = new Node<int>(1);
               broot.Root.LNode = new Node<int>(2);
               broot.Root.RNode = new Node<int>(3);
               broot.Root.LNode.LNode = new Node<int>(4);
               broot.Root.LNode.RNode = new Node<int>(5);
               broot.Root.RNode.LNode = new Node<int>(6);

               ArrayList result = new ArrayList();
               broot.PrintNodeValue(broot.Root, 0, ref result);

               foreach (int i in result)
               {
                     Console.WriteLine(i);
               }

                Console.ReadLine();
           }
     }

      public class Node<T>
     {
          public Node<T> LNode;
          public Node<T> RNode;
          public int Value;
          public Node(int data)
          {
                this.Value = data;
          }
     }

     public class BinaryTree<T>
     {
          public Node<T> Root;
          public void PrintNodeValue(Node<T> node, int ParentValue, ref ArrayList result)
          {
                if (node.LNode != null) PrintNodeValue(node.LNode, node.Value + ParentValue, ref result);
                if (node.RNode != null) PrintNodeValue(node.RNode, node.Value + ParentValue, ref result);
                if (node.LNode == null && node.RNode == null)
                {
                     result.Add(node.Value + ParentValue);
                }
          }
     }
}


Crack.
2진트리는 1개의 노드가 최대 2개의 자식 노드를 가진 트리형입니다.
반듯이 왼쪽부터 채워져야 하는 규칙을 가지고 있지요.
아마도 이 문제 응용문제로 2진 트리에서 공통 조상을 찾아라 든가... 혹은 2진트리를 반전 시켜라와 2진트리 Leaf를 찾아라와 같은 응용 문제가 있을 수 있습니다.
중요한건 재귀함수를 쓸 줄 아느냐 일것 같은데, C#에서는 2진트리 쓸일이 사실 별로 없어서... 쿨럭...
2016/03/02 17:11 2016/03/02 17:11
일전에 Mesh생성하는 방법에 대해 써 놓은 적이 있는데,

Link : http://www.wolfpack.pe.kr/853

문득 Hexa로 만드는것도 가능하지 않을까? 고민했습니다.
그래서, 만들어 봤습니다.

먼저 Mesh 만든 절차를 그대로 따라 했습니다.
1. 좌표를 Vector3 array로 만든다.
* Mesh의 경우는 단 4개의 Vertex로 구성되면 되기 때문에, 좌표는 총 4개를 만들면 되죠.
예를 들어, pivot point가 Center에 있는 4각의 Mesh라면,
(-1, -1, 0), (-1, 1, 0), (1, 1, 0), (1, -1, 0) >> 각각 0, 1, 2, 3 번 이라고 합시다.

2. Polygon Array를 만듭니다. 하나 중요한건 Unity3D는 왼손 좌표계이므로 Surface가 -Z축에서 보여지려면 시계방향으로 Array를 생성해야 합니다.
* 0, 1, 2, 0, 2, 3 / 3개씩 잘라서 보면 0,1,2 폴리곤과 0, 2, 3 폴리곤 2개가 있어, 4각으로 보이죠.

자세한건 위의 Link 참조바랍니다.

Hexa의 경우는 간단히 다음과 같이 하면 되겠지하고 덤볐다가.. -_-;; 개피봤습니다.
사용자 삽입 이미지
1개 일때는 문제없이 0, 1, 3, 1, 2, 3, 0, 3, 4, 0, 4, 5 로 폴리곤 셋을 잘라주면 되는데.. 2개 이상만 되도 일정한 규칙을 발견하기 어려웠습니다.
사용자 삽입 이미지
슬슬 멘붕오기 시작하지요. 여기에 Y축까지 추가되면...
사용자 삽입 이미지
규칙은 사라지고 Chaos 만 남습니다. -_-;;
만약, Pivot이 Center에 있다면? 이라는 질문을 하게 되었고 Vetex를 정리해보니 다음과 같이 그런대로 규칙이 생깁니다.
사용자 삽입 이미지
정리하자면 2*2짜리 Hexa는 가로로 n개의 Vertex를 가집니다.
이걸 수식으로 정리하면 Hexa갯수가 x라면 Vertex수는
1 - 3
2 - 5
3 - 7
4 - 9
n - 2 * 헥사갯수 + 1

입니다만, Hexa는 항상 위에서 보는바와 같이 왔다 갔다 하므로 Y축 확장을 위해 우로 Vertex열이 1줄 더 있어야 하고 좌로도 1줄 더 있어야 하는 상황이 됩니다.

그리고, 또 하나 만난 문제는 저렇게 Vertex를 배열하는게 문제였습니다.
6각형은 60도로 나누어져 있는데 소숫점 오차로 인해 제대로 배열이 안되는것도 문제여서...
그냥 다음과 같이 간단히 일렬로 배열한뒤에...
사용자 삽입 이미지
홀수 열만 0.5정도 올려주면...
사용자 삽입 이미지
근사하게 육각으로 바뀌는 군욤. ㅋ

* 여기까지 코드는 다음과 같습니다.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Hexa : MonoBehaviour {

    private Vector3[] vertexs; 

    void Awake()
    {
        gameObject.AddComponent<MeshFilter>();
        gameObject.AddComponent<MeshRenderer>();
    }

    void Start () {
        SetVertex(5, 6);
    }
    
    void SetVertex(int xSize, int ySize)
    {
        //사전처리 부분입니다. 예외처리를 위해 가로 헥사수는 2이상, 세로 헥사수는 짝수로 고정합니다.
        if (xSize < 2) xSize++; //가로 헥사수, 예외 처리를 위해 2이상으로 강제 처리
        if (ySize % 2 == 1) ySize++; //세로 헥사수  //예외 처리를 위해 짝수로 강제 처리

        // 가로와 세로의 버텍스 수를 구합니다.
        int xDotSize = 2 * xSize + 2; //가로 버텍스 수
        int yDotSize = (ySize % 2 == 0) ? (3 * ySize / 2) + 1 : 3 * (ySize / 2 + 1); //세로 버텍스 수

        //For 문으로 자동으로 찍되 홀수 줄은 0.5f만큼 올립니다.
        MeshFilter MF = GetComponent<MeshFilter>();
        vertexs = new Vector3[xDotSize * yDotSize];
        for (int i = 0, y = 0; y > yDotSize * -1 ; y--)
        {
            for (int x = 0; x < xDotSize; x++, i++)
            {
                vertexs[i] = (x % 2 == 0) ? new Vector3(x, 0f, y) : new Vector3(x, 0f, y + 0.5f);
            }
        }
        MF.mesh.vertices = vertexs;
    }

    private void OnDrawGizmos()
    {
        if (vertexs == null) return;
        Gizmos.color = Color.red;
        for (int i = 0; i < vertexs.Length; i++)
            Gizmos.DrawSphere(vertexs[i], 0.1f);
    }
}


이제 문제는 Center를 찾는 겁니다. 의외로 어렵게 해결된 부분인데,
먼저 좌변의 Center Point들을 먼저 찾고 거기에 가로로 +2를 반복하였습니다.
그 이유는 다음의 그림에서 처럼 첫 Center는 2번째, 2번째 Center는 5번째... 이런식으로 나타 났고 이를 위해 수열 공식 찾느라 오래 걸렸습니다.
사용자 삽입 이미지
암튼 위의 결과를 보인 소스는 다음과 같습니다.

        //SetVertex() 함수 밑부분에 넣었습니다.
        //Find Center
        CenterP = new Vector3[xSize * ySize];
        for (int idx =0, y = 0; y < ySize; y++) {
            int verticesIdx = 0;
            verticesIdx = xDotSize * ((y / 2) + 1 + y) + 1 + (y % 2); //버텍스인덱스는 가로크기* ((y / 2) + 1 + y) + 1 + (y % 2), y는 세로변수 y
            CenterP[idx] = vertexs[verticesIdx];
            CenterIdx.Add(verticesIdx);
            idx++;
            for (int x = 1; x < xSize; x++)
            {
                CenterP[idx] = vertexs[verticesIdx + 2 * x]; //세로에서 구한 센터값에 +2 반복
                CenterIdx.Add(verticesIdx + 2 * x);
                idx++;
            }
        }

좀 복잡하지만, CenterP는 OnGizmo에서 디버깅 용으로 만든 변수이고, 실재 사용하는 변수명은 CenterIdx입니다.
클래스 변수는 다음과 같이 위의 2개 변수를 추가했구요.

    private Vector3[] vertexs;
    private Vector3[] CenterP;
    private List<int> CenterIdx = new List<int>();


마지막으로 OnGizmo를 다음과 같은 최종형태로 만들었습니다.
    private void OnDrawGizmos()
    {
        if (vertexs == null) return;
        Gizmos.color = Color.red;
        for (int i = 0; i < vertexs.Length; i++)
            Gizmos.DrawSphere(vertexs[i], 0.1f);

        if (CenterP == null) return;
        Gizmos.color = Color.yellow;
        for (int i = 0; i < CenterP.Length; i ++ )
            Gizmos.DrawSphere(CenterP[i], 0.1f);

    }


마지막으로 Vertex 연결 순서는 짝수 열과 홀수 열이 조금 다르지만, 정리하면,

                //총 6개의 폴리곤이 있어야 6각형이 나오므로...
                triangles[idx] = CenterIdx[x];
                triangles[idx + 1] = CenterIdx[x] - 1;
                triangles[idx + 2] = CenterIdx[x] - xDotSize;
                
                triangles[idx + 3] = CenterIdx[x];
                triangles[idx + 4] = CenterIdx[x] - xDotSize;
                triangles[idx + 5] = CenterIdx[x] + 1;
                
                triangles[idx + 6] = CenterIdx[x];
                triangles[idx + 7] = CenterIdx[x] + 1;
                triangles[idx + 8] = CenterIdx[x] + xDotSize + 1;

                triangles[idx + 9] = CenterIdx[x];
                triangles[idx + 10] = CenterIdx[x] + xDotSize + 1;
                triangles[idx + 11] = CenterIdx[x] + xDotSize;
                
                triangles[idx + 12] = CenterIdx[x];
                triangles[idx + 13] = CenterIdx[x] + xDotSize;
                triangles[idx + 14] = CenterIdx[x] + xDotSize - 1;
                
                triangles[idx + 15] = CenterIdx[x];
                triangles[idx + 16] = CenterIdx[x] + xDotSize - 1;
                triangles[idx + 17] = CenterIdx[x] - 1;

위의 코드를 좀 짧게 축약하면 다음과 같습니다.

                triangles[idx] = triangles[idx + 3] = triangles[idx + 6] = triangles[idx + 9] = triangles[idx + 12] = triangles[idx + 15] = CenterIdx[x];
                triangles[idx + 1] = triangles[idx + 17] = CenterIdx[x] - 1;
                triangles[idx + 2] = triangles[idx + 4] = CenterIdx[x] - xDotSize;
                triangles[idx + 5] = triangles[idx + 7] = CenterIdx[x] + 1;
                triangles[idx + 8] = triangles[idx + 10] = CenterIdx[x] + xDotSize + 1;
                triangles[idx + 11] = triangles[idx + 13] =  CenterIdx[x] + xDotSize;
                triangles[idx + 14] = triangles[idx + 16] = CenterIdx[x] + xDotSize - 1;


이제 이걸 돌려 보면... 두둥..
사용자 삽입 이미지
전체 코드는 다음과 같습니다.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Hexa : MonoBehaviour {

    private Vector3[] vertexs;
    private Vector3[] CenterP;
    private List<int> CenterIdx = new List<int>();

    void Awake()
    {
        gameObject.AddComponent<MeshFilter>();
        gameObject.AddComponent<MeshRenderer>();
    }

    // Use this for initialization
    void Start () {
        SetVertex(5, 6);
    }
    
    void SetVertex(int xSize, int ySize)
    {
        if (xSize < 2) xSize++; //x 헥사수
        if (ySize % 2 == 1) ySize++; //y 헥사수
        int xDotSize = 2 * xSize + 2; //가로 버텍스 수
        int yDotSize = (ySize % 2 == 0) ? (3 * ySize / 2) + 1 : 3 * (ySize / 2 + 1); //세로 버텍스 수
        MeshFilter MF = GetComponent<MeshFilter>();
        vertexs = new Vector3[xDotSize * yDotSize];
        for (int i = 0, y = 0; y > yDotSize * -1 ; y--)
        {
            for (int x = 0; x < xDotSize; x++, i++)
            {
                vertexs[i] = (x % 2 == 0) ? new Vector3(x, 0f, y) : new Vector3(x, 0f, y + 0.5f);
            }
        }
        MF.mesh.vertices = vertexs;

        //Find Center
        CenterP = new Vector3[xSize * ySize];
        for (int idx =0, y = 0; y < ySize; y++) {
            int verticesIdx = 0;
            verticesIdx = xDotSize * ((y / 2) + 1 + y) + 1 + (y % 2);
            CenterP[idx] = vertexs[verticesIdx];
            CenterIdx.Add(verticesIdx);
            idx++;
            for (int x = 1; x < xSize; x++)
            {
                CenterP[idx] = vertexs[verticesIdx + 2 * x];
                CenterIdx.Add(verticesIdx + 2 * x);
                idx++;
            }
        }

        int[] triangles = new int[18 * (xSize * ySize)];

        for (int idx = 0, x = 0; x < CenterIdx.Count; x++)
        {
            if ((x / xSize) % 2 == 0)
            {
                triangles[idx] = CenterIdx[x];
                triangles[idx + 1] = CenterIdx[x] - xDotSize - 1;
                triangles[idx + 2] = CenterIdx[x] - xDotSize;

                triangles[idx + 3] = CenterIdx[x];
                triangles[idx + 4] = CenterIdx[x] - xDotSize;
                triangles[idx + 5] = CenterIdx[x] - xDotSize + 1;

                triangles[idx + 6] = CenterIdx[x];
                triangles[idx + 7] = CenterIdx[x] - xDotSize + 1;
                triangles[idx + 8] = CenterIdx[x] + 1;

                triangles[idx + 9] = CenterIdx[x];
                triangles[idx + 10] = CenterIdx[x] + 1;
                triangles[idx + 11] = CenterIdx[x] + xDotSize;

                triangles[idx + 12] = CenterIdx[x];
                triangles[idx + 13] = CenterIdx[x] + xDotSize;
                triangles[idx + 14] = CenterIdx[x] - 1;

                triangles[idx + 15] = CenterIdx[x];
                triangles[idx + 16] = CenterIdx[x] - 1;
                triangles[idx + 17] = CenterIdx[x] - xDotSize - 1;

            }
            else
            {
                triangles[idx] = CenterIdx[x];
                triangles[idx + 1] = CenterIdx[x] - 1;
                triangles[idx + 2] = CenterIdx[x] - xDotSize;
                
                triangles[idx + 3] = CenterIdx[x];
                triangles[idx + 4] = CenterIdx[x] - xDotSize;
                triangles[idx + 5] = CenterIdx[x] + 1;
                
                triangles[idx + 6] = CenterIdx[x];
                triangles[idx + 7] = CenterIdx[x] + 1;
                triangles[idx + 8] = CenterIdx[x] + xDotSize + 1;

                triangles[idx + 9] = CenterIdx[x];
                triangles[idx + 10] = CenterIdx[x] + xDotSize + 1;
                triangles[idx + 11] = CenterIdx[x] + xDotSize;
                
                triangles[idx + 12] = CenterIdx[x];
                triangles[idx + 13] = CenterIdx[x] + xDotSize;
                triangles[idx + 14] = CenterIdx[x] + xDotSize - 1;
                
                triangles[idx + 15] = CenterIdx[x];
                triangles[idx + 16] = CenterIdx[x] + xDotSize - 1;
                triangles[idx + 17] = CenterIdx[x] - 1;
            }
            idx += 18;
        }

        MF.mesh.triangles = triangles;
        MF.mesh.RecalculateNormals();

    }

    private void OnDrawGizmos()
    {
        if (vertexs == null) return;
        Gizmos.color = Color.red;
        for (int i = 0; i < vertexs.Length; i++)
            Gizmos.DrawSphere(vertexs[i], 0.1f);

        if (CenterP == null) return;
        Gizmos.color = Color.yellow;
        for (int i = 0; i < CenterP.Length; i ++ )
            Gizmos.DrawSphere(CenterP[i], 0.1f);

    }
}


그럼~ 새해 복 많이 받으세요!
2016/02/09 17:17 2016/02/09 17:17
올만에 쓰는 기술 팁인듯...

암튼, 최근 SNG게임 만들면서 황당한 상황을 만났다.

This article is just a reference of SQL Data Types to C# Data Types.

SQL Server data typeCLR data type (SQL Server)CLR data type (.NET Framework)
varbinarySqlBytes, SqlBinaryByte[]
binarySqlBytes, SqlBinaryByte[]
varbinary(1), binary(1)SqlBytes, SqlBinarybyte, Byte[]
imageNoneNone
varcharNoneNone
charNoneNone
nvarchar(1), nchar(1)SqlChars, SqlStringChar, String, Char[]
nvarcharSqlChars, SqlStringString, Char[]
ncharSqlChars, SqlStringString, Char[]
textNoneNone
ntextNoneNone
uniqueidentifierSqlGuidGuid
rowversionNoneByte[]
bitSqlBooleanBoolean
tinyintSqlByteByte
smallintSqlInt16Int16
intSqlInt32Int32
bigintSqlInt64Int64
smallmoneySqlMoneyDecimal
moneySqlMoneyDecimal
numericSqlDecimalDecimal
decimalSqlDecimalDecimal
realSqlSingleSingle
floatSqlDoubleDouble
smalldatetimeSqlDateTimeDateTime
datetimeSqlDateTimeDateTime
sql_variantNoneObject
User-defined type(UDT)user-defined typeNone
tableNoneNone
cursorNoneNone
timestampNoneNone
xmlSqlXmlNone

위의 표를 자세히 보면 MSSQL char 타잎은 .NET CLR에서 지원하지 않는다. (뭥미...?)
그래서 이리저리 테스트해본 결과...
배열인 Char[]은 지원하고 있다는 사실을 발견하였고,
현재는 이렇게 해서 문제를 해결하고 있다.

        public bool joinmember(string DeviceID, string herotype)
        {
               //LINQSQL 선언부 생략 
 //herotype이 Char(1)이다. 
                um.herotype = (Char)herotype.ToCharArray(0,1)[0]; 

               //중략
                db.userMaster.InsertOnSubmit(um);
               //후략
         }


여기에 맞추기 위해 일단 string으로 받아서 CharArray로 변환후에 [0]번째 Char로 돌려 주는 거다.

상세히 보면, String -Char[]변환->Char[]중 [0]번째만 Return -> Char
복잡하기는 하지만 잘 작동중.
2012/09/04 15:54 2012/09/04 15:54

Link
1편/네트워크 연결하기-http://www.wolfpack.pe.kr/303
2편/Bluetooth사용하기-http://www.wolfpack.pe.kr/310
3편/모바일배포일반-http://www.wolfpack.pe.kr/314
4편/PC에서모바일배포-http://www.wolfpack.pe.kr/315

오늘 그냥 필받았다고 치고 원래는 다음주쯤에 해야할 배포 마지막을 밟아 보고자 한다.
지난번에 기본적인 원리까지 진행했는데 이제 구현할 차례이다.

1. PC 설치 프로젝트를 추가하자.
솔루션을 클릭하고 마우스 우클릭, 추가, 새프로젝트 클릭후에 위저드 화면에서 설치프로젝트로

사용자 삽입 이미지
2. 설치 프로젝트가 열렸다면 불필요한 폴더 다날리고 "응용 프로그램 폴더" 1개만 남겨 놓은뒤에 TestCAB이라는 폴더를 추가하자.
사용자 삽입 이미지
3. 우측 창을 클릭하여 TESTCAB 프로젝트 출력물을 추가하자.
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
4. 응용 프로그램 폴더의 속성중 설치될 폴더가 있다. 너무 기니 알맞게 자르도록 하자.
사용자 삽입 이미지

* 현재 상태는 DefaultLocation이 "C:\Program files\FunnyWorld"가 된다. PCSetup프로젝트의 속성에 manufacturer 설정이 FunnyWorld이기 때문이다.
사용자 삽입 이미지
5. 이제 레지스트리를 추가하자.
* PCSetup프로젝트를 클릭하고 마우스 우클릭, 보기, 레지스트리를 차례로 클릭한다.
사용자 삽입 이미지
* PCSetup에 대한 레지스트리를 추가하도록 하자.
사용자 삽입 이미지
* "VS2008 Windows mobile 6 개발환경 구축 - 3" 말미에 미리보았던 그 구조이다.
- 우클릭후에 새로만들기로 추가하되 레지스트리에 표현되는 종류는 다음과 같다.
문자열값 - REG_SZ
확장 가능한 문자열 값 - REG_EXPAND_SZ
이진값 - REG_BINARY
DWORD - REG_DWORD
이상 4가지 타잎이 지원된다. 하지만 레지스트리에서 사용하는 것은 총 5가지 타잎으로 "다중문자열값(REG_MULTI_SZ)"가 지원되지 않는것이 좀 흠이랄까?
"VS2008 Windows mobile 6 개발환경 구축 - 3"에서 REG_MULTI_SZ로 보인것은 REG_SZ 타입으로 설정하자.

6. 레지스트리 설정이 완료되고나면 이제 설치후 "CEAppMgr.exe"을 실행시켜 주는 녀석을 만들자.
먼저 솔루션에 콘솔 프로젝트를 추가하였다. 윈도우에서 실행되는 것이라면 다른것도 관계없다. 알아서 취향에 맞게 추가하기만 하자.
사용자 삽입 이미지
이제 코딩이다. CEAppMgr.exe가 어디에 있는지 알아야 하니 레지스트리를 뒤져서 실행하도록 짜보자.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32; //레지스트리 관련 필수 추가

namespace runner {     class Program     {         static void Main(string[] args)         {             //레지스트리에 접근하여 값을 가져온다.             string regPath = @"Software\Microsoft\Windows\CurrentVersion\App Paths\CEAppMgr.exe";             RegistryKey rgkey = Registry.LocalMachine.OpenSubKey(regPath, true);             Console.WriteLine(rgkey);             String rtnPath="";             foreach (string Val in rgkey.GetValueNames())                 rtnPath = rgkey.GetValue(Val).ToString();                         //가져온 경로대로 실행한다.             System.Diagnostics.Process ps = new System.Diagnostics.Process();             ps.StartInfo.FileName = @rtnPath;             ps.Start();         }     } }



7. 노가다는 이제 끝나간다. 다시 PC설치용 프로젝트로 이동해서 앞에서 만든 Runner 프로그램을 출력에 추가하고 사용자 작업에 추가해주자.
- runner 프로젝트의 출력을 추가했음
사용자 삽입 이미지
- PCSetup프로젝트의 사용자 지정작업 클릭
사용자 삽입 이미지
- 설치 단계에 runner의 기본출력을 지정하였다.
사용자 삽입 이미지

8. 이제 최종 설치한번 해보자.
- 간단하게 솔루션 탐색기에서 PCSetup 프로젝트 선택후 마우스 우클릭하면 설치할 수 있다.
사용자 삽입 이미지
- 설치하고 나서 원하는 대로 추가/제거 윈도우가 나타난다.
사용자 삽입 이미지

9. 실재 설치후 테스트
- TESTCAB를 선택하자.
사용자 삽입 이미지
- 응용 프로그램 다운로드 완료라고 뜨고 Windows Mobile Device에서는 열심히 설치중이다.
사용자 삽입 이미지
- 설치완료모습
사용자 삽입 이미지


이로써 기본 윈도우즈 모바일 개발환경 구축은 완료되었다.
추가적으로 필요한 부분은 SDK를 구매하는 것을 권한다. 그러나, 일반 범용 어플리케이션은 에뮬레이터로 충분히 나아가 Bluetooth까지 지원하며 PC에서 손쉽게 설치하는 방법까지 공개하였으니 어렵지 않을것이다. 본 윈도우즈 모바일 개발환경 구축 관련 글은 개인 저작물이며 누구나 퍼나를수 있다. 그러나, 허락없이 퍼나르거나 동영상으로 포맷그대로 전환하신 분도 계시다. 쓰지말라고 올리는 것도 아닌데 방명록에 쓰겠다는 멘트만이라도 남겨주면 어떨까?

다음에 또 다른 지식을 나눠보도록 하자.
2009/03/11 15:21 2009/03/11 15:21
Link
1편/네트워크 연결하기-http://www.wolfpack.pe.kr/303
2편/Bluetooth사용하기-http://www.wolfpack.pe.kr/310
3편/모바일배포일반-http://www.wolfpack.pe.kr/314
4편/PC에서모바일배포-http://www.wolfpack.pe.kr/315

이번에는 PC에서 Mobile로 만든 CAB파일을 설치하는 방법에 대해 알아보자.
일단 Windows Mobile 개발이 능숙한 사람을 대상으로하니 자질구래하게 프로그램 소스까지 올리지 않도록 하겠다.

단계는 다음과 같이 한다.
1. Windows Mobile 프로그램 제작
2. Windows Mobile 배포 패키징
3. Regedit로 레지스트리를 건드려 ActiveSync 설치목록에 뜨도록 만들기
4. ActiveSync 설치관리자로 설치하기

1. TestDeploy라는 프로젝트명으로 어플리케이션을 하나 만들었다.

사용자 삽입 이미지
2. 이제 CAB으로 싸자
   1) 솔루션에서 새프로젝트를 추가하자.
사용자 삽입 이미지
   2) TESTCAB이라는 이름으로 모바일 설치 프로젝트를 생성
사용자 삽입 이미지
   3) "프로그램 폴더" 추가
사용자 삽입 이미지
   4) 쓸데없는 폴더는 날리자.
사용자 삽입 이미지
   5) 응용 프로그램 폴더를 클릭하고 추가
사용자 삽입 이미지
사용자 삽입 이미지
   6) 프로그램 폴더에 바로가기를 생성하자.
       - 프로그램 폴더 클릭후에 오른쪽 창에서 마우스 우클릭
사용자 삽입 이미지
      - 응용 프로그램 폴더안의 TestDeploy의 기본 출력(활성)을 선택
사용자 삽입 이미지
       - 파일이 생성되면 "Shortcut to TestDeploy의 기본 출력(활성)"이라고 쓰여져 있는데 한글은
         Ansicode로 변환하는데 실패할 수 있으므로 영문으로 바꾸자."Shortcut to TestDeploy"로
         한글만 지웠다.
   7) 이제 설치파일에 기록될 작성자나 뭐 기타 등등을 고쳐주자.
사용자 삽입 이미지
   8) 솔루션 전체를 빌드하자.
사용자 삽입 이미지
   9) ActiveSync의 "탐색" 기능을 이용하여 생성된 CAB 파일을 Windows Mobile에 옮겨 놓자
사용자 삽입 이미지
    10) 옮겨 놓은 모습
사용자 삽입 이미지
   11) 실행하자.
사용자 삽입 이미지
   12) 프로그램 메뉴에 있는지 확인하고 실행하자.
        - 한글이 깨지는 문제는 Widnows Mobile Emulator가 영문버전이기때문임. 한글버전은 문제
           없음.
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
3. 이제 본격적인 PC를 통한 설치를 하기위해 사전 지식을 쌓아보자.
위에서 일련의 프로그램을 만들고 CAB으로 만들어 배포하는것을 해보았지만 문제는 이게 좀 귀찮다는 것이다. PC에서 Windows Mobile Device를 설치하는 기능이 있음에도 잘 안쓰니까 문제라고나 할까?

- ActiveSync의 프로그램 추가/제거 기능이 바로 그것이다.
사용자 삽입 이미지
- 프로그램 추가/제거를 클릭하면 설치할 수 있는 파일들이 뜬다.
사용자 삽입 이미지
이녀석들은 도대체 어디 있길레 이렇게 뜨는것일까? 시작>실행에서 "Regedit"를 실행하여 살펴보도록 하자.
결론부터 말하자면 여기에 존재한다.
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\AppMgr\Apps

어랏? 많이 보던 녀석들 아닌가?
사용자 삽입 이미지
다시말해 레지스트리에 등록만 해주면 ActiveSync의 기능을 추가/제거 기능을 이용할 수 있을듯 하다.
다음은 "Adobe FlashLite"를 클릭해서 내용을 발취한후 TESTCAB에 맞게 수정한 것이다.
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\AppMgr\Apps\TESTCAB] "AppName"="TESTCAB" "Description"="" "IconIndex"=dword:00000000 "InstallDir"="D:\\Work_Source\\TestDeploy\\TESTCAB\\Debug" "ListCabFiles"=hex(7):54,00,45,00,53,00,54,00,43,00,41,00,42,00,2e,00,43,00,41,\   00,42,00,00,00,00,00 "ListCpuTypes"=hex(7):30,00,00,00,00,00 "Provider"="FunnyWorld"


실재 레지스트리를 살펴본 모습은 이러하다.
사용자 삽입 이미지

이렇게 레지스트리를 고쳤을때 실재 파일의 위치만 정확하다면 다음과 같이 프로그램 추가/제거 윈도우에서 뜬다.
사용자 삽입 이미지

이제 하나만 더해보자.
TESTCAB를 프로그램 추가/제거에 넣었다고는 하나 저기능을 자동으로 띄우지 못한다면 불편한것은 여전하다. 짧게 다시 결론부터 이야기하자면 저녀석의 명칭은 "CEAppMgr.exe"이다.
(프로그램 추가/제거 윈도우를 활성화 한상태에서 윈도우 작업관리자를 띄워 놓고 이름순으로 정렬한뒤에 프로그램 추가/제거창을 닫으니 사라지는 프로세스가 바로 저 이름이었다.)
어디에 있는줄은 모르겠지만 암튼 CEAppMgr.exe를 실행하면 된다니 이 녀석도 레지스트리에서 찾아보자.


\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\CEAppMgr.exe



위의 경로에 기본값으로 박혀 있다는 것을 확인 가능하다.
* 내경우는 "C:\Program Files\Microsoft ActiveSync\CEAPPMGR.EXE"이었다.

다음에 Windows Setup을 통해 CAB파일을 특정장소에 보관하고 레지스트리를 조작한 후에 CEAppMgr.exe를 실행해보도록 하자.
2009/03/10 15:57 2009/03/10 15:57
Windows mobile 6는 사실 Core가 Mobile 5와 동일하다.
다시말해 기죽지 말자.
아무튼 Smart Phone개발하려면 환경구축이 중요한데 특히 옴니아(Omnia)폰과 같이 고가의 장비를 갖춰서 개발한다는 아닌것 같다.

본 포스팅은 이런 환경을 구축하는데 노력이상의 비용을 지불하지 않는 선에서 환경구축을 완료하는데 그 목적이 있다.

1편 - Emulator에 네트워크 어떻게 연결할까?
2편 - Bluetooth를 Emulation할 수 없을까?
3편 - 만들긴 만들었는데 어떻게 배포하지?

Link
1편/네트워크 연결하기-http://www.wolfpack.pe.kr/303
2편/Bluetooth사용하기-http://www.wolfpack.pe.kr/310
3편/모바일배포일반-http://www.wolfpack.pe.kr/314
4편/PC에서모바일배포-http://www.wolfpack.pe.kr/315

이렇게 3부에 걸쳐 Windows Mobile 6 기반의 어플개발환경구축에대해 주저리주저리 떠들어 보자.

준비물은 Visual studio 2008 Express 이상이면 되고
Omnia같이 해상도가 800*480정도 되는 놈은 미쿡 이미지만 지원하므로 따로 다운로드 받는다.
일단은 Windows mobile 6 SDK부터 다운로드 받자.
http://www.microsoft.com/downloads/det ··· ang%3Den
그리고 480 * 800 개발용 이미지는 여기서 더 받도록 하자.
http://www.microsoft.com/downloads/det ··· ang%3Den

다운로드후 설치는 자동으로 OK.

XP라면 Activesync 4.5를 설치하고 Vista라면 디바이스 센터를 업데이트 한다.
여기서는 Activesync로 진행하겠다.
Activesync를 실행한후 "파일>연결설정"을 클릭한다.
다음과 같은 설정창이 뜨면 "다음 중 한가지 연결 허용"을 체크하고 DMA를 추가해둔다.
사용자 삽입 이미지
나머지는 Visual Studio 2008의 몫이다.
VS2008을 실행한후에 "도구>장치 에뮬레이터 관리자"를 클릭하여 관리자를 실행한다.
사용자 삽입 이미지
관리자 실행후에 해당 이미지를 클릭하고 마우스 우클릭하면 메뉴가 뜨는데 여기서 "연결"을 선택하자.
사용자 삽입 이미지
연결을 클릭하면 자동으로 이미지가 활성화되고 Emulator가 작동하기 시작한다.
사용자 삽입 이미지
에뮬레이터가 실행되면 다시 관리자에서 이미지를 선택하고 마우스 우클릭하여 "크레들에 놓기"를 선택하자.
사용자 삽입 이미지
이제 가상으로 크레들에 놓은것처럼 작동되어 동기화를 시작하게된다.
(동기화 설정은 생략함. 왠만하면 동기화 설정은 모두 언체크하여 하지 않도록 하자.)
사용자 삽입 이미지
마지막으로 연결이 완료되었는지 확인하자.
사용자 삽입 이미지
인터넷이 제대로 작동하는지도 확인하자. 본인의 PC가 인터넷이 연결안되어 있으면 말짱꽝이니 조심해서 체크 바란다.
사용자 삽입 이미지

2009/02/04 13:04 2009/02/04 13:04

C# Windows Forms 프로그래밍을 하면 의외로 Form끼리 데이터 공유가 안되서 애먹는 모습을 종종 보았다.

다음과 같은 폼이 있다고 가정하고

namespace TEST
{
    public partial class FormMain : Form
    {
        public string Value
        { 
            get;set;
        }
        public FormMain()
        {
            InitializeComponent();
            RunChild();
        }
        private void RunChild()
        {
            FormLogin cdf = new FormLogin (this);
            cdf.ShowDialog(); //혹은 cdf.Show();
        } 
     }
}

Value에 대한 GET;SET; 속성을 정의하여 준다.

다른 폼에서는
namespace TEST
{
    public partial class FormLogin : Form
    {
        FormMain MotherFrm;
        public FormLogin(FormMain FatherFrm)
        {
            this.MotherFrm = FatherFrm;
            InitializeComponent();
        }
    }
}

와 같이 정의하여주면 MotherFrm.Value와 같이 사용이 가능하다.

2008/10/15 14:14 2008/10/15 14:14

본격적인 LINQ 실행을 함 해보자.
예고와는 다르게 일단 XML부터 Linq를 통해 한번 제대로 굴려보도록 하자.

1. XML 파싱하기.
먼저 다음과 같이 XML파일 하나 만들어 보자
(파일명은 test.xml로 하자.)

<?xml version="1.0" encoding="utf-8" ?>
<config>
   <id>111.111.111.111</id>
   <user>vic</user>
   <pass>password</pass>
</config>

일반적으로 많이 만들어 사용하는 콘피그 파일이다.
Linq이전에는 이녀석을 비교하려고 XML Document 열어서 열심히 While문으로 Read했었다.
Linq로 이놈을 한번 분석해보면 다음과 같이 매우 짧게 진행할 수 있다.

using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

class Test {   static void Main(){    XDocument xe = XDocument.Load(System.Windows.Forms.Application.StartupPath  + "\\test.xml");     var query = from c in xe.Descendants("config")                     select c;

   foreach(var q in query)    {       Console.WriteLine(q);    }    Console.ReadLine();   }  }


실행시켜보면 위의 XML전체가 출력되는 것을 볼수 있을 것이다.
이제 이녀석을 좀더 다듬어 보자.
"select c;"라고 된 부분을 "select c.Element("id");"로 바꿔보자.
    var query = from c in xe.Descendants("config") 
                    select c.Element("id");

실행을 하면 XML의 ID부분만 출력이 될 것이다.
<id>111.111.111.111</id>

어쩐지 제대로 찾아 들어오는 느낌. 이제 아까 바꾼 "select c.Element("id");"를
"select c.Element("id").Value;"로 바꿔보자.
    var query = from c in xe.Descendants("config") 
                    select c.Element("id").Value;

실행하면 결과가 아주 이쁘게 값만 떨어진다.
111.111.111.111

그런데 여기서 만족할 수 없다. 여러개의 값을 가려오려면 어떻게 해야 할 까?
다음과 같이 함 바꿔보자.

    var query = from c in xe.Descendants("config") 
                    select new 
                    {
                        id = c.Element("id").Value,
                       user = c.Element("user").Value
                     }
   //이번에는 foreach문도 바꿔주자
   foreach(var q in query)
   {
      Console.WriteLine(q.id + q.user);
   }   

결과는 직접 함 해보도록하고 이제 다음단계로 SQL문처럼 한번 써보자.
다음과 같이 바꿔보고 실행 함 해보자.
    var query = from c in xe.Descendants("config") 
                where c.Element("user").Value == "vic"
                select c;

어떤게 나오는가? where문이 진짜 먹으니 뿌듯한 느낌!

2. XML생성
이제 한걸음 더 나가서 XML을 생성함 해보자.
사용은 무지 쉽다.
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

class Test {   static void Main(){   XDocument xdoc =       new XDocument(       new XDeclaration("1.0", "UTF-8", "yes"),       new XProcessingInstruction("TEST", "TEST Data"),       new XComment("테스트 XML"),       new XElement("config",           new XElement("id", "1234"),           new XElement("user", "abc")       )            );    xdoc.Save(System.Windows.Forms.Application.StartupPath  + "\\test.xml");   }  }



test,xml을 열어 보면
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?TEST TEST Data?>
<!--테스트 XML-->
<config>
  <id>1234</id>
  <user>abc</user>
</config>

이렇게 정확하게 들어와 있는 것이 보일것이다.

2008/04/16 13:09 2008/04/16 13:09
가면갈수록 어려워지니 쩝...
뭐 암튼...

test.dll이란 이름의 C++로 만들어진 DLL이 있다고 치자.
그리고 그것의 함수는 다음과 같다고 치자.

int returnInt(int a)
{
    return a;
}


이녀석을 컴파일 하면 test.dll 이란게 생길것이다. 이녀석을 Debug라고하는 컴파일후 생성되는 폴더에 재주껏 넣어 놓고 다음과 같이 코딩해보자.

using System;
using System.Runtime.InteropServices; //여기 선언 중요
class InvokeTest
{
    [DllImport("test.dll")] //만약 함수명이 다르면 EntryPoint="function_name" 지정
    public static extern int returnInt(int a);//외부정의함수이므로 extern과 static필수 

    public static void Main()     {         int i = returnInt(1);         Console.WriteLine(i);     } }

2007/09/03 22:02 2007/09/03 22:02