এন থেকে কে উপাদানগুলির সমস্ত সংমিশ্রণ ফিরিয়ে আনতে অ্যালগরিদম


571

আমি একটি ফাংশন লিখতে চাই যা একটি আর্গুমেন্ট হিসাবে অক্ষরের অ্যারে নেয় এবং সেই অক্ষরের একটি সংখ্যা নির্বাচন করে।

বলুন আপনি 8 টি বর্ণের একটি অ্যারে সরবরাহ করেন এবং সে থেকে 3 টি বর্ণ নির্বাচন করতে চান। তারপরে আপনার পাওয়া উচিত:

8! / ((8 - 3)! * 3!) = 56

বিনিময়ে অ্যারে (বা শব্দ) প্রতিটি 3 টি চিঠি নিয়ে।


2
প্রোগ্রামিং ভাষার কোন পছন্দ?
জোনাথন ট্রান

7
সদৃশ অক্ষরগুলি কীভাবে মোকাবেলা করতে চান?
ডাব্লুসিএম

ভাষার কোনও পছন্দ নয়, আমি এটি রুবিতে কোড দিচ্ছি তবে কী অ্যালগরিদম ব্যবহার করা উচিত তা সম্পর্কে সাধারণ ধারণা ভাল। একই মূল্যের দুটি অক্ষর উপস্থিত থাকতে পারে তবে একই অক্ষরটি দু'বার নয়।
ফ্রেডরিক


পিএইচপি-তে, নিম্নলিখিতটি করা উচিত: স্ট্যাকওভারফ্লো
কমল দাğ

উত্তর:


412

আর্ট অফ কম্পিউটার প্রোগ্রামিং ভলিউম 4: ফ্যাসিক্যাল 3 এ এর একটি টন রয়েছে যা আমি আপনার বর্ণনা থেকে কীভাবে আপনার নির্দিষ্ট পরিস্থিতির সাথে ফিট করতে পারি।

গ্রে কোডস

আপনি যে বিষয়টি নিয়ে আসবেন তা অবশ্যই মেমোরি এবং বেশ দ্রুত, আপনার সেটে 20 টি উপাদান দ্বারা সমস্যা হবে - 20 সি 3 = 1140 And এবং আপনি যদি সেটটি দিয়ে পুনরাবৃত্তি করতে চান তবে পরিবর্তিত ধূসর ব্যবহার করা ভাল if কোড অ্যালগরিদম যাতে আপনি তাদের সমস্তকে মেমোরিতে রাখছেন না। এগুলি পূর্বের থেকে পরবর্তী সংমিশ্রণ উত্পন্ন করে এবং পুনরাবৃত্তিগুলি এড়ায়। বিভিন্ন ব্যবহারের জন্য এর অনেকগুলি রয়েছে। আমরা কি ধারাবাহিক সংমিশ্রণের মধ্যে পার্থক্য সর্বাধিকতর করতে চাই? কমান? ইত্যাদি।

ধূসর কোডগুলি বর্ণনা করে এমন কিছু মূল কাগজ:

  1. কিছু হ্যামিল্টন পাথ এবং একটি ন্যূনতম পরিবর্তন অ্যালগরিদম
  2. সংলগ্ন ইন্টারচেঞ্জ সমন্বয় জেনারেশন অ্যালগরিদম

এখানে বিষয়টিকে আচ্ছাদিত আরও কিছু কাগজপত্র দেওয়া হল:

  1. Eades, হিকি এর একটি দক্ষ বাস্তবায়ন পড়ুন সংলগ্ন ইন্টারচেঞ্জ সমাবেশ জেনারেশন অ্যালগরিদম (পিডিএফ, পাসকাল কোড সহ)
  2. সংমিশ্রণ জেনারেটর
  3. সম্মিলিত গ্রে কোডগুলির সমীক্ষা (পোস্টস্ক্রিপ্ট)
  4. গ্রে কোডগুলির জন্য একটি অ্যালগরিদম

চেজের ট্যুইডল (অ্যালগোরিদম)

ফিলিপ জে চেজ, ` অ্যালগরিদম 382: এন অবজেক্টস এম এর মিশ্রণ '(1970)

সি এর অ্যালগরিদম ...

ডিক্সোগ্রাফিকাল অর্ডারের সংমিশ্রনের সূচক (বাকলস অ্যালগরিদম ৫১৫)

আপনি এর সূচী দ্বারা কোনও সংমিশ্রণটিও উল্লেখ করতে পারেন (অভিধানে ক্রমানুসারে)। সূচকের উপর নির্ভর করে সূচকটি ডান থেকে বামে কিছু পরিমাণ পরিবর্তন হওয়া উচিত যা আমরা এমন কিছু নির্মাণ করতে পারি যা একটি সংমিশ্রণ পুনরুদ্ধার করতে পারে।

সুতরাং, আমাদের একটি সেট আছে 2 1,2,3,4,5,6। ... এবং আমরা তিনটি উপাদান চাই। আসুন say 1,2,3 say বলি আমরা বলতে পারি যে উপাদানগুলির মধ্যে পার্থক্যটি একটি এবং ক্রম এবং ন্যূনতম। 2 1,2,4} এর একটি পরিবর্তন রয়েছে এবং এটি ডিক্সিকোগ্রাফিকভাবে 2 নম্বরে রয়েছে place সুতরাং শেষের স্থানে 'পরিবর্তন' সংখ্যাটি অভিধানিক ক্রমটির পরিবর্তনের জন্য দায়ী। এক পরিবর্তনের সাথে দ্বিতীয় স্থান {1,3,4 one এর একটি পরিবর্তন রয়েছে তবে এটি দ্বিতীয় স্থানে থাকার কারণে এটি আরও পরিবর্তনের জন্য অ্যাকাউন্ট রয়েছে (মূল সংখ্যার উপাদানগুলির সংখ্যার সাথে সমানুপাতিক)।

আমি যে পদ্ধতিটি বর্ণনা করেছি তা হ'ল ডিকনস্ট্রাকশন, যেমনটি মনে হয়, সূচি থেকে সেট থেকে শুরু করে আমাদের বিপরীতটি করা দরকার - যা অনেকটাই জটিল is এই হল কিভাবে Buckles সমস্যা solves। আমি সামান্য পরিবর্তনগুলির সাথে সেগুলি গণনা করতে কিছু সি লিখেছিলাম - আমি সেটটি উপস্থাপনের জন্য সংখ্যার ব্যাপ্তির চেয়ে সেটগুলির সূচকটি ব্যবহার করি, তাই আমরা সর্বদা 0 ... এন থেকে কাজ করছি। বিঃদ্রঃ:

  1. যেহেতু সংমিশ্রণগুলি আনঅর্ডারড, তাই {1,3,2} = {1,2,3} - আমরা তাদের অভিধানভুক্ত করার আদেশ দিই।
  2. এই পদ্ধতির প্রথম পার্থক্যের জন্য সেটটি শুরু করতে একটি অন্তর্নিহিত 0 রয়েছে।

ডিক্সোগ্রাফিকাল অর্ডারের মিশ্রণের সূচক (ম্যাকক্যাফ্রে)

আরও একটি উপায় আছে : এটির ধারণাটি উপলব্ধি করা এবং প্রোগ্রাম করা সহজ তবে এটি বাকলসের অপ্টিমাইজেশন ছাড়াই। ভাগ্যক্রমে, এটি সদৃশ সমন্বয়ও উত্পাদন করে না:

সেটটি x_k ... x_1 এ এনসর্বাধিক i = C (x_1, কে) + সি (x_2, কে -1) + ... + সি (x_k, 1), যেখানে সি (এন, আর) = {n টি বেছে নিন}

একটি উদাহরণস্বরূপ: 27 = C(6,4) + C(5,3) + C(2,2) + C(1,1)। সুতরাং, চারটি জিনিসের 27 তম অভিধানের সংমিশ্রণটি হ'ল: 2 1,2,5,6 those, এগুলি আপনি যা দেখতে চান সেট সেট করে। নীচে উদাহরণ (ওক্যামল), chooseফাংশন প্রয়োজন , পাঠকের কাছে বাম:

(* this will find the [x] combination of a [set] list when taking [k] elements *)
let combination_maccaffery set k x =
    (* maximize function -- maximize a that is aCb              *)
    (* return largest c where c < i and choose(c,i) <= z        *)
    let rec maximize a b x =
        if (choose a b ) <= x then a else maximize (a-1) b x
    in
    let rec iterate n x i = match i with
        | 0 -> []
        | i ->
            let max = maximize n i x in
            max :: iterate n (x - (choose max i)) (i-1)
    in
    if x < 0 then failwith "errors" else
    let idxs =  iterate (List.length set) x k in
    List.map (List.nth set) (List.sort (-) idxs)

একটি ছোট এবং সাধারণ সংমিশ্রণ পুনরুক্তি

নিম্নলিখিত দুটি অ্যালগরিদমগুলি ডায়ডটিক উদ্দেশ্যে সরবরাহ করা হয়েছে। তারা একটি পুনরাবৃত্তকারী এবং (আরও সাধারণ) ফোল্ডার সামগ্রিক সংমিশ্রণগুলি প্রয়োগ করে। জটিলতা হে ( এন সি কে ) থাকার কারণে এগুলি যথাসম্ভব দ্রুত । স্মৃতিশক্তি গ্রহন দ্বারা আবদ্ধ k

আমরা পুনরুক্তি দিয়ে শুরু করব, যা প্রতিটি সংমিশ্রনের জন্য কোনও ব্যবহারকারী প্রদত্ত ফাংশনটি কল করবে

let iter_combs n k f =
  let rec iter v s j =
    if j = k then f v
    else for i = s to n - 1 do iter (i::v) (i+1) (j+1) done in
  iter [] 0 0

আরও সাধারণ সংস্করণ প্রারম্ভিক অবস্থা থেকে শুরু করে রাষ্ট্রের পরিবর্তনশীল সহ ব্যবহারকারী প্রদত্ত ফাংশনটিকে কল করবে। যেহেতু আমাদের বিভিন্ন রাজ্যের মধ্যে রাষ্ট্রটি পাস করতে হবে আমরা লুপটি ব্যবহার করব না, পরিবর্তে পুনরাবৃত্তি ব্যবহার করব,

let fold_combs n k f x =
  let rec loop i s c x =
    if i < n then
      loop (i+1) s c @@
      let c = i::c and s = s + 1 and i = i + 1 in
      if s < k then loop i s c x else f c x
    else x in
  loop 0 0 [] x

1
যেখানে সেটটিতে সমান উপাদান রয়েছে সে ক্ষেত্রে এটি নকল সংমিশ্রণ তৈরি করবে?
টমাস আহলে

2
হ্যাঁ এটি থমাস হবে। এটি অ্যারের ডেটাতে অজ্ঞেয় ost পছন্দসই প্রভাবটি বা অন্য অ্যালগরিদম চয়ন করা থাকলে আপনি সর্বদা প্রথমে নকলগুলি ফিল্টার করতে পারেন।
nulucaroni

19
দুর্দান্ত উত্তর। আপনি দয়া করে প্রতিটি অ্যালগরিদমের জন্য রান সময় এবং মেমরি বিশ্লেষণের সংক্ষিপ্তসার সরবরাহ করতে পারেন?
uncaught_exferences 21

2
মোটামুটি ভাল উত্তর। 20 সি 3 হ'ল 1140, বিস্ময়কর চিহ্নটি এখানে বিব্রতকর বলে মনে হচ্ছে কারণ এটি কোনও ফ্যাক্টরিয়াল মত দেখাচ্ছে, এবং ফ্যাক্টরিয়ালগুলি সংমিশ্রণগুলি সন্ধানের সূত্রে প্রবেশ করে। আমি তাই উদ্দীপনা চিহ্ন সম্পাদনা করব।
ক্যাশকো

3
এটি ব্যর্থ হয় যে উদ্ধৃতিগুলির অনেকগুলি পে-ওলের পিছনে রয়েছে। নন-পেওয়াল লিঙ্কগুলিকে অন্তর্ভুক্ত করার বা উত্স থেকে উদ্ধৃত স্নিপেটগুলি অন্তর্ভুক্ত করার কি সম্ভাবনা আছে?
টেরেন্স

195

সি # তে:

public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k)
{
  return k == 0 ? new[] { new T[0] } :
    elements.SelectMany((e, i) =>
      elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] {e}).Concat(c)));
}

ব্যবহার:

var result = Combinations(new[] { 1, 2, 3, 4, 5 }, 3);

ফলাফল:

123
124
125
134
135
145
234
235
245
345

2
এই সমাধানটি "ছোট" সেটগুলির জন্য ভাল কাজ করে তবে বড় সেটগুলির জন্য এটি কিছুটা মেমরি ব্যবহার করে।
আর্টুর কারভালহো

1
সরাসরি সম্পর্কিত নয়, কোডটি খুব আকর্ষণীয় / পঠনযোগ্য এবং আমি ভাবছি যে সি # এর কোন সংস্করণটির এই গঠন / পদ্ধতি রয়েছে? (আমি কেবল সি # ভি 1.0 ব্যবহার করেছি এবং এটি খুব বেশি নয়)।
এলবারেট

অবশ্যই মার্জিত, কিন্তু আইনামিউরেবল অনেক সময় গণনা করা হবে । যদি এটি কোনও উল্লেখযোগ্য অপারেশনের দ্বারা সমর্থিত হয় ...
ড্রয় নোকস

2
যেহেতু এটি একটি এক্সটেনশন পদ্ধতি আপনার ব্যবহারের লাইনটি পড়তে পারে:var result = new[] { 1, 2, 3, 4, 5 }.Combinations(3);
ডেভ কজিনিউ

1
আপনি কি পুনরাবৃত্তাকারী লুপগুলি ব্যবহার করে এই ক্যোয়ারির সঠিক নন লিনক সংস্করণ সরবরাহ করতে পারেন
ইরফান্ডার

81

সংক্ষিপ্ত জাভা সমাধান:

import java.util.Arrays;

public class Combination {
    public static void main(String[] args){
        String[] arr = {"A","B","C","D","E","F"};
        combinations2(arr, 3, 0, new String[3]);
    }

    static void combinations2(String[] arr, int len, int startPosition, String[] result){
        if (len == 0){
            System.out.println(Arrays.toString(result));
            return;
        }       
        for (int i = startPosition; i <= arr.length-len; i++){
            result[result.length - len] = arr[i];
            combinations2(arr, len-1, i+1, result);
        }
    }       
}

ফলাফল হবে

[A, B, C]
[A, B, D]
[A, B, E]
[A, B, F]
[A, C, D]
[A, C, E]
[A, C, F]
[A, D, E]
[A, D, F]
[A, E, F]
[B, C, D]
[B, C, E]
[B, C, F]
[B, D, E]
[B, D, F]
[B, E, F]
[C, D, E]
[C, D, F]
[C, E, F]
[D, E, F]

এটি ও (এন ^ 3) ঠিক বলে মনে হচ্ছে? আমি অবাক হচ্ছি এটি করার জন্য একটি দ্রুত অ্যালগরিদম আছে।
LZH

আমি 20 বেছে 10 এর সাথে কাজ করছি 10 এবং এটি আমার পক্ষে যথেষ্ট দ্রুত বলে মনে হচ্ছে (1 সেকেন্ডেরও কম)
ডেমোঙ্গোলেম

4
@ ন্যানোহিডেড আপনি ভুল বলছেন এটি পুনরাবৃত্তি ছাড়া সংমিশ্রণ। এবং আপনার ক্ষেত্রে পুনরাবৃত্তি হয়।
জ্যাক দ্য রিপার

এই কোডের টুকরো ওয়েবে সন্ধান করা আরও সহজ হওয়া উচিত ... এটি ঠিক আমি যা খুঁজছিলাম!
ম্যানুয়েল এস

আমি কেবল এটি এবং অন্যান্য 7 টি জাভা বাস্তবায়ন পরীক্ষা করেছি - এটি এখন পর্যন্ত সবচেয়ে দ্রুততম ছিল। ২ য়তম দ্রুতগতি ধীর গতির অর্ডারের চেয়ে বেশি ছিল।
স্টুয়ার্ট

77

আমি কি এই সমস্যাটির জন্য আমার পুনরাবৃত্ত পাইথন সমাধানটি উপস্থাপন করতে পারি?

def choose_iter(elements, length):
    for i in xrange(len(elements)):
        if length == 1:
            yield (elements[i],)
        else:
            for next in choose_iter(elements[i+1:len(elements)], length-1):
                yield (elements[i],) + next
def choose(l, k):
    return list(choose_iter(l, k))

ব্যবহারের উদাহরণ:

>>> len(list(choose_iter("abcdefgh",3)))
56

আমি এটির সরলতার জন্য এটি পছন্দ করি।


16
len(tuple(itertools.combinations('abcdefgh',3)))পাইথনে কম কোড সহ একই জিনিস অর্জন করবে।
hgus1294

59
@ hgus1294 সত্য, তবে এটি প্রতারণা হবে। ওপ একটি নির্দিষ্ট প্রোগ্রামিং ভাষার সাথে আবদ্ধ একটি "ম্যাজিক" পদ্ধতি নয়, একটি অ্যালগরিদমের অনুরোধ করেছিলেন Op
MestreLion

1
প্রথম লুপের সীমাটি কঠোরভাবে বলা উচিত নয় for i in xrange(len(elements) - length + 1):? স্লাইস সূচকের বাইরে চলে যাওয়া কৌতূহলীভাবে পরিচালনা করা হয় তবে এটি সঠিক অ্যালগরিদম।
স্টিফান ডলবার্গ

62

আপনার অক্ষরের অ্যারেটি দেখতে এমনটি বলে দেয়: "ABCDEFGH"। আপনার কাছে তিনটি সূচক রয়েছে (আই, জে, কে) আপনি বর্তমান শব্দের জন্য কোন অক্ষর ব্যবহার করতে যাচ্ছেন তা নির্দেশ করে, আপনি দিয়ে শুরু করুন:

ABCDEFGH
^ ^ ^
ijk

প্রথমে আপনি কে পরিবর্তিত হন, সুতরাং পরবর্তী পদক্ষেপটি এর মতো দেখায়:

ABCDEFGH
^ ^ ^
ijk

আপনি যদি শেষ প্রান্তে পৌঁছে যান এবং জে এবং তারপরে আবার কে পরিবর্তিত হন।

ABCDEFGH
^ ^ ^
ijk

ABCDEFGH
^ ^ ^
ijk

একবার আপনি জে পৌঁছেছেন আপনি পরিবর্তন করতে পারবেন i।

ABCDEFGH
  ^ ^ ^
  ijk

ABCDEFGH
  ^ ^ ^
  ijk
...

কোড লিখিত এই চেহারা কিছু

void print_combinations(const char *string)
{
    int i, j, k;
    int len = strlen(string);

    for (i = 0; i < len - 2; i++)
    {
        for (j = i + 1; j < len - 1; j++)
        {
            for (k = j + 1; k < len; k++)
                printf("%c%c%c\n", string[i], string[j], string[k]);
        }
    }
}

115
এই পদ্ধতির সাথে সমস্যা হ'ল এটি কোডটিতে পরামিতি 3 -কে শক্ত করে। (যদি 4 টি অক্ষর পছন্দসই হয় তবে কী হবে?) আমি যেমন প্রশ্নটি বুঝতে পেরেছি, উভয় অক্ষরের অ্যারে এবং নির্বাচনের জন্য বর্ণগুলির সংখ্যা সরবরাহ করা হবে। অবশ্যই, এই সমস্যাটির চারপাশের একটি উপায় হ'ল স্পষ্টভাবে-নেস্ট করা লুপগুলি পুনরাবৃত্তি সহ প্রতিস্থাপন করা।
joel.neely

10
@ ডাঃ পার্সনপারসনআইআই এবং ওপিতে কোনও প্রাসঙ্গিকতার ত্রিভুজ কেন?
MestreLion

7
আপনি এই সমাধানটিকে সর্বদা স্বেচ্ছাচারিত প্যারামিটারের সাথে পুনরাবৃত্ত করতে রূপান্তর করতে পারেন।
রোক ক্রালজ

5
@ রোকরালজ, আমরা কীভাবে "স্বেচ্ছাসেবী পরামিতিগুলির সাথে পুনরাবৃত্তি করতে এই সমাধানটি রূপান্তর করব"? আমার কাছে অসম্ভব বলে মনে হচ্ছে।
অ্যারন ম্যাকডেইড 4'15

3
এটি কীভাবে করা যায় তার একটি সুন্দর স্বজ্ঞাত ব্যাখ্যা
যোনাতন সিমসন

53

নিম্নলিখিত পুনরাবৃত্তিমূলক অ্যালগরিদম একটি আদেশকৃত সেট থেকে সমস্ত কে-উপাদান সংমিশ্রণ চয়ন করে:

  • iআপনার সংমিশ্রণের প্রথম উপাদানটি চয়ন করুন
  • এর চেয়ে বড় উপাদানগুলির সেট থেকে পুনরাবৃত্তভাবে নির্বাচিত উপাদানগুলির iসংমিশ্রণের সাথে একত্রিত করুন ।k-1i

সেটের প্রত্যেকটির জন্য উপরের অংশটি চিহ্নিত করুন i

iপুনরাবৃত্তি এড়াতে আপনি বাকি উপাদানগুলি যত বড় আকারে বেছে নেবেন এটি অপরিহার্য । এইভাবে [৩,৫] একবারে একবারে বেছে নেওয়া হবে, [৩] [৫] এর সাথে একত্রে দু'বার পরিবর্তে (শর্তটি [৫] + [৩]) মুছে ফেলা হবে। এই শর্ত ছাড়াই আপনি সংমিশ্রণের পরিবর্তে বৈচিত্রগুলি পান।


12
উত্তর অনেকের দ্বারা ব্যবহৃত অ্যালগরিদমের ইংরেজিতে খুব ভাল বর্ণনা
MestreLion

উপরের দ্বিতীয়; বিশেষত, এটি আমাকে ব্যবহারকারী 935714 দ্বারা উত্থাপিত সমাধান বুঝতে সহায়তা করেছে। উভয়ই দুর্দান্ত।
জ্যাকোব্ল্যাম্বার্ট

25

সি ++ এ নিম্নোক্ত রুটিনটি [প্রথম, শেষ) ব্যাপ্তির মধ্যে দৈর্ঘ্যের দূরত্বের (প্রথম, কে) সমস্ত সংমিশ্রণ উত্পন্ন করবে:

#include <algorithm>

template <typename Iterator>
bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
   /* Credits: Mark Nelson http://marknelson.us */
   if ((first == last) || (first == k) || (last == k))
      return false;
   Iterator i1 = first;
   Iterator i2 = last;
   ++i1;
   if (last == i1)
      return false;
   i1 = last;
   --i1;
   i1 = k;
   --i2;
   while (first != i1)
   {
      if (*--i1 < *i2)
      {
         Iterator j = k;
         while (!(*i1 < *j)) ++j;
         std::iter_swap(i1,j);
         ++i1;
         ++j;
         i2 = k;
         std::rotate(i1,j,last);
         while (last != j)
         {
            ++j;
            ++i2;
         }
         std::rotate(k,i2,last);
         return true;
      }
   }
   std::rotate(first,k,last);
   return false;
}

এটি এর মতো ব্যবহার করা যেতে পারে:

#include <string>
#include <iostream>

int main()
{
    std::string s = "12345";
    std::size_t comb_size = 3;
    do
    {
        std::cout << std::string(s.begin(), s.begin() + comb_size) << std::endl;
    } while (next_combination(s.begin(), s.begin() + comb_size, s.end()));

    return 0;
}

এটি নিম্নলিখিত মুদ্রণ করবে:

123
124
125
134
135
145
234
235
245
345

1
কি শুরু হয়, এই ক্ষেত্রে কি শেষ? যদি এই ফাংশনে পাস করা সমস্ত ভেরিয়েবলগুলি মান দ্বারা পাস হয় তবে কীভাবে এটি আসলে কিছু ফিরিয়ে দিতে পারে?
সের্গেজ আন্দ্রেজেভ

6
@ সেরেজেজ আন্দ্রেজেভ: প্রতিস্থাপন করুন beingএবং এর beginসাথে s.begin()এবং endসাথে করুন s.end()। কোডটি নিবিড়ভাবে এসটিএল এর next_permutationঅ্যালগরিদম অনুসরণ করে , আরও বিশদে এখানে বর্ণিত ।
অ্যান্টনি ল্যাবারে

5
কি হচ্ছে? i1 = সর্বশেষ; --i1; i1 = কে;
মনোজ আর

24

আমি এই থ্রেডটি দরকারী হিসাবে পেয়েছি এবং ভেবেছিলাম যে আমি একটি জাভাস্ক্রিপ্ট সমাধান যুক্ত করব যা আপনি ফায়ারব্যাগে পপ করতে পারেন। আপনার জেএস ইঞ্জিনের উপর নির্ভর করে, প্রারম্ভিক স্ট্রিং বড় হলে এটি কিছুটা সময় নিতে পারে।

function string_recurse(active, rest) {
    if (rest.length == 0) {
        console.log(active);
    } else {
        string_recurse(active + rest.charAt(0), rest.substring(1, rest.length));
        string_recurse(active, rest.substring(1, rest.length));
    }
}
string_recurse("", "abc");

আউটপুট নিম্নলিখিত হিসাবে হওয়া উচিত:

abc
ab
ac
a
bc
b
c

4
@ NanoHead- এটি ভুল নয় । আউটপুট ইতিমধ্যে "এসি" দেখায় - এবং "সিএ" "এসি" এর সমান সমন্বয় । আপনি ক্রমান্বয়ের কথা বলছেন (গণিতে) যেখানে "এসি" "সিএ" এর মতো হবে না।
জাকব জেনকভ

1
এটি n কে কে বেছে নেবে না।
shinzou

20
static IEnumerable<string> Combinations(List<string> characters, int length)
{
    for (int i = 0; i < characters.Count; i++)
    {
        // only want 1 character, just return this one
        if (length == 1)
            yield return characters[i];

        // want more than one character, return this one plus all combinations one shorter
        // only use characters after the current one for the rest of the combinations
        else
            foreach (string next in Combinations(characters.GetRange(i + 1, characters.Count - (i + 1)), length - 1))
                yield return characters[i] + next;
    }
}

সুন্দর সমাধান। : আমি এই সাম্প্রতিক প্রশ্নের উত্তর এটা রেফারেন্সড stackoverflow.com/questions/4472036/...
wageoghe

এই ফাংশনটির সাথে একমাত্র সমস্যাটি পুনরাবৃত্তি is পিসিতে চলমান সফ্টওয়্যারটির জন্য এটি সাধারণত ঠিক আছে, আপনি যদি আরও
সংস্থানযুক্ত

এটি অনেকগুলি তালিকা বরাদ্দ করবে এবং অ্যারের আইটেমগুলিকে প্রতিটি নতুন ক্ষেত্রে নকল করতে প্রচুর কাজ করবে। আমার কাছে মনে হচ্ছে পুরো তালিকাটি সম্পূর্ণ না হওয়া পর্যন্ত এই তালিকাগুলি সংগ্রহযোগ্য হবে না।
নিয়াল কান্নাটন

যে চতুর। আপনি কি একটি অ্যালগরিদম খুঁজে পেয়েছেন বা এটি স্ক্র্যাচ থেকে?
পাপারাজ্জো

20

পাইথনের সংক্ষিপ্ত উদাহরণ:

def comb(sofar, rest, n):
    if n == 0:
        print sofar
    else:
        for i in range(len(rest)):
            comb(sofar + rest[i], rest[i+1:], n-1)

>>> comb("", "abcde", 3)
abc
abd
abe
acd
ace
ade
bcd
bce
bde
cde

ব্যাখ্যার জন্য, পুনরাবৃত্তির পদ্ধতিটি নিম্নলিখিত উদাহরণ সহ বর্ণিত হয়েছে:

উদাহরণ: এবিসিডিডি
3 এর সমস্ত সমন্বয় হবে:

  • বাকী থেকে সমস্ত সংমিশ্রণ (বিসিডিই) সহ একটি
  • বাকি (সিডিই) থেকে 2 এর সমস্ত সংমিশ্রণ সহ বি
  • বাকি (ডিই) থেকে 2 এর সমস্ত সংমিশ্রণ সহ সি

17

হাস্কেলে সাধারণ পুনরাবৃত্তির অ্যালগরিদম

import Data.List

combinations 0 lst = [[]]
combinations n lst = do
    (x:xs) <- tails lst
    rest   <- combinations (n-1) xs
    return $ x : rest

আমরা প্রথমে বিশেষ ক্ষেত্রে সংজ্ঞায়িত করি, অর্থাৎ শূন্য উপাদান নির্বাচন করে। এটি একটি একক ফলাফল উত্পন্ন করে, যা খালি তালিকা (অর্থাত একটি শূন্য তালিকা রয়েছে এমন একটি তালিকা)।

এন> 0 xএর জন্য তালিকার প্রতিটি উপাদান জুড়ে যায় এবং xsপ্রতিটি উপাদান পরে থাকে x

restপুনরাবৃত্ত কলটি ব্যবহার করে n - 1উপাদানগুলিকে বেছে xsনিয়েছে combinations। ফাংশনের চূড়ান্ত ফলাফল একটি তালিকা যেখানে প্রতিটি উপাদান হল x : rest(অর্থাত একটি তালিকা যা হয়েছে xপ্রধান হিসেবে এবং restপ্রতিটি ভিন্ন মান লেজ হিসাবে) xএবং rest

> combinations 3 "abcde"
["abc","abd","abe","acd","ace","ade","bcd","bce","bde","cde"]

এবং অবশ্যই, হাস্কেল যেহেতু অলস, তাই তালিকাটি ধীরে ধীরে প্রয়োজনীয় হিসাবে তৈরি করা হয়, তাই আপনি আঞ্চলিকভাবে বৃহত্তর সংমিশ্রণগুলি মূল্যায়ন করতে পারেন।

> let c = combinations 8 "abcdefghijklmnopqrstuvwxyz"
> take 10 c
["abcdefgh","abcdefgi","abcdefgj","abcdefgk","abcdefgl","abcdefgm","abcdefgn",
 "abcdefgo","abcdefgp","abcdefgq"]

13

এবং এখানে গ্রান্ট্যাড্ডি কোবল আসে, এটি খুব ম্যালেন্ডেড ভাষা।

আসুন প্রতিটি বাইটের 34 টি উপাদানের একটি অ্যারে ধরে নিই (খাঁটি স্বেচ্ছাসেবী নির্বাচন।) ধারণাটি সমস্ত সম্ভাব্য 4-উপাদান সংমিশ্রণগুলি গণনা করা এবং এটিকে একটি অ্যারেতে লোড করা।

আমরা 4 টি গ্রুপের প্রতিটি পদের জন্য 4 টি সূচক ব্যবহার করি

অ্যারেটি এভাবে প্রক্রিয়া করা হয়:

    idx1 = 1
    idx2 = 2
    idx3 = 3
    idx4 = 4

আমরা IDX4 4 থেকে শেষ পর্যন্ত পরিবর্তিত হয়। প্রতিটি আইডিএক্স 4 এর জন্য আমরা চারটি দলের এক অনন্য সমন্বয় পাই। যখন idx4 অ্যারের শেষে আসে, আমরা idx3 1 দ্বারা বৃদ্ধি করি এবং idx4 + কে idx3 + 1 এ সেট করি। তারপরে আমরা আবার শেষ পর্যন্ত আইডিএক্স 4 চালাই। আমরা এই পদ্ধতিতে এগিয়ে চলেছি, যথাক্রমে idx3, idx2, এবং idx1 এর বাড়ানো পর্যন্ত আইডিএক্স 1 এর অবস্থান অ্যারের শেষ থেকে 4 এর চেয়ে কম না হওয়া পর্যন্ত। এটি অ্যালগরিদম শেষ করে।

1          --- pos.1
2          --- pos 2
3          --- pos 3
4          --- pos 4
5
6
7
etc.

প্রথম পুনরাবৃত্তি:

1234
1235
1236
1237
1245
1246
1247
1256
1257
1267
etc.

একটি কোবল উদাহরণ:

01  DATA_ARAY.
    05  FILLER     PIC X(8)    VALUE  "VALUE_01".
    05  FILLER     PIC X(8)    VALUE  "VALUE_02".
  etc.
01  ARAY_DATA    OCCURS 34.
    05  ARAY_ITEM       PIC X(8).

01  OUTPUT_ARAY   OCCURS  50000   PIC X(32).

01   MAX_NUM   PIC 99 COMP VALUE 34.

01  INDEXXES  COMP.
    05  IDX1            PIC 99.
    05  IDX2            PIC 99.
    05  IDX3            PIC 99.
    05  IDX4            PIC 99.
    05  OUT_IDX   PIC 9(9).

01  WHERE_TO_STOP_SEARCH          PIC 99  COMP.

* Stop the search when IDX1 is on the third last array element:

COMPUTE WHERE_TO_STOP_SEARCH = MAX_VALUE - 3     

MOVE 1 TO IDX1

PERFORM UNTIL IDX1 > WHERE_TO_STOP_SEARCH
   COMPUTE IDX2 = IDX1 + 1
   PERFORM UNTIL IDX2 > MAX_NUM
      COMPUTE IDX3 = IDX2 + 1
      PERFORM UNTIL IDX3 > MAX_NUM
         COMPUTE IDX4 = IDX3 + 1
         PERFORM UNTIL IDX4 > MAX_NUM
            ADD 1 TO OUT_IDX
            STRING  ARAY_ITEM(IDX1)
                    ARAY_ITEM(IDX2)
                    ARAY_ITEM(IDX3)
                    ARAY_ITEM(IDX4)
                    INTO OUTPUT_ARAY(OUT_IDX)
            ADD 1 TO IDX4
         END-PERFORM
         ADD 1 TO IDX3
      END-PERFORM
      ADD 1 TO IDX2
   END_PERFORM
   ADD 1 TO IDX1
END-PERFORM.

তবে কেন {} {} {}} {}
শিনজৌ

9

এখানে স্কালায় একটি মার্জিত, জেনেরিক বাস্তবায়ন, যেমন 99 স্কাল সমস্যার উপরে বর্ণিত ।

object P26 {
  def flatMapSublists[A,B](ls: List[A])(f: (List[A]) => List[B]): List[B] = 
    ls match {
      case Nil => Nil
      case sublist@(_ :: tail) => f(sublist) ::: flatMapSublists(tail)(f)
    }

  def combinations[A](n: Int, ls: List[A]): List[List[A]] =
    if (n == 0) List(Nil)
    else flatMapSublists(ls) { sl =>
      combinations(n - 1, sl.tail) map {sl.head :: _}
    }
}

9

যদি আপনি এসকিউএল সিনট্যাক্স ব্যবহার করতে পারেন - বলুন, আপনি যদি কোনও কাঠামো বা অ্যারের ক্ষেত্রগুলি অ্যাক্সেস করতে লিনকুই ব্যবহার করে থাকেন, বা সরাসরি একটি অক্ষরের সাথে "বর্ণমালা" নামে একটি টেবিলযুক্ত একটি ডাটাবেস অ্যাক্সেস করেন তবে আপনি নিম্নলিখিতটি মানিয়ে নিতে পারেন কোড:

SELECT A.Letter, B.Letter, C.Letter
FROM Alphabet AS A, Alphabet AS B, Alphabet AS C
WHERE A.Letter<>B.Letter AND A.Letter<>C.Letter AND B.Letter<>C.Letter
AND A.Letter<B.Letter AND B.Letter<C.Letter

"বর্ণমালা" (আপনি 3, 8, 10, 27, ইত্যাদি হতে পারেন) টেবিলের মধ্যে কত অক্ষর রয়েছে তা সত্ত্বেও এটি 3 টি বর্ণের সমস্ত সংমিশ্রণ ফিরিয়ে দেবে।

আপনি যা চান তা যদি সম্মতিগুলির চেয়ে সমস্ত অনুমোদন হয় (যেমন আপনি "এসিবি" এবং "এবিসি" আলাদা হিসাবে গণ্য করতে চান, কেবল একবার উপস্থিত হওয়ার চেয়ে) কেবলমাত্র শেষ লাইনটি (এএনএডি) মুছুন এবং এটি হয়ে গেছে।

সম্পাদনা-পরবর্তী: প্রশ্নটি পুনরায় পড়ার পরে, আমি বুঝতে পারি যে প্রয়োজনীয় জিনিসগুলি সাধারণ অ্যালগরিদম, 3 টি আইটেম নির্বাচন করার ক্ষেত্রে কেবল একটি নির্দিষ্ট নয়। অ্যাডাম হিউজের উত্তর সম্পূর্ণ, দুর্ভাগ্যক্রমে আমি এটিকে ভোট দিতে পারি না (এখনও)। এই উত্তরটি সহজ তবে যখন আপনি ঠিক 3 টি আইটেম চান কেবল তখনই কাজ করে।


7

সম্মিলন সূচকগুলির অলস প্রজন্মের সাথে আর একটি সি # সংস্করণ। এই সংস্করণটি সমস্ত মানের তালিকা এবং বর্তমান সংমিশ্রনের মানগুলির মধ্যে ম্যাপিং সংজ্ঞায়িত করতে সূচকগুলির একক অ্যারে বজায় রাখে, অর্থাত্ পুরো রানটাইমের সময় অবিচ্ছিন্নভাবে ও (কে) অতিরিক্ত স্থান ব্যবহার করে । কোডটি ও (কে) সময়ে প্রথমটি সহ পৃথক সংমিশ্রণ উত্পন্ন করে ।

public static IEnumerable<T[]> Combinations<T>(this T[] values, int k)
{
    if (k < 0 || values.Length < k)
        yield break; // invalid parameters, no combinations possible

    // generate the initial combination indices
    var combIndices = new int[k];
    for (var i = 0; i < k; i++)
    {
        combIndices[i] = i;
    }

    while (true)
    {
        // return next combination
        var combination = new T[k];
        for (var i = 0; i < k; i++)
        {
            combination[i] = values[combIndices[i]];
        }
        yield return combination;

        // find first index to update
        var indexToUpdate = k - 1;
        while (indexToUpdate >= 0 && combIndices[indexToUpdate] >= values.Length - k + indexToUpdate)
        {
            indexToUpdate--;
        }

        if (indexToUpdate < 0)
            yield break; // done

        // update combination indices
        for (var combIndex = combIndices[indexToUpdate] + 1; indexToUpdate < k; indexToUpdate++, combIndex++)
        {
            combIndices[indexToUpdate] = combIndex;
        }
    }
}

পরীক্ষার কোড:

foreach (var combination in new[] {'a', 'b', 'c', 'd', 'e'}.Combinations(3))
{
    System.Console.WriteLine(String.Join(" ", combination));
}

আউটপুট:

a b c
a b d
a b e
a c d
a c e
a d e
b c d
b c e
b d e
c d e

এটি অর্ডার সংরক্ষণ করে। আমি ফলাফলটি সেট করে c b aযা এটি দেয় না সেট করার আশা করছি ।
দিমিত্রি নেস্টারুক

টাস্কটি হ'ল সমস্ত সংমিশ্রণগুলি তৈরি করা যা কে ওভার এন-কে সন্তুষ্ট করে। দ্বি- পদার্থ সহগগুলি এন উপাদানগুলির একটি নির্দিষ্ট সেট থেকে কে উপাদানগুলির একটি সীমানাবিহীন উপসেট বেছে নিচ্ছে সে সম্পর্কে প্রশ্নের উত্তর দেয় । সুতরাং প্রস্তাবিত অ্যালগরিদম যা করা উচিত তা করে।
ক্রিস্টোফ

6

https://gist.github.com/3118596

জাভাস্ক্রিপ্টের জন্য একটি বাস্তবায়ন রয়েছে। এটিতে কে-কম্বিনেশন এবং যে কোনও অবজেক্টের অ্যারের সমস্ত সংমিশ্রণ পেতে ফাংশন রয়েছে। উদাহরণ:

k_combinations([1,2,3], 2)
-> [[1,2], [1,3], [2,3]]

combinations([1,2,3])
-> [[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]

6

এখানে আপনার কাছে সি # তে কোডড অ্যালগরিদমের একটি অলস মূল্যায়িত সংস্করণ রয়েছে:

    static bool nextCombination(int[] num, int n, int k)
    {
        bool finished, changed;

        changed = finished = false;

        if (k > 0)
        {
            for (int i = k - 1; !finished && !changed; i--)
            {
                if (num[i] < (n - 1) - (k - 1) + i)
                {
                    num[i]++;
                    if (i < k - 1)
                    {
                        for (int j = i + 1; j < k; j++)
                        {
                            num[j] = num[j - 1] + 1;
                        }
                    }
                    changed = true;
                }
                finished = (i == 0);
            }
        }

        return changed;
    }

    static IEnumerable Combinations<T>(IEnumerable<T> elements, int k)
    {
        T[] elem = elements.ToArray();
        int size = elem.Length;

        if (k <= size)
        {
            int[] numbers = new int[k];
            for (int i = 0; i < k; i++)
            {
                numbers[i] = i;
            }

            do
            {
                yield return numbers.Select(n => elem[n]);
            }
            while (nextCombination(numbers, size, k));
        }
    }

এবং পরীক্ষার অংশ:

    static void Main(string[] args)
    {
        int k = 3;
        var t = new[] { "dog", "cat", "mouse", "zebra"};

        foreach (IEnumerable<string> i in Combinations(t, k))
        {
            Console.WriteLine(string.Join(",", i));
        }
    }

আশা করি এটি আপনাকে সাহায্য করবে!


6

আমি পাইথনে প্রজেক্ট ইউলারের জন্য ব্যবহার করার জন্য একটি ক্রমুয়েশন অ্যালগরিদম পেয়েছিলাম:

def missing(miss,src):
    "Returns the list of items in src not present in miss"
    return [i for i in src if i not in miss]


def permutation_gen(n,l):
    "Generates all the permutations of n items of the l list"
    for i in l:
        if n<=1: yield [i]
        r = [i]
        for j in permutation_gen(n-1,missing([i],l)):  yield r+j

যদি

n<len(l) 

আপনার পুনরাবৃত্তি ছাড়া আপনার প্রয়োজন সমস্ত সংমিশ্রণ থাকা উচিত, আপনার এটির কি দরকার?

এটি একটি জেনারেটর, সুতরাং আপনি এটি এরকম কিছুতে ব্যবহার করুন:

for comb in permutation_gen(3,list("ABCDEFGH")):
    print comb 

5
Array.prototype.combs = function(num) {

    var str = this,
        length = str.length,
        of = Math.pow(2, length) - 1,
        out, combinations = [];

    while(of) {

        out = [];

        for(var i = 0, y; i < length; i++) {

            y = (1 << i);

            if(y & of && (y !== of))
                out.push(str[i]);

        }

        if (out.length >= num) {
           combinations.push(out);
        }

        of--;
    }

    return combinations;
}

5

ক্লোজার সংস্করণ:

(defn comb [k l]
  (if (= 1 k) (map vector l)
      (apply concat
             (map-indexed
              #(map (fn [x] (conj x %2))
                    (comb (dec k) (drop (inc %1) l)))
              l))))

5

আপনার অক্ষরের অ্যারেটি দেখতে এমনটি বলে দেয়: "ABCDEFGH"। আপনার কাছে তিনটি সূচক রয়েছে (আই, জে, কে) আপনি বর্তমান শব্দের জন্য কোন অক্ষর ব্যবহার করতে যাচ্ছেন তা নির্দেশ করে, আপনি দিয়ে শুরু করুন:

ABCDEFGH
^ ^ ^
ijk

প্রথমে আপনি কে পরিবর্তিত হন, সুতরাং পরবর্তী পদক্ষেপটি এর মতো দেখায়:

ABCDEFGH
^ ^ ^
ijk

আপনি যদি শেষ প্রান্তে পৌঁছে যান এবং জে এবং তারপরে আবার কে পরিবর্তিত হন।

ABCDEFGH
^ ^ ^
ijk

ABCDEFGH
^ ^ ^
ijk

একবার আপনি জে পৌঁছেছেন আপনি পরিবর্তন করতে পারবেন i।

ABCDEFGH
  ^ ^ ^
  ijk

ABCDEFGH
  ^ ^ ^
  ijk
...
function initializePointers($cnt) {
    $pointers = [];

    for($i=0; $i<$cnt; $i++) {
        $pointers[] = $i;
    }

    return $pointers;     
}

function incrementPointers(&$pointers, &$arrLength) {
    for($i=0; $i<count($pointers); $i++) {
        $currentPointerIndex = count($pointers) - $i - 1;
        $currentPointer = $pointers[$currentPointerIndex];

        if($currentPointer < $arrLength - $i - 1) {
           ++$pointers[$currentPointerIndex];

           for($j=1; ($currentPointerIndex+$j)<count($pointers); $j++) {
                $pointers[$currentPointerIndex+$j] = $pointers[$currentPointerIndex]+$j;
           }

           return true;
        }
    }

    return false;
}

function getDataByPointers(&$arr, &$pointers) {
    $data = [];

    for($i=0; $i<count($pointers); $i++) {
        $data[] = $arr[$pointers[$i]];
    }

    return $data;
}

function getCombinations($arr, $cnt)
{
    $len = count($arr);
    $result = [];
    $pointers = initializePointers($cnt);

    do {
        $result[] = getDataByPointers($arr, $pointers);
    } while(incrementPointers($pointers, count($arr)));

    return $result;
}

$result = getCombinations([0, 1, 2, 3, 4, 5], 3);
print_r($result);

Https://stackoverflow.com/a/127898/2628125 এর উপর ভিত্তি করে , তবে কোনও আকারের পয়েন্টারের জন্য আরও বিমূর্ত।


এই ভয়াবহ ভাষা কি? ব্যাশ?
shinzou

1
পিএইচপি, তবে ভাষা এখানে কোনও
গুরুত্ব

আমি খুব খুশি আমি এই ভাষাটি শিখতে অস্বীকার করি। এমন একটি ভাষা যেখানে তার দোভাষী /
সংকলকটির

4

সবই বলা এবং করা এখানে তার জন্য ও'কমল কোড আসে। অ্যালগরিদম কোড থেকে স্পষ্ট হয় ..

let combi n lst =
    let rec comb l c =
        if( List.length c = n) then [c] else
        match l with
        [] -> []
        | (h::t) -> (combi t (h::c))@(combi t c)
    in
        combi lst []
;;

4

এখানে একটি পদ্ধতি যা আপনাকে এলোমেলো দৈর্ঘ্যের স্ট্রিং থেকে নির্দিষ্ট আকারের সমস্ত সংমিশ্রণ দেয়। কুইনমার্স সমাধানের মতো, তবে বৈচিত্র্যপূর্ণ ইনপুট এবং কে।

কোডটি চারপাশে মোড়ানোতে পরিবর্তিত হতে পারে, অর্থাত্ 'ড্যাব' ইনপুট থেকে 'অ্যাবসিডি' ডব্লু কে = 3।

public void run(String data, int howMany){
    choose(data, howMany, new StringBuffer(), 0);
}


//n choose k
private void choose(String data, int k, StringBuffer result, int startIndex){
    if (result.length()==k){
        System.out.println(result.toString());
        return;
    }

    for (int i=startIndex; i<data.length(); i++){
        result.append(data.charAt(i));
        choose(data,k,result, i+1);
        result.setLength(result.length()-1);
    }
}

"Abcde" এর আউটপুট:

এবি আবড আবে এসিড এসি এডি বিসিডি বিএসই বিডি সিডি


3

আমি এর জন্য এসকিউএল সার্ভার ২০০ in এ একটি সমাধান তৈরি করেছি এবং এটি আমার ওয়েবসাইটে পোস্ট করেছি: http://www.jessemclain.com/downloads/code/sql/fn_GetMChooseNCombos.sql.htm

ব্যবহার দেখানোর জন্য এখানে একটি উদাহরণ রয়েছে:

SELECT * FROM dbo.fn_GetMChooseNCombos('ABCD', 2, '')

ফলাফল:

Word
----
AB
AC
AD
BC
BD
CD

(6 row(s) affected)

3

সি ++ এ আমার প্রস্তাবটি এখানে

আমি পুনরাবৃত্তকারী ধরণের উপর যতটা নিষেধাজ্ঞা আরোপ করার চেষ্টা করেছি ততই এই সমাধানটি কেবল সামনের দিকে পুনরুক্তিকারী হিসাবে ধরে নিয়েছে, এবং এটি কনস্টেটিটর হতে পারে। এটি কোনও স্ট্যান্ডার্ড ধারক সঙ্গে কাজ করা উচিত। যে ক্ষেত্রে আর্গুমেন্টগুলি এটি বোঝায় না তা স্ট্যান্ড :: অকার্যকর_আরগুমেন্ট

#include <vector>
#include <stdexcept>

template <typename Fci> // Fci - forward const iterator
std::vector<std::vector<Fci> >
enumerate_combinations(Fci begin, Fci end, unsigned int combination_size)
{
    if(begin == end && combination_size > 0u)
        throw std::invalid_argument("empty set and positive combination size!");
    std::vector<std::vector<Fci> > result; // empty set of combinations
    if(combination_size == 0u) return result; // there is exactly one combination of
                                              // size 0 - emty set
    std::vector<Fci> current_combination;
    current_combination.reserve(combination_size + 1u); // I reserve one aditional slot
                                                        // in my vector to store
                                                        // the end sentinel there.
                                                        // The code is cleaner thanks to that
    for(unsigned int i = 0u; i < combination_size && begin != end; ++i, ++begin)
    {
        current_combination.push_back(begin); // Construction of the first combination
    }
    // Since I assume the itarators support only incrementing, I have to iterate over
    // the set to get its size, which is expensive. Here I had to itrate anyway to  
    // produce the first cobination, so I use the loop to also check the size.
    if(current_combination.size() < combination_size)
        throw std::invalid_argument("combination size > set size!");
    result.push_back(current_combination); // Store the first combination in the results set
    current_combination.push_back(end); // Here I add mentioned earlier sentinel to
                                        // simplyfy rest of the code. If I did it 
                                        // earlier, previous statement would get ugly.
    while(true)
    {
        unsigned int i = combination_size;
        Fci tmp;                            // Thanks to the sentinel I can find first
        do                                  // iterator to change, simply by scaning
        {                                   // from right to left and looking for the
            tmp = current_combination[--i]; // first "bubble". The fact, that it's 
            ++tmp;                          // a forward iterator makes it ugly but I
        }                                   // can't help it.
        while(i > 0u && tmp == current_combination[i + 1u]);

        // Here is probably my most obfuscated expression.
        // Loop above looks for a "bubble". If there is no "bubble", that means, that
        // current_combination is the last combination, Expression in the if statement
        // below evaluates to true and the function exits returning result.
        // If the "bubble" is found however, the ststement below has a sideeffect of 
        // incrementing the first iterator to the left of the "bubble".
        if(++current_combination[i] == current_combination[i + 1u])
            return result;
        // Rest of the code sets posiotons of the rest of the iterstors
        // (if there are any), that are to the right of the incremented one,
        // to form next combination

        while(++i < combination_size)
        {
            current_combination[i] = current_combination[i - 1u];
            ++current_combination[i];
        }
        // Below is the ugly side of using the sentinel. Well it had to haave some 
        // disadvantage. Try without it.
        result.push_back(std::vector<Fci>(current_combination.begin(),
                                          current_combination.end() - 1));
    }
}

3

আমি সম্প্রতি জাভাতে লিখেছি এমন একটি কোড এখানে রয়েছে যা "আউট" উপাদানগুলির "নাম" উপাদানগুলির সমস্ত সংমিশ্রণ গণনা করে এবং প্রদান করে।

// author: Sourabh Bhat (heySourabh@gmail.com)

public class Testing
{
    public static void main(String[] args)
    {

// Test case num = 5, outOf = 8.

        int num = 5;
        int outOf = 8;
        int[][] combinations = getCombinations(num, outOf);
        for (int i = 0; i < combinations.length; i++)
        {
            for (int j = 0; j < combinations[i].length; j++)
            {
                System.out.print(combinations[i][j] + " ");
            }
            System.out.println();
        }
    }

    private static int[][] getCombinations(int num, int outOf)
    {
        int possibilities = get_nCr(outOf, num);
        int[][] combinations = new int[possibilities][num];
        int arrayPointer = 0;

        int[] counter = new int[num];

        for (int i = 0; i < num; i++)
        {
            counter[i] = i;
        }
        breakLoop: while (true)
        {
            // Initializing part
            for (int i = 1; i < num; i++)
            {
                if (counter[i] >= outOf - (num - 1 - i))
                    counter[i] = counter[i - 1] + 1;
            }

            // Testing part
            for (int i = 0; i < num; i++)
            {
                if (counter[i] < outOf)
                {
                    continue;
                } else
                {
                    break breakLoop;
                }
            }

            // Innermost part
            combinations[arrayPointer] = counter.clone();
            arrayPointer++;

            // Incrementing part
            counter[num - 1]++;
            for (int i = num - 1; i >= 1; i--)
            {
                if (counter[i] >= outOf - (num - 1 - i))
                    counter[i - 1]++;
            }
        }

        return combinations;
    }

    private static int get_nCr(int n, int r)
    {
        if(r > n)
        {
            throw new ArithmeticException("r is greater then n");
        }
        long numerator = 1;
        long denominator = 1;
        for (int i = n; i >= r + 1; i--)
        {
            numerator *= i;
        }
        for (int i = 2; i <= n - r; i++)
        {
            denominator *= i;
        }

        return (int) (numerator / denominator);
    }
}

3

একটি সংক্ষিপ্ত জাভাস্ক্রিপ্ট সমাধান:

Array.prototype.combine=function combine(k){    
    var toCombine=this;
    var last;
    function combi(n,comb){             
        var combs=[];
        for ( var x=0,y=comb.length;x<y;x++){
            for ( var l=0,m=toCombine.length;l<m;l++){      
                combs.push(comb[x]+toCombine[l]);           
            }
        }
        if (n<k-1){
            n++;
            combi(n,combs);
        } else{last=combs;}
    }
    combi(1,toCombine);
    return last;
}
// Example:
// var toCombine=['a','b','c'];
// var results=toCombine.combine(4);

3

অ্যালগরিদম:

  • 1 থেকে 2 Count n পর্যন্ত গণনা করুন।
  • প্রতিটি অঙ্ককে এর বাইনারি উপস্থাপনায় রূপান্তর করুন।
  • অবস্থানের ভিত্তিতে আপনার সেটের উপাদানগুলিতে প্রতিটি 'অন' বিট অনুবাদ করুন।

সি # তে:

void Main()
{
    var set = new [] {"A", "B", "C", "D" }; //, "E", "F", "G", "H", "I", "J" };

    var kElement = 2;

    for(var i = 1; i < Math.Pow(2, set.Length); i++) {
        var result = Convert.ToString(i, 2).PadLeft(set.Length, '0');
        var cnt = Regex.Matches(Regex.Escape(result),  "1").Count; 
        if (cnt == kElement) {
            for(int j = 0; j < set.Length; j++)
                if ( Char.GetNumericValue(result[j]) == 1)
                    Console.Write(set[j]);
            Console.WriteLine();
        }
    }
}

কেন এটি কাজ করে?

একটি এন-এলিমেন্ট সেট এবং এন-বিট সিকোয়েন্সগুলির সাবসেটের মধ্যে একটি সক্ষমতা রয়েছে।

এর অর্থ আমরা ক্রম গণনা করে কতগুলি সাবসেট আছে তা নির্ধারণ করতে পারি।

উদাহরণস্বরূপ, নীচে সেট করা চারটি উপাদানটি sequ 0,1} এক্স {0, 1} এক্স {0, 1} এক্স {0, 1} (বা 2 ^ 4) বিভিন্ন সিকোয়েন্স দ্বারা প্রতিনিধিত্ব করা যেতে পারে।

সুতরাং - আমাদের যা করতে হবে তা সমস্ত সংমিশ্রণগুলি খুঁজতে 1 থেকে 2 ^ n পর্যন্ত গণনা করতে হবে। (আমরা খালি সেটটিকে অগ্রাহ্য করি)) এরপরে, অঙ্কগুলি তাদের বাইনারি উপস্থাপনায় অনুবাদ করুন। তারপরে আপনার সেটগুলির উপাদানগুলি 'অন' বিটগুলির জন্য প্রতিস্থাপন করুন।

আপনি যদি কেবল কে উপাদানগুলির ফলাফল চান, কেবলমাত্র যখন বি বিটগুলি 'চালু' থাকে তখন মুদ্রণ করুন।

(আপনি যদি কে লেন্থের সাবসেটের পরিবর্তে সমস্ত সাবসেট চান তবে সিএনটি / কেএলমেন্ট অংশটি সরিয়ে দিন))

(প্রমাণ স্বরূপ, কম্পিউটার বিজ্ঞান, লেহম্যান জন্য MIT- র বিনামূল্যে কোর্সসমূহের গণিত দেখতে এট, বিভাগ 11.2.2। Https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-042j-mathematics- কম্পিউটার-বিজ্ঞান-পতনের জন্য 2010 / রিডিংস / )


3

সংক্ষিপ্ত অজগর কোড, সূচক অবস্থানের ফলন

def yield_combos(n,k):
    # n is set size, k is combo size

    i = 0
    a = [0]*k

    while i > -1:
        for j in range(i+1, k):
            a[j] = a[j-1]+1
        i=j
        yield a
        while a[i] == i + n - k:
            i -= 1
        a[i] += 1

2

দ্বিপদী সহগের সাথে কাজ করার জন্য সাধারণ ফাংশনগুলি পরিচালনা করার জন্য আমি একটি ক্লাস লিখেছি, যা আপনার সমস্যার অধীনে আসা সমস্যার ধরণ। এটি নিম্নলিখিত কাজগুলি সম্পাদন করে:

  1. কোনও এন-কে কোনও ফাইলের জন্য কে বেছে নেওয়ার জন্য সমস্ত কে-সূচককে একটি দুর্দান্ত ফর্ম্যাটে আউটপুট দেয়। কে-সূচকগুলি আরও বর্ণনামূলক স্ট্রিং বা অক্ষর দ্বারা প্রতিস্থাপিত হতে পারে। এই পদ্ধতিটি এই ধরণের সমস্যা সমাধান করা বেশ তুচ্ছ করে তোলে।

  2. বাছাই করা দ্বিপদী সহগের সারণীতে প্রবেশের যথাযথ সূচকে কে-সূচকগুলিকে রূপান্তর করে। এই কৌশলটি পুরানো প্রকাশিত কৌশলগুলির চেয়ে অনেক দ্রুত যা পুনরাবৃত্তির উপর নির্ভর করে। এটি পাসকালের ত্রিভুজের অন্তর্নিহিত গাণিতিক সম্পত্তি ব্যবহার করে এটি করে। আমার কাগজ এই সম্পর্কে কথা বলে। আমি বিশ্বাস করি যে আমি এই কৌশলটি আবিষ্কার এবং প্রকাশিত প্রথম, তবে আমি ভুল হতে পারি।

  3. বাছাই করা দ্বিপদী সহগের সারণিতে সূচিটিকে সংশ্লিষ্ট কে-সূচকে রূপান্তর করে।

  4. দ্বিপদী সহগের গণনা করতে মার্ক ডোমিনাস পদ্ধতি ব্যবহার করে , যা উপচে পড়ার সম্ভাবনা অনেক কম এবং বৃহত সংখ্যার সাথে কাজ করে।

  5. ক্লাসটি .NET C # তে লিখিত আছে এবং জেনেরিক তালিকা ব্যবহার করে সমস্যার সাথে সম্পর্কিত (যদি থাকে) সম্পর্কিত বিষয়গুলি পরিচালনা করার একটি উপায় সরবরাহ করে। এই শ্রেণীর নির্মাতা ইনিটিবেল নামে একটি মূল মূল্য গ্রহণ করে যা সত্য হয়ে গেলে অবজেক্টগুলি পরিচালনা করার জন্য একটি জেনেরিক তালিকা তৈরি করে। যদি এই মানটি মিথ্যা হয় তবে তা সারণী তৈরি করবে না। উপরোক্ত 4 টি পদ্ধতি সম্পাদনের জন্য সারণী তৈরি করার দরকার নেই। টেবিল অ্যাক্সেস করার জন্য অ্যাকসেসর পদ্ধতি সরবরাহ করা হয়।

  6. একটি সম্পর্কিত পরীক্ষা ক্লাস রয়েছে যা ক্লাস এবং এর পদ্ধতিগুলি কীভাবে ব্যবহার করতে হয় তা দেখায়। এটি 2 টি ক্ষেত্রে ব্যাপকভাবে পরীক্ষা করা হয়েছে এবং কোনও ত্রুটি নেই।

এবং এই শ্রেণীর সম্পর্কে পড়তে কোড ডাউনলোড করতে, দেখতে Tablizing দ্য বাইনমিয়াল Coeffieicent

এই শ্রেণিটি সি ++ এ রূপান্তর করা কঠিন হবে না।


এটিকে "মার্ক ডোমিনাস পদ্ধতি" বলা সত্য নয়, কারণ আমি যেমনটি উল্লেখ করেছি যে এটি কমপক্ষে 850 বছর পুরানো, এবং এটি ভাবাও এতটা কঠিন নয়। এটাকে কেন লীলাবতী পদ্ধতি বলছেন না ?
এমজেডি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.