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 간격으로) 굉장한 성능하락이 예상되는데요,

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




donaricano-btn



[최초 등록일: ]
[최종 수정일: 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의 경우 일대일 매칭인 반면, 제가 원하는 것은 범위 매칭인 샘이죠

[손님]
2017-02-07 03시36분
[spowner] 범위는 중첩될 수는 있으나, 문제를 쉽게 해결하기 위해 중첩은 배제하는 것으로 합니다... 답을 주세요~ 라고 강요하는 것은 아닙니다 T_T 다른 아이디어가 궁금해요
[손님]
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 문으로는 되지 않을 것임.
---------




[손님]
2017-02-07 07시05분
[spowner] @ryujh님 감사합니다. 님 덕분에 아이디어가 떠올랐어요. 제가 알기로 참조형 인스턴스의 Directory류 탐색의 키는 HashCode를 재정의 함으로서 가공할 수 있는것으로 아는데, 아이템의 HashCode를 min+max로 고유하게 만든 다음, 입력값으로 해당 것을 찾도록 하면 되겠네요... 머리속으로는 정리됐는데, 구현해봐야겠습니다
[손님]
2017-02-07 07시09분
[spowner] 아아.. 생각처럼 안되는군요 T_T
[손님]
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;
        }
    }
}

[손님]

... 16  17  18  19  20  21  22  23  24  25  26  27  [28]  29  30  ...
NoWriterDateCnt.TitleFile(s)
4815김지용3/14/20174571.net core linux 오류 [2]
4814김솔지3/13/20175681인쇄 시 , 출력화면을 이미지 파일로 저장하고 싶습니다. [1]파일 다운로드1
4813spowner3/8/20176841멀티 스레드 환경에서 처리하여야 할 목록을 효율적으로 사용하는 기법 질문 드립니다 [2]
4812popo2/23/20176567.NET Window ClassName 변경 질문 드립니다. [1]
4809힘찬도약2/15/20178756C# 가상 시리얼 [4]
4808이길용2/9/20178152WCF 외부 접속 관련해서 질문드립니다ㅠ [1]
4807헬조선식스웨그2/8/201713844WPF의 속도에 대해서 궁금합니다. [3]
4803헬조선식스웨그2/7/20178385WPF로 메신져 메세지 박스 구현 문의 [2]
4802spowner2/6/20175884특정 범위의 값을 다른 값으로 치환하는 메소드를 만들어야 할 때 가장 빠른 방법은? [7]
4804spowner2/7/20175941    답변글 [답변]: 특정 범위의 값을 다른 값으로 치환하는 메소드를 만들어야 할 때 가장 빠른 방법은?
4805spowner2/7/20175579    답변글 [답변]: 특정 범위의 값을 다른 값으로 치환하는 메소드를 만들어야 할 때 가장 빠른 방법은? (글삭제가 안돼 재첨부합니다)파일 다운로드1
4801spowner2/3/20175797C#의 참조 동작관련하여 아이디어 문의 드립니다 [4]
4800오세운2/1/20178876C# 에서 C++ DLL임포트 질문입니다. [2]
4798손님1/29/20176668picturebox의 image.dispose [1]
4797김철환1/13/20176972책에 관한 질문입니다 [3]
4796Beren Ko1/13/20176479++ 후위연산자와 = 을 함께 사용할 때 생성되는 IL 코드 관련... [2]
4795김철환1/11/20177925이벤트 부분을 읽고 있는데 이해가 안되서 질문합니다.. [11]
4794김철환1/10/20175536안녕하세요 c# 6.0 책을 구매한 사람인데요 [3]
4793장준영1/7/20177271안녕하세요 c언어 처음 공부해보는 학생입니다 [4]파일 다운로드1
4792김재영1/4/20177087소스코드 공개 전 성태님의 의견을 듣고싶습니다 [3]
4791C#초보12/28/20167316비동기 소켓 close시 ObjectDisposedException 문제점 질문 있습니다.. [1]
4790미나리12/24/20167501파워포인트 쇼 제어 SimpleHttpServer.cs 작동문제 [4]파일 다운로드1
4789김솔지12/21/20167384프린트 시, 프린트하는 파일의 파일명 구하는 부분에 대해서 질문드립니다. [1]
4788짜두12/19/20166676Visual Studio 2015 에서 msbuild 12 사용 [5]
4787손님12/18/20167907VLC라이브러리에 대해 아시나요? [3]파일 다운로드1
4785Hyoungki Kim12/16/20168387WPF 개발 시 MVVM 프레임워크 사용 [2]
... 16  17  18  19  20  21  22  23  24  25  26  27  [28]  29  30  ...