Post List

레이블이 Algorithm인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Algorithm인 게시물을 표시합니다. 모든 게시물 표시

2016년 4월 1일 금요일

[Top 20 Coding Interview] 20.Selection Sort (C#)

Selection Sort

Sorting an Array using Selection Sort
Selection Sort(선택정렬)을 구현하세요.
Selection Sort가 무엇인지는 아래 Link를 참조하세요.

C#

using System;

class Program
{
    static void SelectionSort<T>(ref T[] array ) where T : IComparable
    {
        for (int i = 0; i < array.Length; i++)
        {
            T minValue = array[i];
            int minIndex = i;

            for (int j = i + 1; j < array.Length; j++)
            {
                if (array[j].CompareTo(minValue) < 0)
                {
                    minValue = array[j];
                    minIndex = j;
                }
            }

            if (i != minIndex)
            {
                T temp = array[i];
                array[i] = minValue;
                array[minIndex] = temp;
            }
        }
    }
    static void Main(string[] args)
    {
        int[] array = { 9, 4, 6, 5, 7, 8, 3, 2, 1, 0 };

        SelectionSort<int>(ref array);

        foreach(int n in array)
        {
            Console.Write($"{n}\t");
        }

        Console.WriteLine();
    }
}

[Top 20 Coding Interview] 19. Sum Digits (C#)

Sum Digits

How to find sum of digits of a number using Recursion?
재귀함수를 사용해서 입력된 숫자의 각 자리수를 더하세요.

C#

class Program
{
    static int SumDigits(int number)
    {
        if (number < 0)
            number *= -1;

        if (number < 10)
            return number;

        return number % 10 + SumDigits(number / 10);
    }
    static void Main(string[] args)
    {
        int[] digits = { 123456, 654321, -126543 };
        int[] result = { SumDigits(digits[0]),
                         SumDigits(digits[1]),
                         SumDigits(digits[2]) };

        for (int i = 0; i < result.Length; i++)
        {
            System.Console.WriteLine($"Sum Digits of {digits[i]} is {result[i]}");
        }
    }
}

[Top 20 Coding Interview] 18.Remove Duplicates In Sorted Linked List (C#)

Q.18.Remove Duplicates In Sorted Linked List

How to remove duplicates from a sorted linked list?
정렬된 Linked List에서 중복값을 제거하세요.
16번문제에서 만든 LinkedNode<T> class에 아래 1개의 method를 추가했습니다.

C# 추가한 method

public void RemoveDuplicatesInSortedLinkedList()
{
    if (!IsSorted())
        throw new Exception("Not Sorted");

    LinkedNode<T> traveling = GetFisrt();

    while (traveling._next != null)
    {
        if (traveling.Value.CompareTo(traveling._next.Value) == 0)
        {
            traveling.Next = traveling._next._next;
        }
        traveling = traveling._next;
    }
}

C# 전체 Code (Test 포함)

using System;
using System.Collections.Generic;

class LinkedNode<T> where T : IComparable
{
    public T Value { set; get; }

    private LinkedNode<T> _previous = null;
    private LinkedNode<T> _next = null;

    public LinkedNode<T> Previous
    {
        set
        {
            _previous = value;
            if (value != null)
                value._next = this;
        }
        get
        {
            return _previous;
        }
    }

    public LinkedNode<T> Next
    {
        set
        {
            _next = value;
            if (value != null)
                value._previous = this;
        }
        get
        {
            return _next;
        }
    }

    public LinkedNode(T value)
    {
        Value = value;
    }

    public bool DetectCirculation()
    {
        List<LinkedNode<T>> vVisitedNodes = new List<LinkedNode<T>>();
        vVisitedNodes.Add(this);

        LinkedNode<T> traveling = Previous;
        while (traveling != null)
        {
            foreach (LinkedNode<T> visited in vVisitedNodes)
                if (visited == traveling)
                    return true;
            vVisitedNodes.Add(traveling);
            traveling = traveling.Previous;
        }

        traveling = Next;
        while (traveling != null)
        {
            foreach (LinkedNode<T> Visited in vVisitedNodes)
                if (Visited == traveling)
                    return true;
            vVisitedNodes.Add(traveling);
            traveling = traveling.Next;
        }

        return false;
    }

    public LinkedNode<T> GetFisrt()
    {
        if (DetectCirculation())
            throw new Exception("Circulation Linked Node");
        LinkedNode<T> findFirst = this;

        while (findFirst._previous != null)
        {
            findFirst = findFirst._previous;
        }

        return findFirst;
    }

    public LinkedNode<T> GetLast()
    {
        if (DetectCirculation())
            throw new Exception("Circulation Linked Node");
        LinkedNode<T> findLast = this;

        while (findLast._next != null)
        {
            findLast = findLast._next;
        }

        return findLast;
    }

    public bool IsSorted()
    {
        LinkedNode<T> traveling = GetFisrt();

        while (traveling._next != null)
        {
            if (traveling.Value.CompareTo(traveling._next.Value) > 0)
                return false;
            traveling = traveling._next;
        }

        return true;
    }

    public static LinkedNode<T> Merge(LinkedNode<T> list1, LinkedNode<T> list2)
    {
        if (list1 != null && !list1.IsSorted())
            throw new Exception("No Sorted List Inserted : " + nameof(list1));

        if (list2 != null && !list2.IsSorted())
            throw new Exception("No Sorted List Inserted : " + nameof(list2));

        if (list1 == null)
        {
            return list2;
        }
        else if (list2 == null)
        {
            return list1;
        }

        LinkedNode<T> first = null;
        LinkedNode<T> current = null;

        LinkedNode<T> node1 = list1.GetFisrt();
        LinkedNode<T> node2 = list2.GetFisrt();

        if (node1.Value.CompareTo(node2.Value) >= 0)
        {
            first = node2;
            current = first;
            node2 = node2.Next;
        }
        else
        {
            first = node1;
            current = first;
            node1 = node1.Next;
        }

        while (node1 != null && node2 != null)
        {
            if (node1.Value.CompareTo(node2.Value) >= 0)
            {
                current.Next = node2;
                current = current.Next;
                node2 = node2.Next;
                if (node2 == null)
                {
                    current.Next = node1;
                    break;
                }
            }
            else
            {
                current.Next = node1;
                current = current.Next;
                node1 = node1.Next;
                if (node1 == null)
                {
                    current.Next = node2;
                    break;
                }
            }
        }
        return first;
    }

    public void Reverse()
    {
        LinkedNode<T> newFirst = GetLast();
        LinkedNode<T> travelingForward = newFirst;
        LinkedNode<T> travelingBackward = travelingForward._previous;

        while (travelingBackward != null)
        {
            travelingForward._next = travelingBackward;

            travelingForward = travelingForward._next;
            travelingBackward = travelingBackward._previous;
        }

        travelingForward._next = null;
        newFirst._previous = null;

        travelingForward = newFirst;
        while (travelingForward._next != null)
        {
            travelingForward.Next = travelingForward._next;
            travelingForward = travelingForward._next;
        }
    }

    public void RemoveDuplicatesInSortedLinkedList()
    {
        if (!IsSorted())
            throw new Exception("Not Sorted");

        LinkedNode<T> traveling = GetFisrt();

        while (traveling._next != null)
        {
            if (traveling.Value.CompareTo(traveling._next.Value) == 0)
            {
                traveling.Next = traveling._next._next;
            }
            traveling = traveling._next;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        LinkedNode<int> node1 = new LinkedNode<int>(1);
        LinkedNode<int> node2 = new LinkedNode<int>(3);
        LinkedNode<int> node3 = new LinkedNode<int>(5);
        LinkedNode<int> node4 = new LinkedNode<int>(6);
        node1.Next = node2;
        node2.Next = node3;
        node3.Next = node4;

        LinkedNode<int> node5 = new LinkedNode<int>(1);
        LinkedNode<int> node6 = new LinkedNode<int>(5);
        LinkedNode<int> node7 = new LinkedNode<int>(8);
        LinkedNode<int> node8 = new LinkedNode<int>(9);
        node5.Next = node6;
        node6.Next = node7;
        node7.Next = node8;

        LinkedNode<int> merged = LinkedNode<int>.Merge(node1, node5);

        merged.RemoveDuplicatesInSortedLinkedList();

        LinkedNode<int> ret = merged.GetFisrt();

        while (ret != null)
        {
            System.Console.Write(string.Format("{0,4}", ret.Value));
            ret = ret.Next;
        }
        System.Console.WriteLine("");
    }
}

2016년 3월 31일 목요일

[Top 20 Coding Interview] 17. Rotate Array (C#)

Rotate Array

How to rotate an array by a given pivot ?
Array를 주어진 Pivot(중심점) 만큼 Rotate하세요.
한마디로 Shift하되 밀려나간만큼 뒤에 다시 붙이라는 말입니다.
원문의 Link를 보면 기가 막힌 방법으로 단 하나의 임시변수만 할당하면서도 숫자들을 많이 이동시키지 않고 풀었더군요.
대신 그것을 보고 실제로 맞게 동작하는지를 해석하는데 시간이 좀 걸렸습니다.
저는 그냥 array크기만큼의 임시공간을 사용했지만,
그냥 누가봐도 이해하기 쉽게 작성하였습니다.

C

using System;

class Program
{
    static void Rotate(ref int[] array, int pivot)
    {
        if (pivot > array.Length)
            throw new ArgumentOutOfRangeException();

        int[] original = (int[])array.Clone();

        int nRotateCount = array.Length - pivot;

        for (int i = 0; i < nRotateCount; i++)
        {
            array[i] = original[i + pivot];
        }

        for (int i = nRotateCount; i < array.Length; i++)
        {
            array[i] = original[nRotateCount - i];
        }
    }
    static void Main(string[] args)
    {
        int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        Rotate(ref array, 1);

        foreach (int element in array)
        {
            Console.Write(string.Format("{0,4}", element));
        }

        Console.WriteLine("");
        Console.ReadKey();
    }
}

[Top 20 Coding Interview] 16. Reverse Linked List (C#)

Reverse Linked List

Write code to reverse a linked list, if you able to do it using loops, try to solve with recursion?
Linked List를 Reverse하세요. (뒤집으세요.)
역으로 진행되도록 만드세요. 라고 이해하면 됩니다.
3번문제에서 만든 LinkedNode<T> class에 아래 2개의 method를 추가했습니다.

C# 추가한 method

public LinkedNode<T> GetLast()
{
    if (DetectCirculation())
        throw new Exception("Circulation Linked Node");
    LinkedNode<T> findLast = this;

    while (findLast._next != null)
    {
        findLast = findLast._next;
    }

    return findLast;
}

public void Reverse()
{
    LinkedNode<T> newFirst = GetLast();
    LinkedNode<T> travelingForward = newFirst;
    LinkedNode<T> travelingBackward = travelingForward._previous;

    while (travelingBackward != null)
    {
        travelingForward._next = travelingBackward;

        travelingForward = travelingForward._next;
        travelingBackward = travelingBackward._previous;
    }

    travelingForward._next = null;
    newFirst._previous = null;

    travelingForward = newFirst;
    while(travelingForward._next != null)
    {
        travelingForward.Next = travelingForward._next;
        travelingForward = travelingForward._next;
    }
}

C# 전체 Code (Test 포함)

using System;
using System.Collections.Generic;

class LinkedNode<T> where T : IComparable
{
    public T Value { set; get; }

    private LinkedNode<T> _previous = null;
    private LinkedNode<T> _next = null;

    public LinkedNode<T> Previous
    {
        set
        {
            _previous = value;
            if (value != null)
                value._next = this;
        }
        get
        {
            return _previous;
        }
    }

    public LinkedNode<T> Next
    {
        set
        {
            _next = value;
            if (value != null)
                value._previous = this;
        }
        get
        {
            return _next;
        }
    }

    public LinkedNode(T value)
    {
        Value = value;
    }

    public bool DetectCirculation()
    {
        List<LinkedNode<T>> vVisitedNodes = new List<LinkedNode<T>>();
        vVisitedNodes.Add(this);

        LinkedNode<T> traveling = Previous;
        while (traveling != null)
        {
            foreach (LinkedNode<T> visited in vVisitedNodes)
                if (visited == traveling)
                    return true;
            vVisitedNodes.Add(traveling);
            traveling = traveling.Previous;
        }

        traveling = Next;
        while (traveling != null)
        {
            foreach (LinkedNode<T> Visited in vVisitedNodes)
                if (Visited == traveling)
                    return true;
            vVisitedNodes.Add(traveling);
            traveling = traveling.Next;
        }

        return false;
    }

    public LinkedNode<T> GetFisrt()
    {
        if (DetectCirculation())
            throw new Exception("Circulation Linked Node");
        LinkedNode<T> findFirst = this;

        while (findFirst._previous != null)
        {
            findFirst = findFirst._previous;
        }

        return findFirst;
    }

    public LinkedNode<T> GetLast()
    {
        if (DetectCirculation())
            throw new Exception("Circulation Linked Node");
        LinkedNode<T> findLast = this;

        while (findLast._next != null)
        {
            findLast = findLast._next;
        }

        return findLast;
    }

    public bool IsSorted()
    {
        LinkedNode<T> traveling = GetFisrt();

        while (traveling._next != null)
        {
            if (traveling.Value.CompareTo(traveling._next.Value) > 0)
                return false;
            traveling = traveling._next;
        }

        return true;
    }

    public static LinkedNode<T> Merge(LinkedNode<T> list1, LinkedNode<T> list2)
    {
        if (list1 != null && !list1.IsSorted())
            throw new Exception("No Sorted List Inserted : " + nameof(list1));

        if (list2 != null && !list2.IsSorted())
            throw new Exception("No Sorted List Inserted : " + nameof(list2));

        if (list1 == null)
        {
            return list2;
        }
        else if (list2 == null)
        {
            return list1;
        }

        LinkedNode<T> first = null;
        LinkedNode<T> current = null;

        LinkedNode<T> node1 = list1.GetFisrt();
        LinkedNode<T> node2 = list2.GetFisrt();

        if (node1.Value.CompareTo(node2.Value) >= 0)
        {
            first = node2;
            current = first;
            node2 = node2.Next;
        }
        else
        {
            first = node1;
            current = first;
            node1 = node1.Next;
        }

        while (node1 != null && node2 != null)
        {
            if (node1.Value.CompareTo(node2.Value) >= 0)
            {
                current.Next = node2;
                current = current.Next;
                node2 = node2.Next;
                if (node2 == null)
                {
                    current.Next = node1;
                    break;
                }
            }
            else
            {
                current.Next = node1;
                current = current.Next;
                node1 = node1.Next;
                if (node1 == null)
                {
                    current.Next = node2;
                    break;
                }
            }
        }
        return first;
    }

    public void Reverse()
    {
        LinkedNode<T> newFirst = GetLast();
        LinkedNode<T> travelingForward = newFirst;
        LinkedNode<T> travelingBackward = travelingForward._previous;

        while (travelingBackward != null)
        {
            travelingForward._next = travelingBackward;

            travelingForward = travelingForward._next;
            travelingBackward = travelingBackward._previous;
        }

        travelingForward._next = null;
        newFirst._previous = null;

        travelingForward = newFirst;
        while(travelingForward._next != null)
        {
            travelingForward.Next = travelingForward._next;
            travelingForward = travelingForward._next;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        LinkedNode<int> node1 = new LinkedNode<int>(1);
        LinkedNode<int> node2 = new LinkedNode<int>(3);
        LinkedNode<int> node3 = new LinkedNode<int>(5);
        LinkedNode<int> node4 = new LinkedNode<int>(6);
        node1.Next = node2;
        node2.Next = node3;
        node3.Next = node4;

        LinkedNode<int> node5 = new LinkedNode<int>(2);
        LinkedNode<int> node6 = new LinkedNode<int>(4);
        LinkedNode<int> node7 = new LinkedNode<int>(8);
        LinkedNode<int> node8 = new LinkedNode<int>(9);
        node5.Next = node6;
        node6.Next = node7;
        node7.Next = node8;

        LinkedNode<int> merged = LinkedNode<int>.Merge(node1, node5);

        merged.Reverse();

        LinkedNode<int> ret = merged.GetFisrt();

        while (ret != null)
        {
            System.Console.Write(string.Format("{0,4}", ret.Value));
            ret = ret.Next;
        }
        System.Console.WriteLine("");
    }
}

2016년 3월 28일 월요일

[Top 20 Coding Interview] 15. Check Duplicates (C#)

Check Duplicates

Algorithm to find if Array contains duplicates?
배열에 중복된 값이 있는지 검사하세요.

C#

using System;
using System.Collections.Generic;

class Program
{
    static bool HaveDuplicates<T>(List<T> list) where T : IComparable
    {
        int nCnt = list.Count;

        for (int i = 0; i < nCnt; i++)
        {
            for (int j = i + 1; j < nCnt; j++)
            {
                if (list[i].CompareTo(list[j]) == 0)
                    return true;
            }
        }

        return false;
    }
    static void Main(string[] args)
    {
        List<string> listStr = new List<string> { "Luna", "Star", "Silver", "Dev", "star", "luna" };
        List<int> listInt = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 5 };

        Console.WriteLine(string.Format("{0} have duplicates ? {1}",
            nameof(listStr), HaveDuplicates<string>(listStr) ? "Yes" : "No"));

        Console.WriteLine(string.Format("{0} have duplicates ? {1}",
            nameof(listInt), HaveDuplicates<int>(listInt) ? "Yes" : "No"));
    }
}

2016년 3월 15일 화요일

[Top 20 Coding Interview] 14. Palindrome (C#)

Check Palindrome

Algorithm to check if a number is Palindrome?
Palindrome인지 검사하세요.

Palindrome란 ? 문자, 숫자의 순서가 앞에서 읽은 것과 뒤에서 읽은 것이 같은 것을 의미합니다.
가장 대표적인 예제로는 다음과 같은 것들이 있습니다.
"A man, a plan, a canal, Panama!", "Amor, Roma", "race car", "stack cats", "step on no pets", "taco cat", "put it up", "Was it a car or a cat I saw?" and "No 'x' in Nixon".

C#

class Program
{
    static bool IsCharOrNumber(char c)
    {
        return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '1' && c <= '0');
    }

    static bool IsPalindrome(string str)
    {
        str = str.ToLower();

        int forward = 0;
        int backward = str.Length - 1;

        while (forward < backward)
        {
            while (!IsCharOrNumber(str[forward]))
                forward++;

            while (!IsCharOrNumber(str[backward]))
                backward--;

            if (str[forward] != str[backward])
                return false;

            forward++;
            backward--;
        }

        return true;
    }

    static void Main(string[] args)
    {
        System.Console.WriteLine(string.Format("[{0}] is Palindrome ? {1}",
            "A man, a plan, a canal, Panama!",
            IsPalindrome("A man, a plan, a canal, Panama!") ? "Yes" : "No"));

        System.Console.WriteLine(string.Format("[{0}] is Palindrome ? {1}",
            "LunaStar the Silver",
            IsPalindrome("LunaStar the Silver") ? "Yes" : "No"));
    }
}