Microsoft MVP성태의 닷넷 이야기
글쓴 사람
spowner (spowner at naver.com)
홈페이지
첨부 파일
 

문제 : 특정 범위의 값을 다른 값으로 치환하는 행위를 빠르게 처리 하여야 한다
전제 : 값형은 double, 값의 범위에 대한 목록 동적으로 많이 등록할 수 있음
설명 :

가령, 0 ~ 1000 범위의 값일 경우, 입력 값이 1000일 경우 출력값은 980이 됩니다. 즉, 0 ~ 1000 범위 안의 값일 경우 율이 980 / 1000 이므로 입력값에 0.98을 곱하는 식입니다
그런데 이 범위 레인지는 특정하지 않고 리스트로 무한대 등록이 가능하다고 가정합니다.
즉,

0 ~ 1000 => 980, out = input * 0.98
1001 ~ 2000 => 1900, out = input * xx
2001 ~ 4000 => 3800, out =...
4001 ~ 8000 => 7600,
8001 ~ 10000 => 9400,
...

단순무식한 방법으로는 범위 시작과, 범위 종료를 리스트로 관리하고, 앞으로 검색, 뒤로 검색하여 범위를 찾고 율을 계산해서 사용하는 것인데,
이 방식은 쉽지만 호출횟수가 많으면 많을수록 (가령, 1ms 간격으로) 굉장한 성능하락이 예상되는데요,

좀 더 효율적인 방법이 무엇이 있을까요??








[최초 등록일: ]
[최종 수정일: 2/6/2017]


비밀번호

댓글 작성자
 



2017-02-06 01시01분
음... 문제를 좀 더 설명해 주셔야 할 것 같습니다. 잘 이해가 안되는 군요. ^^; 그러니까, 리스트에 0,1,2,...,1000의 값이 들어 있는데 입력 값이 1,000이면 980을 출력한다는 건가요? 아니면, 리스트 중간에 값이 비어 있을 수 있다는 건가요?
정성태
2017-02-07 03시25분
[spowner] 죄송합니다. 일하면서 쓰느라.. (라고 변명하면서 글을 잘 못씁니다)
중간 비어있는 것 맞고요, 제가 고민하는 것은 (min, max)=rate 로 이루어진 아이템이 있고 이 아이템이 복수개일 때, 특정 값을 입력하면 min >= value && max < value 인 rate를 찾아서 output에 value*rate(또는 rate)를 반환해야 합니다
제가 선택한 방법은 목록에 min과 max를 찾아 거기에 부여된 rate를 잡아내는 건데, 목록 전체 검사를 해야 합니다. Dictionary의 경우 일대일 매칭인 반면, 제가 원하는 것은 범위 매칭인 샘이죠

[guest]
2017-02-07 03시36분
[spowner] 범위는 중첩될 수는 있으나, 문제를 쉽게 해결하기 위해 중첩은 배제하는 것으로 합니다... 답을 주세요~ 라고 강요하는 것은 아닙니다 T_T 다른 아이디어가 궁금해요
[guest]
2017-02-07 04시06분
[ryujh] 안녕하세요.

아래는 메모를 붙인 것이니 확인 바랍니다.

원래 제공하는 것(문법, 라이브러리 등)을 있는 그대로 활용하는 것이 가장 좋다는 생각입니다.

----------
min 의 sortedlist key (0, 1001, 2001, 4001, ... ) value (0.98, xx, ...)
max 의 sortedlist key (1000, 2000, 4000, 8000, ... ) value (0.98, xx, ...)

input(100) 를 min 에 add key 하면 (0, 100, 1001) 이고 input보다 작은 key의 value 를 구하여 0.98 input과 곱한다.
input(100) 를 max 에 add key 하면 (100, 1000) 이고 input보다 큰 key의 value 를 구하여 0.98 input과 곱한다.

동적으로 등록하기 때문에 sortedlist(sorteddictionary) 로 정렬하는 방법 이외에 있을지 모르겠음.

if/else, switch 문으로는 되지 않을 것임.
---------




[guest]
2017-02-07 07시05분
[spowner] @ryujh님 감사합니다. 님 덕분에 아이디어가 떠올랐어요. 제가 알기로 참조형 인스턴스의 Directory류 탐색의 키는 HashCode를 재정의 함으로서 가공할 수 있는것으로 아는데, 아이템의 HashCode를 min+max로 고유하게 만든 다음, 입력값으로 해당 것을 찾도록 하면 되겠네요... 머리속으로는 정리됐는데, 구현해봐야겠습니다
[guest]
2017-02-07 07시09분
[spowner] 아아.. 생각처럼 안되는군요 T_T
[guest]
2017-02-07 08시21분
[spowner] 이렇게 해결했습니다. 생각을 해보면 답은 가까운데 있는데, 어렵게 생각했네요.. 참고하시라고 소스코드 공개합니다

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

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

namespace ConsoleApp8
{
    class Program
    {
        static void Main(string[] args)
        {
            // 등록된 범위는 중복되지 않다고 가정
            var list = new List<Item>
            {
                new Item { Min = 0, Max = 1000, Rate = 0.9d },
                new Item { Min = 1001, Max = 2000, Rate = 1.1d },
                new Item { Min = 2001, Max = 3000, Rate = 1.2d },
                new Item { Min = 3001, Max = 4000, Rate = 1.2d },
                new Item { Min = 4001, Max = 5000, Rate = 1.0d }
            };

            // 목록은 항상 정렬되었다고 가정
            list.Sort((x, y) =>
            {
                return x.Max.CompareTo(y.Min);
            });

            // 목록 출력
            foreach (var i in list)
            {
                Console.WriteLine(i);
            }

            Console.WriteLine();

            // 정렬되어 있으므로 이진검색 가능
            var value = 4500;
            var item = new Item(value);
            var index = list.BinarySearch(item, item);

            var rate = list[index].Rate;

            Console.WriteLine($"{value} => {rate}");
        }
    }

    public class Item : IComparer<Item>
    {
        public double Min { get; set; }
        public double Max { get; set; }
        public double Rate { get; set; }

        public Item()
        {
        }

        public Item(double value)
        {
            Max = value;
        }

        public override string ToString()
        {
            return $"{Min} ~ {Max} : {Rate}";
        }

        public int Compare(Item x, Item y)
        {
            var value = y.Max;

            if (value >= x.Min && value <= x.Max)
                return 0;
            else if (value < x.Min)
                return 1;
            else // else if (x.Max > value)
                return -1;
        }
    }
}

[guest]

... 46  47  48  49  50  [51]  52  53  54  55  56  57  58  59  60  ...
NoWriterDateCnt.TitleFile(s)
1556김응규4/22/201512208    답변글 [답변]: WCF net.tcp 관련해서 질문 드립니다. [1]파일 다운로드1
1554(삭제)4/19/201512975안드로이드 에뮬레이터에서 특정 앱 구동불가할때! [2]
1552spow...4/18/201518894마이크로세컨드 단위의 Sleep이 필요한데 찾질 못하겠습니다. [5]
1553spow...4/18/201512164    답변글 [답변]: 마이크로세컨드 단위의 Sleep이 필요한데 찾질 못하겠습니다. [1]
1551인디언기...4/16/201511559iisnode에 대해서 글 올리셨던데 질문이 있습니다 [1]
1549김선아4/15/201512023.net framework 4.5와 c++ dll에 관한 질문입니다 [1]
1550김선아4/15/201510438    답변글 [답변]: .net framework 4.5와 c++ dll에 관한 질문입니다 [2]
1547문명식4/3/201512454IWebBrowser Key Event 관련 [2]
1545나종식3/25/201511426internet explorer dns cache flush [2]
1543이용원3/23/201511414hyper-v 질문드려요! [1]
1544이용원3/24/201510549    답변글 한가지만 더 여쭤볼게요! [1]
1541임기성3/20/201517775Microsoft.Office.Core dll관련 문제 [1]
1539펜플3/17/201511105asp.net 질문입니다. [1]
1540113/17/201511100    답변글 [답변]: asp.net 질문입니다. [1]
1538열공합시닷3/13/201511881중계서버 질문드립니다 [1]
1537김재영3/11/201512949asp.net의 빌드 유휴시간 이후의 리빌드 작업을 컨트롤 할 수 있습니까? [2]
1536솔솔3/9/201511387mac address얻으려고 하는데요.. [1]
1535Stud...3/4/201511946C#엔 MFC의 theApp 과 같은 기능을 하는것이 없나요? [3]
1534김동진3/4/201511387C#에서 BHO로 Windows Explorer에서의 동작이 가능할지요 [2]
1533김동현3/3/201511648컴파일 된 프로그램에 코드 삽입(?) 관련입니다. [1]
1532반가워요3/3/201514252C# 소켓연결에 packet송수신... [8]
1531강현수3/2/201512885C# com 등록 시 GUID 변경 관련 문의 [1]
1529김민규2/15/201512767C++ 64bit/32bit [3]파일 다운로드1
1528김개똥2/14/201510261좀 관련없는 질문이지만, 정말 답답하고 찾는데 명확한 해답 찾지못해 질문 올립니다. <Windows 사용자 인증> [1]
1527방문자1/27/201511310System Timer의 Tick에서 Backgroundworker를 호출하면 스레드 문제가 있을까요? [1]
1526황상대1/26/201513127C# 마샬링 관련 질문이 있습니다. [1]
... 46  47  48  49  50  [51]  52  53  54  55  56  57  58  59  60  ...