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]

... 16  17  18  19  20  21  [22]  23  24  25  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
5376영귤9/1/20206956nullable 타입간의 비교연산은 그냥 가능한 건가요? [1]
5375영귤8/30/20208456이벤트와 델리게이트의 차이가 궁금합니다. [2]
5374guest8/27/20209535시작하세요! C# 8.0 프로그래밍 책에 오타가 있습니다. [1]
5373agj8/26/20207757System.Single::ToString()함수의 IL코드를 보았는데 ldnull, throw가 전부입니다. 왜 이렇게 짧죠? [2]
5372민성8/24/20207749안녕하세요 WPF 웹브라우저 컨트롤에서 웹브라우저 자체를 엣지로 할 수가 있나요? [2]
5371서현준8/11/20206825Hyper-V 내부 네트워크 환경 중, VM 에서 인터넷 접속 [1]
5370독자8/11/20205843.net createobject 관련 질문입니다.. [4]
5369독자8/10/20206188c# 8.0 프로그래밍 책에 대한 질문 드립니다 [1]
5368guest8/10/20207473시작하세요! C# 8.0 프로그래밍 책에 오타가 있습니다. [1]
5367박순기8/8/20206371디버깅 시 반전되는 부분 글 색상이나 배경색을 변경하는 방법 [3]파일 다운로드1
5366간절함8/7/20207063하나의 솔루션에서, 32비트 프로젝트에서 다른 64비트 프로젝트 참조하는 방법 궁금합니다. [4]
5365영귤8/6/20206322TimeSpan 구할 때 시간대를 바꿔도 같은 값이 나오는 것 같습니다. [1]
5364박순기8/5/20206377visual studio의 menu bar font size 변경방법 문의 [2]파일 다운로드1
5363클락8/1/20206975c# 9.0 출간 준비 중이신가요? [2]
5361하태7/29/20206602안녕하세요! 바이너리데이터 파싱 질문 드리겠습니다!. [2]
5360진우7/28/20207507엑셀에서 발생하는 모든 이벤트를 감지 할수 있는지 궁금합니다. [6]파일 다운로드1
5358홍길동7/22/20206258개체에서 open 속성이나 매서드가 지원 되지 않읍니다.라고 오류창이 뜨는데. [1]
5357손동섭7/22/20206332책 예제코드... [3]
5355neska7/21/20206707안녕하세요 문의 드립니다 [1]
5354민성7/15/20208174안녕하세요 db연결 문자 보안 [2]
5353형성재7/14/20207236Visual Studio Setup Project에서 VC++2010재배포패키지설치 [4]
5352윤식7/10/20207203닷넷코어 빌드 시 runtimeconfig 파일을 없앨 수 있는지.. [4]
5351runr...7/2/20207079C# 에서 C++ dll 병렬 사용 [1]
5350홍성호6/29/20208692C++에서 정의된 구조체(공유메모리)를 C#으로 공유메모리에서 구조체 변환시 에러가 발생 합니다. [1]파일 다운로드1
5349jero...6/24/20206212logon credential provider 관련 문의드립니다. [1]
5348776/19/20205974시작하세요 C# 8.0프로그래밍 책에 대한 질문입니다. [8]
... 16  17  18  19  20  21  [22]  23  24  25  26  27  28  29  30  ...