퇴근5분전

 

 

임의의 수 n 이 짝수이면 / 2, 홀수이면 *3 + 1

n이 1이 될때까지의 회수를 구한다.  이는 1,000,000 까지 유효하다.

ex) 22를 넣으면 16이 나옴. ( 22 짝수 /2 -> 11 홀수 * 3 +1 > 34 ... 1 까지 총 16회 )

 

 결과) 딱 3줄로 정리됨. ( 재귀 )

 

두범위의 숫자내에 최대횟수를 구하라.

1 10      =  20

100 200 = 125

...

 

 

'# 1) 프로그래밍 > 프로그래밍챌린지' 카테고리의 다른 글

Chapter 01. Q4. LCD 숫자 표시  (0) 2014.07.04
Chapter 01. Q3. 여행... ㅡ.,ㅡ?  (0) 2014.07.04
Chapter 01. Q2. 지뢰찾기  (0) 2014.07.02
시작하며...  (0) 2014.07.01

 

알고리즘 트레이닝을 다시 시작하며. 이번엔 정리를 해본다.

목표는 일주일에 3개 씩.

꾀 오래전에 사둔 책으로 잠깐씩 봤던것인데... 기술사 공부하면서 틈틈히 해보자.

 

 

 

'# 1) 프로그래밍 > 프로그래밍챌린지' 카테고리의 다른 글

Chapter 01. Q4. LCD 숫자 표시  (0) 2014.07.04
Chapter 01. Q3. 여행... ㅡ.,ㅡ?  (0) 2014.07.04
Chapter 01. Q2. 지뢰찾기  (0) 2014.07.02
Chapter 01. Q1. 3n+1  (0) 2014.07.01

 

음... 어떤 계기로 인해 사용하게 된 디렉토리 생성 코드

if (Directory.Exists("workreport") == false)
{
    Directory.CreateDirectory("workreport");
}
if (Directory.Exists("workreport\\csv") == false)
{
    Directory.CreateDirectory("workreport\\csv");
}

 

이거.. 그냥

Directory.CreateDirectory("workreport\\csv");

이러면 된다.

 

오늘 툴 만들면서 확인한 내용인데... 어허... 왜 각 디렉토리를 체크하면서 디렉토리를 생성했었는지 기억이 안남...

 

파일을 복사할때 디렉토리가 온전하게 있지 않으면 에러가 발생하는데

이때 디렉토리 경로만 얻어서 디렉토리를 생성하면 된다!

왜 저렇게 삽질을 했었는지 기억이 안나 ...

 

// process 경로 읽어오기.

http://stackoverflow.com/questions/5497064/c-how-to-get-the-full-path-of-running-process 

 

System.Management   참조.

 
        static private string ProcessExecutablePath(Process process)
        {
            try
            {
                return process.MainModule.FileName;
            }
            catch
            {
                string query = "SELECT ExecutablePath, ProcessID FROM Win32_Process";
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);

                foreach (ManagementObject item in searcher.Get())
                {
                    object id = item["ProcessID"];
                    object path = item["ExecutablePath"];

                    if (path != null && id.ToString() == process.Id.ToString())
                    {
                        return path.ToString();
                    }
                }
            }

            return "";
        }

 

64bit 머신에서 메모장(32bit)을 읽어오려고 확인해봤더니

 

원래 알던 Proecess.StartInfo.fileName.. 이라든가 Module에서 정보를 확인해보려고 했지만...

32bit 모듈은 알수 없다는 디버깅 정보가 표시되서 확인이 안되었다.

위에 소스는 찾은 결과...

'# 1) 프로그래밍' 카테고리의 다른 글

ExtJs > ExtNet 변환 툴!!!  (0) 2014.07.10
Directory.Create 관련...  (0) 2014.06.09
가장 가까운 점 구하기  (0) 2014.02.08
한글분해_결합, 오토마타...  (0) 2014.01.30
달력 컨트롤] 새로 만든 달력!!!  (0) 2014.01.26

 

  이번 오브젝트 툴을 만들면서 오브젝트간에 관계 표시를 위해 라인을 그리던중...

기존에는 (오브젝트)중심점 --- (오브젝트)중심점으로 라인을 잡고 오브젝트면과의 교차점등을 구해서 라인을 그렸었는데...

 

  생각해보니 내부에 다각형을 넣어두고 중심점이 아닌 다각형 꼭지점간에 라인을 그리면 좀더 많은 라인을 중첩되지 않게 구현이 될듯 하여 사각 박스 내부에 들어갈 다각형을 고민하였다. ppt에 원을 넣고 클릭하면 몇개의 점들이 보이는데 이걸 참고하기로 하였다.

 

 우선 사각형을 만들었고, 내부에 원을 그려넣었는데 이 원의 꼭지점 갯수를 정했다 16개!

 

그리고 각 오브젝트간 관계에 대한 선을 그리기 전에 오브젝트간에 가장 가까운 점을 구하게 되었다.

 

알고리즘도 있는듯 한데 어차피 대상이 16개 - 16개 이므로 하나씩 루프를 돌며 찾는다.

 

 

 

 완성된 모습... 오브젝트를 이리 저리 옮겨봐도 역시 잘 찾아서 따라온다.

 

Box = UserControl

내부 동그라미는 별도 관리 객체를 만들었고 Box내부에서 Paint로 그린다.

 

라인이 그려지기 전에 각 오브젝트간 관계에 따라 가까운 점을 찾아 그린다. ( 계산은 별도관리객체에서 한다. )

 

각 포인트마다 char 문자를 준 이유는 가장 가까운 점을 찾은 후 다음 관계라인을 그릴때는 다음 가까운 라인을 찾기 위해 쓰여진다.

 

 

 

'# 1) 프로그래밍' 카테고리의 다른 글

Directory.Create 관련...  (0) 2014.06.09
C#] 프로세스의 파일경로 읽어오기.  (0) 2014.05.30
한글분해_결합, 오토마타...  (0) 2014.01.30
달력 컨트롤] 새로 만든 달력!!!  (0) 2014.01.26
알고리즘] 2  (0) 2013.11.15

 

 전 부터 몇번 시도했었지만.. 어렵던 오토마타가 성공했다.

전엔 검색해도 글이 얼마 없더니 엄청 늘어나있네...

참고자료 : http://ydongyol.tistory.com/m/30   <-- 오토마타 설명인데 중간에 이해 안되는 것들이 많다.

               http://i-coo.tistory.com/m/48     <-- 유니코드 분해, 결합

               http://cook.byus.net/wp/?p=475 <-- 가상키보드 만들기 ( ie10에선 안돌더라 )

 

 

제일 위에 분해 결합. 뷃 이란 글자를 분해하고, 다시 재결합한 모양.

 

아래 IN, OUT은 Step+를 통해서 하나씩 입력하게 해서 한글이 만들어지는 과정을 확인했음.

char[] inputChars = new char[] { 'ㄹ', 'ㅣ', 'ㄴ', 'ㅜ', 'ㄱ', 'ㅅ', 'ㅡ', 'ㄹ', 'ㅣ', 'ㄴ', 'ㅜ', 'ㄱ', 'ㅅ', 'ㅡ' };

 

 

 

구현한 내용은 두가지를 짬뽕해서 만들었는데, 실제 오토마타라기 보다 한글 끼워맞추기?

각 한글 자음 모음이 들어와서 저장하는 것은 오토마타 로직을 이용했는데,

초성 중성 종성은 계산에 의한것이 아닌 초성, 중성, 종성자 모음에서 찾아오는 것으로 살짝 바꿨다.

 

그리고 최종 찾은 문자들로 오토마타의 End1, End2에서는 각 문자를 결합하였고...

 

키보드 키를 눌러 각 문자가 들어왔을때 결합시점을 언제해야되는지 몰라서 오토마타 로직을 다시 보고 다시보고..

하루를 꼬박 보고 비슷하게 구현이 되었다. 약간에 오류를 수정하고나니 이제 된다.

 

오토마타와 다른 부분은 스택을 안썼다. 소스가 부분 부분 나온데다가 몇개의 소스를 내려받아서 봤는데

각기 다른 방식으로 구현이 되어있어서 분석이 어렵더라..

 

 한글이 각각 들어오는 부분과 오토마타 처리 로직과 비교해보면서 엑셀에 정리해서 코딩을 수정하면서

꼬박 하루 걸렸다.

 

 

 

 

 

 

 

 

 

'# 1) 프로그래밍' 카테고리의 다른 글

C#] 프로세스의 파일경로 읽어오기.  (0) 2014.05.30
가장 가까운 점 구하기  (0) 2014.02.08
달력 컨트롤] 새로 만든 달력!!!  (0) 2014.01.26
알고리즘] 2  (0) 2013.11.15
알고리즘] 1  (0) 2013.11.14

 

다시 만들었다.

 

 

 

디자인은 동일하게 가져가고 내부 로직은 좀더 간결하게 바꾸었다.

 

주차에 대한것은 아래처럼 몇주차를 어렵게 구하지 않고 현재로부터 -1, + 1 형태로 변수 세개로 처리했다.

기존 달력은 문제점이... 조금씩 틀어지는 부분이 있어서 위처럼 1픽셀까지 맞추었다.

 

 

 

 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 이 달력은 새로 만든 스케쥴러에 사용한 달력임.

 

휴일과 관련된 내용과 몇 주차 인지에 대해 계산에 사용한 방법등을 기록해본다.

 

 # 해당년도의 1월 1일의 요일에 대한 코드값을 구한다.

int {올해 1월1일 요일} =  (int)new DateTime(DateTimeInfo.Year, 1, 1).DayOfWeek;

요일은

일요일 = 0,

월요일 = 1,

...

토요일 = 6

 

 

몇주차 구하기 :

한해는 365일로 7로 나누면 52.1... 총 53주가 나옴.

 

DateTimeInfo.DayOfYear  는 올해 365일중 몇일인지가 나옴.

 

int 몇주차 = (DateTimeInfo.DayOfYear + {올해 1월1일 요일}) / 7;
if ((DateTimeInfo.DayOfYear + {올해 1월1일 요일}) % 7 > 0) thisWeekCnt++;

 

전주, 금주, 차주를  구하면서...

년도가 바뀌는 부분인 12월 31일 ~ 1월1일로 지나가는 주차 묶어주는 계산

ex)    ((2014 - 2013 )*53) - ((2014-2013)*계산주) + ( 이번주차 - 1)

 

계산주 같은 경우 전년도 계산주기때문에 12월 마지막주와 새해 1월 1일은 같은 주차가 되는데

12월 마지막주차는 53주차로 위 계산에서 0이 되므로!

12월 마지막주의 전주는 52이므로 1을 더하게 된다.. 이렇게 계산되면 계속 전주차는 계속 줄어듬...

 

if (StartDateTime.Year == DateTime.Today.Year)
{
    int weekGap = thisWeekCnt - calcWeekCnt;
    if (weekGap == 0)
    {
        weekCountButton.Text = "금주";
    }
    else if (weekGap == 1)
    {
        weekCountButton.Text = "전주";
    }
    else if (weekGap == -1)
    {
        weekCountButton.Text = "차주";
    }
    else
    {
        weekCountButton.Text = - (weekGap) + " 주";
    }
}
else
{
    weekCountButton.Width -= 3;
    weekCountButton.Text = -((((DateTime.Today.Year - StartDateTime.Year) * 53) - ((DateTime.Today.Year -  StartDateTime.Year) * calcWeekCnt)) + (thisWeekCnt - 1)) + " 주";                         
}

 

전주차 ( 년도 변환되는 곳 )

 

 

# 국경일 기념일 처리..

private SortedList<DateTime, string> GetDayHolidays(int year)
{
    //휴일 
    SortedList<DateTime, string> holidays = new SortedList<DateTime, string>();
    //( 양력 )
    holidays.Add(new DateTime(year, 1, 1), "신정"); // 신정
    holidays.Add(new DateTime(year, 3, 1), "3.1절"); // 3.1절(5대 국경일)
    holidays.Add(new DateTime(year, 5, 5), "어린이날"); // 어린이날
    holidays.Add(new DateTime(year, 6, 6), "현충일"); // 현충일
    //holidays.Add(new DateTime(year, 7, 17), "제헌절"); // 제헌절 (5대 국경일, 휴일에서 제외됨)
    holidays.Add(new DateTime(year, 8, 15), "광복절"); // 광복절 (5대 국경일)
    holidays.Add(new DateTime(year, 10, 3), "개천절"); // 개천절(5대 국경일)
    holidays.Add(new DateTime(year, 10, 9), "한글날"); // 한글날(5대 국경일)
    holidays.Add(new DateTime(year, 12, 25), "크리스마스"); // 크리스마스
    //음력
    KoreanLunisolarCalendar kc = new KoreanLunisolarCalendar();
    //설
    holidays.Add(kc.ToDateTime(year, 1, 1, 0, 0, 0, 0), "설");
    holidays.Add(kc.ToDateTime(year, 1, 1, 0, 0, 0, 0).AddDays(-1), "설(전)");
    holidays.Add(kc.ToDateTime(year, 1, 1, 0, 0, 0, 0).AddDays(+1), "설(후)");
    //석가탄신일
    holidays.Add(kc.ToDateTime(year, 4, 8, 0, 0, 0, 0), "석가탄신일");
    //추석
    holidays.Add(kc.ToDateTime(year, 8, 15, 0, 0, 0, 0), "추석");
    holidays.Add(kc.ToDateTime(year, 8, 15, 0, 0, 0, 0).AddDays(-1), "추석(전)");
    holidays.Add(kc.ToDateTime(year, 8, 15, 0, 0, 0, 0).AddDays(+1), "추석(후)");
    return holidays;
}

 

 

적용 )

var holidays = DayHolidays.Where(d => (d.Key.Year == _info.DateTimeInfo.Year && d.Key.Month == _info.DateTimeInfo.Month))

                                      .Select(d => new { DAY = d.Key.Day, DESC = d.Value });

 

if (holidays.Where(d => d.DAY == _info.DateTimeInfo.Day).Count() > 0)
{
    _btn.ForeColor = HolidayForeColor;
    string tooltip = holidays.Where(d => d.DAY == _info.DateTimeInfo.Day).Select(t => t.DESC).First();
    _btn.MouseHover += (s, e) => { toolTip1.SetToolTip(_btn, tooltip); };
}

 

- 설 같은것 툴팁으로 표시 ( 음력계산기를 이용 함 )

 

 

 

 

 

 

 

 

'# 1) 프로그래밍' 카테고리의 다른 글

가장 가까운 점 구하기  (0) 2014.02.08
한글분해_결합, 오토마타...  (0) 2014.01.30
알고리즘] 2  (0) 2013.11.15
알고리즘] 1  (0) 2013.11.14
C#] 문자열 정렬처리...  (0) 2013.11.10

 

친구가 준 문제2

 

N개의 열과 M개의 행으로 구성된 사각형 맵이 있는데, 각 영역은 특정 색으로 칠해져 있다.
맵의 두 영역은 다음 조건이 만족될 때 같은 나라에 포함된다.
같은 색을 가지고 있다.
다른 색으로 칠해진 영역을 거치지 않고, 동서남북 네 방향으로만 움직여서 한 영역에서 다른 영역으로 이동할 수 있다.
맵은 인덱스 0에서 시작하는 M열과 N행으로 구성된 정수들의 매트릭스로 기술될 수 있다. 각 영역의 색은 매트릭스의 각 요소로써 기술된다.
두 영역은 매트릭스의 각 요소가 같은 값을 가질 때에만 같은 색을 가진다.
예를 들어, 7열, 3행으로 구성된 매트릭스 A를 생각해보자.
A[0][0] = 5 A[0][1] = 4 A[0][2] = 4
A[1][0] = 4 A[1][1] = 3 A[1][2] = 4
A[2][0] = 3 A[2][1] = 2 A[2][2] = 4
A[3][0] = 2 A[3][1] = 2 A[3][2] = 2
A[4][0] = 3 A[4][1] = 3 A[4][2] = 4
A[5][0] = 1 A[5][1] = 4 A[5][2] = 4
A[6][0] = 4 A[6][1] = 1 A[6][2] = 1
매트릭스 A는 5가지 색으로 칠해진 맵으로 기술된다. 맵의 영역들은 7개의 다른 나라를 포함한다.
- A[0][0] 는 한 영역으로 구성된 하나의 나라를 형성한다.
- A[0][1], A[0][2], A[1][2], A[2][2]는 네 개의 영역으로 구성된 하나의 나라를 형성한다.
- A[1][0] 는 한 영역으로 구성된 하나의 나라를 형성한다.
- A[1][1] 는 한 영역으로 구성된 하나의 나라를 형성한다.
- A[2][0] 는 한 영역으로 구성된 하나의 나라를 형성한다.
- A[2][1], A[3][0], A[3][1], A[3][2] 는 네 개의 영역으로 구성된 하나의 나라를 형성한다.
- A[4][0], A[4][1] 는 두 개의 영역으로 구성된 하나의 나라를 형성한다.
- A[4][2], A[5][1], A[5][2] 는 세 개의 영역으로 구성된 하나의 나라를 형성한다.
- A[5][0] 는 한 영역으로 구성된 하나의 나라를 형성한다.
- A[6][0] 는 한 영역으로 구성된 하나의 나라를 형성한다.
- A[6][1], A[6][2] 는 두 개의 영역으로 구성된 하나의 나라를 형성한다.
함수를 작성해라.
def solution(A: Vector[Vector[Int]]): Int = {
 // TODO:
}
함수는 주어진 N열, M행의, 인덱스 0에서 시작하는 매트릭스 A에 대해서, 매트릭스 A에 의해 기술되는 맵의 영역들이 포함되는 나라의 수를 반환한다.
다음을 가정해라.
N은 범위 [1..300,000]의 정수이다.
M은 범위 [1..300,000]의 정수이다.
매트릭스 A의 요소 수는 범위 [1..300,000] 사이의 정수이다.
매트릭스 A의 각 요소의 값은 범위 [?1,000,000,000..1,000,000,000] 사이의 정수이다.
예를 들어, 위의 예에서, 7개의 열과 3개의 행으로 구성된 매트릭스 A에 대해서, 함수는 11을 반환해야만 한다.

 

풀이 )

    소요시간은 코딩시간 2시간, 고민시간 출퇴근 2시간 + 집에서 미드보면서 1시간...

    오래 걸리네...

 

Index = Row * ColCount + Col ;

격자의 Index로 루프를 돈다.

 

for{

1. Value = 0, Value와 현재 인덱스 값과 같은지 확인. 다르면 List에 등록 & 카운트

while(){

2. List에서 Index의 값 꺼내 Map의 현재 위치에서 좌, 우, 하 에 대한 Cell값 비교

3. 값이 같으면 List에 Index값 추가.

4. List의 다음 Index 값을 꺼내어 2번 ~ 3번 반복.

}

5. 같은 값이 없으면 리스트에 등록된 Index의 Cell 값에 * -1 적용.

6. 리스트 초기화

}

 

static void Main(string[] args)

    int[,] map = new int[,] {
        { 5, 4, 4},
        { 4, 3, 4},
        { 3, 2, 4},
        { 2, 2, 2},
        { 3, 3, 4},
        { 1, 4, 4},
        { 4, 1, 1},
    };
    int RowCount = map.GetUpperBound(0) + 1;
    int ColCount = map.GetUpperBound(1) + 1;
    int cnt = 0;
    int value = 0, row = 0, col = 0;
    int xMinus = 0, xPlus = 0, yPlus = 0;
    List<int> BufferIndex = new List<int>();

    bool IsFind = false;

    for (int idx = 0; idx < map.Length; idx++)
    {
        IsFind = false;
        value = 0;
        row = idx / ColCount; col = idx % ColCount;
        BufferIndex.Clear();
        if (value != map[row, col] && 0 < map[row, col])
        {
            value = map[row, col];
            BufferIndex.Add(idx); cnt++;
            IsFind = true;
        }

        while (IsFind)
        {
            if (value == 2)
            {
                int breakValue = 0;
            }
            IsFind = false;
            for (int i = 0; i < BufferIndex.Count; i++)
            {
                row = BufferIndex[i] / ColCount; col = BufferIndex[i] % ColCount;

                xMinus = col - 1;
                xPlus = col + 1;
                yPlus = row + 1;

                // -x;
                if (xMinus >= 0 &&

value == map[row, xMinus] &&

0 < map[row, xMinus] &&

!BufferIndex.Contains(row * ColCount + xMinus))
                {
                    BufferIndex.Add(row * ColCount + xMinus);
                    IsFind |= true;
                }
                // +x;
                if (xPlus < ColCount &&

value == map[row, xPlus] &&

0 < map[row, xPlus] &&

!BufferIndex.Contains(row * ColCount + xPlus))
                {
                    BufferIndex.Add(row * ColCount + xPlus);
                    IsFind |= true;
                }
                // +y;
                if (yPlus < RowCount &&

value == map[yPlus, col] &&

0 < map[yPlus, col] &&

!BufferIndex.Contains(yPlus * ColCount + col))
                {
                    BufferIndex.Add(yPlus * ColCount + col);
                    IsFind |= true;
                }
            }
        }

        for (int loop = 0; loop < BufferIndex.Count; loop++)
        {
            map[BufferIndex[loop]/ ColCount, BufferIndex[loop] % ColCount]*= -1;
        }
        Console.WriteLine("count=" + cnt);
        Print(map);
        Console.ReadLine();
        Console.Clear();
    }

    Console.WriteLine("count=" + cnt);
    Console.ReadLine();
}

static void Print(int[,] map)
{
    int RowCount = map.GetUpperBound(0) + 1;
    int ColCount = map.GetUpperBound(1) + 1;
    for (int r = 0; r < RowCount; r++)
    {
        Console.Write(r.ToString("D2")+"행 ");
        for (int c = 0; c < ColCount; c++)
        {
            Console.Write( map[r, c] + " ");
        }
        Console.WriteLine("");
    }
}

'# 1) 프로그래밍' 카테고리의 다른 글

한글분해_결합, 오토마타...  (0) 2014.01.30
달력 컨트롤] 새로 만든 달력!!!  (0) 2014.01.26
알고리즘] 1  (0) 2013.11.14
C#] 문자열 정렬처리...  (0) 2013.11.10
.net] 모니터링 프로그램...  (0) 2012.05.13

친구가 준 문제.. ( 회사 시험... )

 

다음 열의 정수 배열은 다음처럼, 현재 열의 각 정수와 그 정수가 연속적으로 나타나는 개수의 쌍으로 구성된다.
1
1 1 → 위의 열은, 1이 하나다.
1 2 → 위의 열은, 1이 두 개다.
1 1 2 1 → 위의 열은, 1이 하나, 2가 두 개다.
1 2 2 1 1 1 → 위의 열은, 1이 두 개, 2가 하나, 1이 하나다.
1 1 2 2 1 3 → 위의 열은, 1이 하나, 2가 두 개, 1이 세 개다.
1 2 2 2 1 1 3 1 → ...
1 1 2 3 1 2 3 1 1 1 → ...

0으로 시작하는 주어진 인덱스 M에 대해서,
M을 각 열의 인덱스라고 하자.
인덱스 M이 가리키는 열의 정수 배열은 무엇인가?

예를 들어,
만일 M=4 라면,
답은 "1 2 2 1 1 1"이다

 

 

C# 구현. ( 1시간 걸림. 삽질 30분후에 뭔가 안맞는것 같아 고민 하던 중에... )

 

            List<int> result = new List<int>();
            int[] prms = new int[] { 1 };
            int x = 0;
            int M = 5;
            for (int loop = 0; loop < M; loop++)
            {
                x = 0;
                for (int idx = 0; idx < prms.Length; idx++)
                {
                    if (x != prms[idx])
                    {
                        result.Add(prms[idx]);
                        result.Add(1);
                        x = prms[idx];
                    }
                    else
                        result[result.Count - 1]++;
                }

                textBox1.AppendText("" + loop + "] " + string.Join(" ", prms) + Environment.NewLine);

                prms = result.ToArray();
                result.Clear(); 
            }

 

'# 1) 프로그래밍' 카테고리의 다른 글

달력 컨트롤] 새로 만든 달력!!!  (0) 2014.01.26
알고리즘] 2  (0) 2013.11.15
C#] 문자열 정렬처리...  (0) 2013.11.10
.net] 모니터링 프로그램...  (0) 2012.05.13
.NET] 트리 뷰_ 체크박스 - 더블클릭  (0) 2012.04.09

 

 훈스 닷넷에 문의 글이 하나 올라왔다.

 

 "994.jpg", "995.jpg", "995-1.jpg", "995-2.jpg", "996.jpg", "997.jpg", "998.jpg", "998-1.jpg", "999.jpg", "1000.jpg", "1000-1.jpg",

 

정렬해야 되는데 '-' 들어간 것때문에 정렬이 이상하게 된다고...

 

Array.Sort를 이용하였다는 글이었다.

 

http://www.hoons.net/Board/qacshap/Content/60271

 

그래서 우선 간단하게 만들어본다고 시작하게 되었는데...

 

우선 첫번째 실수는 정렬에 대한 내용 이해를 잘못했다

 

994, 995, 1000, 995-1, 1000-1 형태로 정렬을 해야되는건가? 하고 코드를 시작했다.

 

답글을 보니 Lookw님은 처음 나열된 순서대로 나오도록 작성을 해 올리셨더라.

 

List<string> ls = new List<string>
{
    "1000-100","1000-99","998-1","999","999-0", "994","995","995-1",
    "999-1","1000","995-2","996","997","998"
};
var ls2 = ls.Select(x =>
{
    var subs = x.Split('-');
    if (subs.Length > 1)
        return new {Original=x, First = subs[0], Last = subs[1] };
    else
        return new {Original=x, First = subs[0], Last=string.Empty};
})
.OrderBy(x => int.Parse(x.First))
.ThenBy(x =>
{
if (x.Last != string.Empty)
    return int.Parse(x.Last);
else
    return 0;
})
.Select(x => x.Original);

 

그래서 나도 정렬 순서를 바꾸려고 코드를 수정했는데 1시간동안 수정했다.

string[] arr = new string[] {
                "994","995","995-1","995-2","996","997","998",
                "998-1","999","1000","1000-100","1000-99",
 //"994.jpg",
 //"995.jpg",
 //"995-1.jpg",
 //"995-2.jpg",
 //"996.jpg",
 //"997.jpg",
 //"998.jpg",
 //"998-1.jpg",
 //"999.jpg",
 //"1000.jpg",
 //"1000-1.jpg",
};

            int maxLenght = arr.Max(s => s.Replace(".jpg", "").Length);
            int hipen = 4;
            Func<string, string[]> Process = (s) =>
            {
                string[] NameExtensArray = s.Split(new char[] { '.' });
                string[] NameHipenArray = NameExtensArray[0].Split(new char[] { '-' });
                if (NameHipenArray.Length == 1)
                {
                    NameHipenArray = new string[] { NameHipenArray[0], "" };
                }
                return new string[] { NameHipenArray[0].PadLeft(maxLenght, '0'), NameHipenArray[1].PadLeft(hipen, '0').PadRight(hipen, '0'), NameExtensArray[NameExtensArray.LongLength - 1] };
            };

            Comparison<string> compare = (s1, s2) =>
            {
                string[] cv1 = Process(s1);
                string[] cv2 = Process(s2);
                return (cv1[0] + cv1[1]).CompareTo(cv2[0] + cv2[1]);
            };
            Array.Sort(arr, compare);

 

이렇게 작성해두고 잠깐 있으니 String.Format이 떠올랐다.

 

string k1 = string.Format("{0, 8}",  "995").Replace(" ","0");
string k2 = string.Format("{0, 8}", "1000").Replace(" ", "0");

요건 {0, 8} 같은 경우 8자리에 오른쪽 정렬, {0, -8}은 왼쪽 정렬

 

이걸로 다시... 코드를 작성!

 

 string[] arr2 = new string[] { 
         //"994","995","995-1","995-2","996","997","998",
         //"998-1","999","1000","1000-100","1000-99",
         "994.jpg",  "995.jpg",  "995-1.jpg",  "995-2.jpg",  "996.jpg",  "997.jpg",
         "998.jpg",  "998-1.jpg",  "999.jpg",  "1000.jpg",  "1000-1.jpg",

   };

         int maxLenght2 = arr2.Max(s => s.Replace(".jpg", "").Length);
         var result = from o in (arr2.Select(ars =>
         {
               string[] strings = ars.Replace(".jpg", "").Split('-');
               string opt = "0000";
               if (strings.Length > 1)
               {
                        opt = strings[1].Split('.')[0];
                }
                return new {

 key = ars,

             value = string.Format("{0," + maxLenght2 + " }",

            strings[0].Split('-')[0]).Replace(" ", "0")  +

           string.Format("{0, 4}", opt).Replace(" ", "0")

    }

   }))

         orderby o.value
         select o.key;

 

이게 뭐라고 금욜저녁에 필 꽃혀서리...

 

 

 

 

 

 

 

 

 

 

'# 1) 프로그래밍' 카테고리의 다른 글

알고리즘] 2  (0) 2013.11.15
알고리즘] 1  (0) 2013.11.14
.net] 모니터링 프로그램...  (0) 2012.05.13
.NET] 트리 뷰_ 체크박스 - 더블클릭  (0) 2012.04.09
.net ] 한글 유니코드 변환  (0) 2012.04.07