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)
1151황기동6/5/201311331무선 패킷 전송관련 질문 [1]
1147이진권6/2/201311356c# 윈폼 facebook과 연동2 [1]
1144황은영5/29/201315849원격지 서버에서 COM+ 호출이 되지 않습니다. [7]
1143김선희5/28/201316765윈도우 8, 익스플로러 10, 64bit->32bit [1]
1142백지훈5/15/201311194음성인식 TTS 관련해서 질문드립니다 ㅜㅜ [2]파일 다운로드1
1141나그네5/10/201311275안녕하세요..전자세금 관련하여.. 보다보다 여기까지 왔습니다. [4]
1140이성환5/8/201311473제네릭과 배열 관련 기초 질문입니다. [11]
1139양영석5/3/201310036페이스북 로그인 관련하여.... [1]
1137김민현4/30/201310081Binary 구조체에 대한 Linq query 관련 질문입니다. [3]파일 다운로드1
1136박상영4/25/201310959ksc5601에서 지원하지않는 확장문자 찾는방법 [3]
1135sequ...4/16/201326526c# dll c++ 에서 사용하기 (event 사용) [17]
1134이성환4/12/201310722volatile 키워드 관련 질문입니다. [3]파일 다운로드1
1133서광석4/8/201313935vb.net 2010에서 배포시 문제점 확인 방법에 대한 질문드립니다 [1]
1131헤딩3/28/201316213IIS 처리 성능을 높이고 싶으면 풀의 proecss 수를 계속 늘리면 될까요? [1]
1130박재율3/27/201310491WCF 서비스가 종종 죽는데 도움좀 부탁드립니다 ㅠ [1]
1129이상민3/21/201314873안녕하세요...IE Embedded Smart Client가 Windows8에서 정상동작을 하지 않습니다. [8]
1125박홍균3/19/20139035안녕하십니까. visual studio 에서 TFS 접속 관련으로 궁금한 점 여쭤봅니다.
1124궁금이3/18/201312092IIS 서버 이중화 구성시 데이터 베이스 트랜잭션 관리에 관해서... [1]
1127궁금이3/19/20139498    답변글 [답변]: IIS 서버 이중화 구성시 데이터 베이스 트랜잭션 관리에 관해서...(정성태님 봐주세요)
1122김시현3/11/201310919 Xamarin 에 관련하여 질문드립니다. [4]
1121롬메달2/14/201311014Assembly.Load로 얻은 객체안에서 제3의 어셈블리를 참조할때의 문제입니다. [8]
1120Lyn2/12/201310535안녕하세요. 블로그에 기술관련글을 꾸준히 포스팅 하실 수 있는 원동력이 궁금합니다. [1]
1119박진영2/4/201334031닷넷 DLL 실행 에러 (보호된 메모리를 읽거나 쓰려고 했습니다..) [2]파일 다운로드1
1118C#조으다1/29/201312090공유기 관리 페이지에 접근시 윈도우 인증창이 뜹니다. [4]
1117최윤호1/28/20139867답변주셔서 감사합니다 질문의 요지는 그게 아니고 [1]파일 다운로드1
1116C#조으다1/27/201317085비프음을 컴퓨터 내장 스피커로 출력하려면.. [2]
... 46  47  48  49  50  51  52  53  54  55  56  57  58  [59]  60  ...