성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Roll A Lisp In C - Reading ; https...
[정성태] Java - How to use the Foreign Funct...
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - 조합(Combination) 예제 코드</h1> <p> 조합 코드가 간혹 쓰이는 경우가 있는데, 거의 템플릿에 가깝게 쓸 수 있어서 그냥 다음의 소스 코드를 그대로 가져다 써도 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Generating the mth Lexicographical Element of a Mathematical Combination ; https://msdn.microsoft.com/en-us/library/aa289166(v=vs.71).aspx Using Combinations to Improve Your Software Test Case Generation ; <a target='tab' href='https://docs.microsoft.com/en-us/archive/msdn-magazine/2004/july/using-combinations-to-improve-your-software-test-case-generation'>https://docs.microsoft.com/en-us/archive/msdn-magazine/2004/july/using-combinations-to-improve-your-software-test-case-generation</a> </pre> <br /> <pre style='height: 400px; margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; using System.Text; namespace ConsoleApplication1 { class Combination { private long n = 0; private long k = 0; private long[] data = null; public Combination(long n, long k) { if (n < 0 || k < 0) { throw new Exception("Negative parameter in constructor"); } this.n = n; this.k = k; this.data = new long[k]; for (long i = 0; i < k; ++i) { this.data[i] = i; } } public Combination Successor() { if (this.data.Length == 0 || this.data[0] == this.n - this.k) { return null; } Combination answer = new Combination(this.n, this.k); long i; for (i = 0; i < this.k; ++i) { answer.data[i] = this.data[i]; } for (i = this.k - 1; i > 0 && answer.data[i] == this.n - this.k + i; --i) ; ++answer.data[i]; for (long j = i; j < this.k - 1; ++j) { answer.data[j + 1] = answer.data[j] + 1; } return answer; } public string[] ApplyTo(string[] strarr) { if (strarr.Length != this.n) { throw new Exception("Bad array size"); } string[] result = new string[this.k]; for (long i = 0; i < result.Length; ++i) { result[i] = strarr[this.data[i]]; } return result; } public static long Choose(long n, long k) { if (n < 0 || k < 0) { throw new Exception("Invalid negative parameter in Choose()"); } if (n < k) { return 0; } if (n == k) { return 1; } long delta, iMax; if (k < n - k) { delta = n - k; iMax = k; } else { delta = k; iMax = n - k; } long answer = delta + 1; for (long i = 2; i <= iMax; ++i) { checked { answer = (answer * (delta + i)) / i; } } return answer; } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("{ "); for (long i = 0; i < this.k; ++i) { sb.AppendFormat("{0} ", this.data[i]); } sb.Append("}"); return sb.ToString(); } } } </pre> <br /> 위의 Combination 타입은 항목들의 순서를 직접 바꾸는 방식이 아닌, 항목들의 배열 인덱스 숫자를 바꾸는 방식으로 동작합니다. 예를 들어, 위의 코드를 5개의 항목 중에 3개를 뽑는 인덱스 조합을 다음과 같이 출력해 볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Combination c = new Combination(5, 3); while (c != null) { Console.WriteLine(c.ToString()); c = c.Successor(); } </pre> <br /> 출력 결과는 이렇게 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > { 0 1 2 } { 0 1 3 } { 0 1 4 } { 0 2 3 } { 0 2 4 } { 0 3 4 } { 1 2 3 } { 1 2 4 } { 1 3 4 } { 2 3 4 } </pre> <br /> 출력된 숫자의 범위는 0 ~ 4이므로, 그냥 이것을 조합으로 보여주고 싶은 배열의 인덱스로 사용해도 됩니다.<br /> <br /> 따라서, 다음과 같은 배열이 있다고 가정할 때,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > { "ant", "bug", "cat", "dog", "elk" } </pre> <br /> 이 중에서 3개의 항목을 뽑는 모든 조합을 다음과 같이 구할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string[] items = new string[] { "ant", "bug", "cat", "dog", "elk" }; Combination c = new Combination(items.Length, 3); // 5개 중에 3개를 취하는 조합 string[] snapshot = null; while (c != null) { snapshot = c.ApplyTo(items); DisplayItems(snapshot); // 배열의 내용을 출력하는 메서드 c = c.Successor(); } </pre> <br /> 출력 결과는 우리가 원하는 조합을 보여줍니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > { ant, bug, cat } { ant, bug, dog } { ant, bug, elk } { ant, cat, dog } { ant, cat, elk } { ant, dog, elk } { bug, cat, dog } { bug, cat, elk } { bug, dog, elk } { cat, dog, elk } </pre> <br /> 참고로, 단순히 총 조합의 수만 알고 싶다면 Choose 정적 메서드를 호출해 주면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Console.WriteLine("# of combination: " + Combination.Choose(5, 3)); // 출력 결과: 10 </pre> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1020&boardid=331301885'>첨부한 파일은 이 글의 코드를 포함</a>합니다.)<br /> <br /> <script type="math/tex"> \begin{pmatrix}n \\ k \end{pmatrix} = \frac{n!}{k!(n-k)!} = \begin{cases} \begin{pmatrix}n - 1 \\ k - 1 \end{pmatrix} + \begin{pmatrix}n - 1 \\ k \end{pmatrix} &\mbox { if } 0 < k < n \\ 1 &\mbox { if } \: k = 0 \: or \: k = n \end{cases} </script> <br /> <hr style='width: 50%' /><br /> <br /> 조합도 다양하게 응용이 가능한데요. 가령 '중복 가능한 조합'이 필요하다면 다음의 코드를 가져다 쓰시면 됩니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 방탈출3 - Room 10의 '중복가능한 조합' 문제를 위한 C# 프로그래밍 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1102'>http://www.sysnet.pe.kr/2/0/1102</a> </pre> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
7582
(왼쪽의 숫자를 입력해야 합니다.)