একটি স্ট্রিংয়ের সমস্ত সম্ভাব্য ক্রমের তালিকা তৈরি করুন


159

দৈর্ঘ্যে x এবং y অক্ষরের মধ্যে একটি স্ট্রিংয়ের সমস্ত সম্ভাব্য ক্রমের তালিকা তৈরি করতে গিয়ে কীভাবে অক্ষরের একটি চলক তালিকা থাকবে।

যে কোনও ভাষা কাজ করবে তবে এটি পোর্টেবল হতে হবে।


উত্তর:


70

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

কিছু সিউডোকোড:

list = originalString.split('')
index = (0,0)
list = [""]
for iteration n in 1 to y:
  index = (index[1], len(list))
  for string s in list.subset(index[0] to end):
    for character c in originalString:
      list.add(s + c)

এরপরে আপনাকে x এর চেয়ে কম দৈর্ঘ্যের সমস্ত স্ট্রিং সরিয়ে ফেলতে হবে, সেগুলি তালিকার প্রথম (x-1) * লেন (মূল স্ট্রিং) এন্ট্রি হবে।


4
প্রথমে উপাদানগুলির তালিকা কেন সংরক্ষণ করুন এবং তারপরে এটি পরিষ্কার করবেন? (সিউডোকোডে 1 এবং 3 লাইন উল্লেখ করে)।
হাভার্ড গিথাস

6
ওয়াই (লাইন 4) কী?
জেসিম

7
@ জাসিম প্রশ্ন থেকে: "x এবং y বর্ণের দৈর্ঘ্যের মধ্যে স্ট্রিংয়ের সমস্ত সম্ভাব্য ক্রম "
সি কে_

39

ব্যাকট্র্যাকিং ব্যবহার করা ভাল

#include <stdio.h>
#include <string.h>

void swap(char *a, char *b) {
    char temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

void print(char *a, int i, int n) {
    int j;
    if(i == n) {
        printf("%s\n", a);
    } else {
        for(j = i; j <= n; j++) {
            swap(a + i, a + j);
            print(a, i + 1, n);
            swap(a + i, a + j);
        }
    }
}

int main(void) {
    char a[100];
    gets(a);
    print(a, 0, strlen(a) - 1);
    return 0;
}

3
সেরা সমাধান চিরকালের জন্য
4-6 এ গ্রোয়ম্যানম্যান

25

আপনি প্রচুর স্ট্রিং পাচ্ছেন, এটি অবশ্যই ...

\ Sum_ {আমি = এক্স} ^ Y {অর্থাত \ frac {R!} {{(RI)}!}}
যেখানে x এবং y আপনি কীভাবে সেগুলি সংজ্ঞায়িত করেন এবং r হল হ'ল আমরা যে অক্ষরগুলি নির্বাচন করছি তা হল - যদি আমি আপনাকে সঠিকভাবে বুঝতে পারি। আপনার অবশ্যই এটি প্রয়োজনীয় হিসাবে উত্পন্ন করা উচিত এবং opালু না হয়ে বলুন, একটি পাওয়ারসেট তৈরি করুন এবং তারের দৈর্ঘ্য ফিল্টার করুন।

নিম্নলিখিতগুলি অবশ্যই উত্পন্ন করার সর্বোত্তম উপায় নয়, তবে এটি একটি আকর্ষণীয় দিক বাদে, কম নয়।

নথ (ভলিউম 4, ফ্যাসিকাল 2, 7.2.1.3) আমাদের বলে যে (গুলি, টি) -কোবিনেশনটি পুনরাবৃত্তির সাথে এক সাথে নেওয়া টি + 1 জিনিসগুলির সমতুল্য - একটি (গুলি, টি) - সংমিশ্রণ দ্বারা চিহ্নিতকরণ দ্বারা চিহ্নিত করা হয় নথ যা সমান {t \ + s + t \ চয়ন করুন। আমরা প্রথমে প্রতিটি (গুলি, টি) -বাইনারি আকারে সংমিশ্রণ তৈরি করে (সুতরাং, দৈর্ঘ্যের (গুলি + টি)) এবং প্রতিটি 1 এর বামে 0 এর সংখ্যা গণনা করে এটি নির্ধারণ করতে পারি।

10001000011101 -> অনুগতিতে পরিণত হয়: {0, 3, 4, 4, 4, 1}


15

নথ, পাইথনের উদাহরণ অনুসারে অপরিবর্তিত সমাধান:

def nextPermutation(perm):
    k0 = None
    for i in range(len(perm)-1):
        if perm[i]<perm[i+1]:
            k0=i
    if k0 == None:
        return None

    l0 = k0+1
    for i in range(k0+1, len(perm)):
        if perm[k0] < perm[i]:
            l0 = i

    perm[k0], perm[l0] = perm[l0], perm[k0]
    perm[k0+1:] = reversed(perm[k0+1:])
    return perm

perm=list("12345")
while perm:
    print perm
    perm = nextPermutation(perm)

2
আসলে, স্ট্রিং বাছাই না করা অবস্থায় এটি কাজ করে না । যদি আপনি "54321"কেবল একটি স্ট্রিং দিয়ে চেষ্টা করেন তবে (নিজেই) প্রদর্শিত হবে।
টনজো

1
মজার বিষয়টি nextPermutation()হ'ল রাজ্যহীন - এটি কেবলমাত্র ইনপুট গ্রহণ করতে দেয় এবং সূচিগুলি পুনরাবৃত্তি থেকে পুনরাবৃত্তিতে রক্ষণ করা হয় না। প্রাথমিক ইনপুটটি বাছাই করা হয়েছিল এবং অর্ডারিংটি কোথায় বজায় থাকে তার উপর ভিত্তি করে সূচীগুলি ( k0এবং l0) নিজেই সন্ধান করে তা ধরে নিয়ে এটি সক্ষম হয় । "54321" -> "12345" - এর মতো একটি ইনপুট সাজানোর ফলে এই অ্যালগরিদমটি প্রত্যাশিত সমস্ত অনুমতিটি সন্ধান করতে পারে। তবে যেহেতু এটি উত্পন্ন প্রতিটি ক্রমের জন্য সেই সূচকগুলি পুনরায় খুঁজে পেতে অতিরিক্ত পরিমাণে কাজ করে, তাই এটি পুনরাবৃত্তির সাথে আরও কার্যকর করার উপায় রয়েছে।
spaaarky21

13

আপনি " দক্ষতার সাথে একটি সেটের সাবসেটগুলি গণনা করতে দেখবেন সাবসেটগুলি , যা আপনি যা চান তার অংশটি করতে একটি অ্যালগরিদমকে বর্ণনা করে - দ্রুত দৈর্ঘ্য x থেকে y এর মধ্যে এন অক্ষরের সমস্ত উপসেটটি দ্রুত তৈরি করে। এটি সি তে একটি বাস্তবায়ন রয়েছে

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


13

সার্পের উত্তরের ভিত্তিতে কিছু কাজ করা জাভা কোড :

public class permute {

    static void permute(int level, String permuted,
                    boolean used[], String original) {
        int length = original.length();
        if (level == length) {
            System.out.println(permuted);
        } else {
            for (int i = 0; i < length; i++) {
                if (!used[i]) {
                    used[i] = true;
                    permute(level + 1, permuted + original.charAt(i),
                       used, original);
                    used[i] = false;
                }
            }
        }
    }

    public static void main(String[] args) {
        String s = "hello";
        boolean used[] = {false, false, false, false, false};
        permute(0, "", used, s);
    }
}

একটি মন্তব্য হিসাবে, নোট করুন যে পুনরাবৃত্ত অক্ষরগুলির সাথে একটি স্ট্রিংয়ের জন্য এটি অনন্য অনুমানের উত্পাদন করবে না। এটি একটি হ্যাশ দিয়ে সমাধান করা যেতে পারে, তবে এটি দীর্ঘ স্ট্রিংগুলির সাথে সমস্যা হতে পারে।
গ্লেন

8
এই রানটি আরও দ্রুততর করার জন্য আপনি স্ট্রিংয়ের পরিবর্তে চর অ্যারে ব্যবহার করতে চান যেহেতু জাভাতে স্ট্রিংগুলি অবিচ্ছেদ্য।
অভিজিৎ কাশনিয়া

13

এখানে সি # তে একটি সহজ সমাধান।

এটি একটি প্রদত্ত স্ট্রিংয়ের কেবল আলাদা স্বতন্ত্র অনুমতি দেয়।

    static public IEnumerable<string> permute(string word)
    {
        if (word.Length > 1)
        {

            char character = word[0];
            foreach (string subPermute in permute(word.Substring(1)))
            {

                for (int index = 0; index <= subPermute.Length; index++)
                {
                    string pre = subPermute.Substring(0, index);
                    string post = subPermute.Substring(index);

                    if (post.Contains(character))
                            continue;                       

                    yield return pre + character + post;
                }

            }
        }
        else
        {
            yield return word;
        }
    }

12

এখানে অনেক ভাল উত্তর আছে। আমি সি ++ তে খুব সাধারণ পুনরাবৃত্ত সমাধান সমাধানের পরামর্শ দিই।

#include <string>
#include <iostream>

template<typename Consume>
void permutations(std::string s, Consume consume, std::size_t start = 0) {
    if (start == s.length()) consume(s);
    for (std::size_t i = start; i < s.length(); i++) {
        std::swap(s[start], s[i]);
        permutations(s, consume, start + 1);
    }
}

int main(void) {
    std::string s = "abcd";
    permutations(s, [](std::string s) {
        std::cout << s << std::endl;
    });
}

দ্রষ্টব্য : পুনরাবৃত্ত অক্ষরগুলির সাথে থাকা স্ট্রিংগুলি অনন্য অনুমানের উত্পাদন করে না।


9

আমি রুবিতে এটি দ্রুত বেত্রাঘাত করেছি:

def perms(x, y, possible_characters)
  all = [""]
  current_array = all.clone
  1.upto(y) { |iteration|
    next_array = []
    current_array.each { |string|
      possible_characters.each { |c|
        value = string + c
        next_array.insert next_array.length, value
        all.insert all.length, value
      }
    }
    current_array = next_array
  }
  all.delete_if { |string| string.length < x }
end

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

যাইহোক, কোডের পিছনে ধারণাটি 0 দৈর্ঘ্যের স্ট্রিং দিয়ে শুরু হয়, তারপরে লম্বা Z এর সমস্ত স্ট্রিংয়ের ট্র্যাক রাখুন যেখানে Z পুনরাবৃত্তির বর্তমান আকার। তারপরে, প্রতিটি স্ট্রিংয়ের মধ্য দিয়ে যান এবং প্রতিটি অক্ষরে প্রতিটি অক্ষর যুক্ত করুন। শেষ অবধি, এক্স থ্রেশহোল্ডের নীচে থাকা যে কোনওটিকে সরিয়ে ফেলুন এবং ফলাফলটি ফিরিয়ে দিন।

আমি এটি সম্ভাব্য অর্থহীন ইনপুট (নাল অক্ষর তালিকা, এক্স এবং y এর অদ্ভুত মান ইত্যাদি) দিয়ে পরীক্ষা করিনি।


11
এই কোডটি ভুল। এটি অকার্যকর অনুমতিগুলি তৈরি করবে, যেমন পুনরাবৃত্ত অক্ষরগুলির সাথে। উদাহরণস্বরূপ, "এবিসি" স্ট্রিংয়ের জন্য, এটি আকার 3 এর এই অনুমতিগুলি উত্পন্ন করে: ["আআআএ", "আব", "আ্যাক", "আবা", "অ্যাবি", "এবিসি", "এসিএ", "এসিবি", "এ্যাক", "বা", "বাব", "ব্যাক", "বিবিএ", "বিবিবি", "বিবিসি", "বিসিএ", "বিসিবি", "বিসিসি", "সিএএ", "ক্যাব", "স্যাক "," সিবিএ "," সিবিবি "," সিবিসি "," সিসিএ "," সিসিবি "," সিসিসি "]। এটি ভুল।
pmc255

8

এটি মাইকের রুবি সংস্করণের অনুবাদ, কমন লিস্পে:

(defun perms (x y original-string)
  (loop with all = (list "")
        with current-array = (list "")
        for iteration from 1 to y
        do (loop with next-array = nil
                 for string in current-array
                 do (loop for c across original-string
                          for value = (concatenate 'string string (string c))
                          do (push value next-array)
                             (push value all))
                    (setf current-array (reverse next-array)))
        finally (return (nreverse (delete-if #'(lambda (el) (< (length el) x)) all)))))

এবং অন্য সংস্করণ, সামান্য খাটো এবং আরও লুপ সুবিধার বৈশিষ্ট্য ব্যবহার করে:

(defun perms (x y original-string)
  (loop repeat y
        collect (loop for string in (or (car (last sets)) (list ""))
                      append (loop for c across original-string
                                   collect (concatenate 'string string (string c)))) into sets
        finally (return (loop for set in sets
                              append (loop for el in set when (>= (length el) x) collect el)))))

8

এখানে একটি সাধারণ শব্দ সি # রিকারসিভ সমাধান:

পদ্ধতি:

public ArrayList CalculateWordPermutations(string[] letters, ArrayList words, int index)
        {
            bool finished = true;
            ArrayList newWords = new ArrayList();
            if (words.Count == 0)
            {
                foreach (string letter in letters)
                {
                    words.Add(letter);
                }
            }

            for(int j=index; j<words.Count; j++)
            {
                string word = (string)words[j];
                for(int i =0; i<letters.Length; i++)
                {
                    if(!word.Contains(letters[i]))
                    {
                        finished = false;
                        string newWord = (string)word.Clone();
                        newWord += letters[i];
                        newWords.Add(newWord);
                    }
                }
            }

            foreach (string newWord in newWords)
            {   
                words.Add(newWord);
            }

            if(finished  == false)
            {
                CalculateWordPermutations(letters, words, words.Count - newWords.Count);
            }
            return words;
        }

কল করা হচ্ছে:

string[] letters = new string[]{"a","b","c"};
ArrayList words = CalculateWordPermutations(letters, new ArrayList(), 0);

8

... এবং এখানে সি সংস্করণটি রয়েছে:

void permute(const char *s, char *out, int *used, int len, int lev)
{
    if (len == lev) {
        out[lev] = '\0';
        puts(out);
        return;
    }

    int i;
    for (i = 0; i < len; ++i) {
        if (! used[i])
            continue;

        used[i] = 1;
        out[lev] = s[i];
        permute(s, out, used, len, lev + 1);
        used[i] = 0;
    }
    return;
}

8

পারমিট (এবিসি) -> এপির্ম (বিসি) -> এপির্ম [বিপিআরএম (সি)] -> এপির্ম [( * বি সি), (সি বি * )] -> [( * এ বিসি ), (বি সি), (বিসি এ * ), ( * এ সিবি), (সি বি), (সিবি এ * )] প্রতিটি বর্ণমালা সন্নিবেশ করানোর সময় সদৃশগুলি মুছে ফেলার জন্য পূর্ববর্তী স্ট্রিং একই বর্ণমালা দিয়ে শেষ হয় কিনা তা পরীক্ষা করে দেখুন (কেন? - অনুশীলন)

public static void main(String[] args) {

    for (String str : permStr("ABBB")){
        System.out.println(str);
    }
}

static Vector<String> permStr(String str){

    if (str.length() == 1){
        Vector<String> ret = new Vector<String>();
        ret.add(str);
        return ret;
    }

    char start = str.charAt(0);
    Vector<String> endStrs = permStr(str.substring(1));
    Vector<String> newEndStrs = new Vector<String>();
    for (String endStr : endStrs){
        for (int j = 0; j <= endStr.length(); j++){
            if (endStr.substring(0, j).endsWith(String.valueOf(start)))
                break;
            newEndStrs.add(endStr.substring(0, j) + String.valueOf(start) + endStr.substring(j));
        }
    }
    return newEndStrs;
}

সমস্ত অনুমতি সংকলন ডুপ্লিকেট মুদ্রণ


8

সি ++ এ পুনরাবৃত্ত সমাধান

int main (int argc, char * const argv[]) {
        string s = "sarp";
        bool used [4];
        permute(0, "", used, s);
}

void permute(int level, string permuted, bool used [], string &original) {
    int length = original.length();

    if(level == length) { // permutation complete, display
        cout << permuted << endl;
    } else {
        for(int i=0; i<length; i++) { // try to add an unused character
            if(!used[i]) {
                used[i] = true;
                permute(level+1, original[i] + permuted, used, original); // find the permutations starting with this string
                used[i] = false;
            }
        }
}

7

পার্লে, আপনি যদি নিজেকে ছোট হাতের বর্ণমালায় সীমাবদ্ধ রাখতে চান তবে আপনি এটি করতে পারেন:

my @result = ("a" .. "zzzz");

এটি ছোট হাতের অক্ষর ব্যবহার করে 1 এবং 4 টি অক্ষরের মধ্যে সমস্ত সম্ভাব্য স্ট্রিং দেয়। বড় হাতের, পরিবর্তন জন্য "a"করতে "A"এবং "zzzz"করতে"ZZZZ"

মিশ্র ক্ষেত্রে ক্ষেত্রে এটি আরও শক্ত হয়ে যায়, এবং পার্লের কোনও বিল্টিন অপারেটরের সাথে সম্ভবত এটি সম্ভব নয়।


7

রুবি উত্তর যে কাজ করে:

class String
  def each_char_with_index
    0.upto(size - 1) do |index|
      yield(self[index..index], index)
    end
  end
  def remove_char_at(index)
    return self[1..-1] if index == 0
    self[0..(index-1)] + self[(index+1)..-1]
  end
end

def permute(str, prefix = '')
  if str.size == 0
    puts prefix
    return
  end
  str.each_char_with_index do |char, index|
    permute(str.remove_char_at(index), prefix + char)
  end
end

# example
# permute("abc")

: রুবি একটি অভিনব এক মাছ ধরার নৌকা জন্য stackoverflow.com/questions/5773961/...
dojosto

6
import java.util.*;

public class all_subsets {
    public static void main(String[] args) {
        String a = "abcd";
        for(String s: all_perm(a)) {
            System.out.println(s);
        }
    }

    public static Set<String> concat(String c, Set<String> lst) {
        HashSet<String> ret_set = new HashSet<String>();
        for(String s: lst) {
            ret_set.add(c+s);
        }
        return ret_set;
    }

    public static HashSet<String> all_perm(String a) {
        HashSet<String> set = new HashSet<String>();
        if(a.length() == 1) {
            set.add(a);
        } else {
            for(int i=0; i<a.length(); i++) {
                set.addAll(concat(a.charAt(i)+"", all_perm(a.substring(0, i)+a.substring(i+1, a.length()))));
            }
        }
        return set;
    }
}

6

নিম্নলিখিত জাভা পুনরাবৃত্তি একটি প্রদত্ত স্ট্রিংয়ের সমস্ত অনুমতি মুদ্রণ করে:

//call it as permut("",str);

public void permut(String str1,String str2){
    if(str2.length() != 0){
        char ch = str2.charAt(0);
        for(int i = 0; i <= str1.length();i++)
            permut(str1.substring(0,i) + ch + str1.substring(i,str1.length()),
                     str2.substring(1,str2.length()));
    }else{
    System.out.println(str1);
    }
}

নীচে উপরের "পারমুট" পদ্ধতির আপডেট হওয়া সংস্করণ যা এন করে! (এন ফ্যাকটোরিয়াল) উপরের পদ্ধতির তুলনায় কম পুনরাবৃত্তি কল

//call it as permut("",str);

public void permut(String str1,String str2){
   if(str2.length() > 1){
       char ch = str2.charAt(0);
       for(int i = 0; i <= str1.length();i++)
          permut(str1.substring(0,i) + ch + str1.substring(i,str1.length()),
                 str2.substring(1,str2.length()));
   }else{
    char ch = str2.charAt(0);
    for(int i = 0; i <= str1.length();i++)
        System.out.println(str1.substring(0,i) + ch +    str1.substring(i,str1.length()),
                 str2.substring(1,str2.length()));
   }
}

এটিই সবচেয়ে পরিষ্কার সমাধান, এবং আমি বিশ্বাস করি আমি "কোডিং সাক্ষাত্কার ক্র্যাকিং" বইতে এর আগে দেখেছি
তাও ঝাং

1
@ টাওজ্যাং এর পরিপূরকটির জন্য ধন্যবাদ, আমি এটিকে অন্য কোথাও থেকে অনুলিপি করিনি তবে এটি সম্ভব যে কেউ একই রকম আলগো তৈরি করেছেন। যাইহোক আমি কম পুনরাবৃত্ত কলগুলির জন্য উপরের কোডটি আপডেট করেছি
রামি

5

আপনি কেন প্রথম স্থানে এটি করতে চাইবেন তা আমি নিশ্চিত নই। X এবং y এর যে কোনও মাঝারি আকারের বৃহত মানগুলির জন্য ফলাফলটি বিশাল হবে এবং এক্স এবং / বা y বড় হওয়ার সাথে সাথে তা তাত্পর্যপূর্ণভাবে বৃদ্ধি পাবে।

আপনার সম্ভাব্য অক্ষরের সেটটি বর্ণমালার 26 টি ছোট হাতের অক্ষর এবং আপনি আপনার অ্যাপ্লিকেশনটিকে এমন সমস্ত বিভাজন তৈরি করতে বলুন যেখানে দৈর্ঘ্য = 5 মনে করে আপনি স্মৃতিশক্তি শেষ না হয়ে ধরেছেন 11,881,376 (অর্থাত্ 26 টি পাওয়ার) 5) স্ট্রিং ফিরে। এই দৈর্ঘ্যটি 6 টি পর্যন্ত টানুন এবং আপনি 308,915,776 স্ট্রিং ফিরে পাবেন। এই সংখ্যাগুলি খুব দ্রুত বেদনাদায়কভাবে বড় হয়।

আমি জাভাতে একসাথে রেখেছি এমন একটি সমাধান এখানে। আপনাকে দুটি রানটাইম আর্গুমেন্ট সরবরাহ করতে হবে (x এবং y এর সাথে সম্পর্কিত)। আনন্দ কর.

public class GeneratePermutations {
    public static void main(String[] args) {
        int lower = Integer.parseInt(args[0]);
        int upper = Integer.parseInt(args[1]);

        if (upper < lower || upper == 0 || lower == 0) {
            System.exit(0);
        }

        for (int length = lower; length <= upper; length++) {
            generate(length, "");
        }
    }

    private static void generate(int length, String partial) {
        if (length <= 0) {
            System.out.println(partial);
        } else {
            for (char c = 'a'; c <= 'z'; c++) {
                generate(length - 1, partial + c);
            }
        }
    }
}

দীর্ঘ সময় তবে আপনি কি তাদের পুনরাবৃত্তি দিয়ে উত্পাদন করছেন না?
কাকিরা

5

জাভাস্ক্রিপ্টে আমি এখানে এসেছি এমন একটি পুনরাবৃত্ত সংস্করণ। এটি উপরে কাঠের নন-রিকার্সিভের উপর ভিত্তি করে তৈরি নয়, যদিও এর অ্যালিমেট অদলবদলের কিছু মিল রয়েছে। আমি 8 টি পর্যন্ত উপাদানগুলির ইনপুট অ্যারেগুলির জন্য এর সঠিকতা যাচাই করেছি।

একটি দ্রুত অপ্টিমাইজেশান প্রাক-উড়ন্ত হবে out অ্যারের এবং এড়ানো হবেpush()

মূল ধারণাটি হ'ল:

  1. একটি একক উত্স অ্যারে দেওয়া, অ্যারেগুলির একটি নতুন নতুন সেট তৈরি করুন যা প্রতিটি পরবর্তী উপাদানগুলির সাথে ঘুরে ফিরে প্রথম উপাদানটিকে অদলবদল করে, এবং অন্যান্য উপাদানগুলিকে নিরবিচ্ছিন্ন রেখে দেয়। উদাহরণস্বরূপ: প্রদত্ত 1234, 1234, 2134, 3214, 4231 উত্পন্ন করুন।

  2. আগের পাস থেকে প্রতিটি অ্যারে নতুন পাসের জন্য বীজ হিসাবে ব্যবহার করুন, তবে প্রথম উপাদানটি অদলবদলের পরিবর্তে পরবর্তী উপাদানগুলির সাথে দ্বিতীয় উপাদানটি অদলবদল করুন। এছাড়াও, এবার আউটপুটে আসল অ্যারেটি অন্তর্ভুক্ত করবেন না।

  3. সম্পন্ন না হওয়া পর্যন্ত ধাপ 2 পুনরাবৃত্তি করুন।

কোড নমুনা এখানে:

function oxe_perm(src, depth, index)
{
    var perm = src.slice();     // duplicates src.
    perm = perm.split("");
    perm[depth] = src[index];
    perm[index] = src[depth];
    perm = perm.join("");
    return perm;
}

function oxe_permutations(src)
{
    out = new Array();

    out.push(src);

    for (depth = 0; depth < src.length; depth++) {
        var numInPreviousPass = out.length;
        for (var m = 0; m < numInPreviousPass; ++m) {
            for (var n = depth + 1; n < src.length; ++n) {
                out.push(oxe_perm(out[m], depth, n));
            }
        }
    }

    return out;
}

3

রুবিতে:

str = "a"
100_000_000.times {puts str.next!}

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

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

আপনার সমস্যাটি এর সাথে কিছুটা মিল: http://beust.com/weblog/archives/000491.html (সমস্ত সংখ্যার তালিকা করুন যাতে কোনও অঙ্কই নিজেকে পুনরাবৃত্তি করে না, যার ফলে এটি পুরো অনেকগুলি ভাষা সমাধান করে, অ্যাক্যামল লোক ক্রমিটেশন ব্যবহার করছে এবং কিছু জাভা লোক এখনও অন্য সমাধান ব্যবহার করছে)।


আপনার প্রস্তাব সঙ্গে একটি সমস্যা যে str.next! সমস্ত মুদ্রণযোগ্য অক্ষর পুনরাবৃত্তি হবে না। আপনার উদাহরণটি কেবল ছোট হাতের অক্ষর তৈরি করবে - কোনও বিরামচিহ্ন বা বড় অক্ষর।
জারসেন

3

আমার আজ এটির প্রয়োজন ছিল এবং যদিও ইতিমধ্যে দেওয়া উত্তরগুলি আমাকে সঠিক দিকে নির্দেশ করেছে, তারা আমার যা ইচ্ছা তা ছিল না।

হিপের পদ্ধতি ব্যবহার করে এখানে একটি বাস্তবায়ন দেওয়া হয়েছে। অ্যারেটির দৈর্ঘ্য কমপক্ষে 3 হওয়া উচিত এবং ব্যবহারিক বিবেচনার জন্য 10 বা তার বেশি হওয়া উচিত নয়, আপনি যা করতে চান তার উপর নির্ভর করে ধৈর্য এবং ঘড়ির গতি।

আপনি নিজের লুপটি প্রবেশ করার আগে, Perm(1 To N)প্রথম শৃঙ্খলা Stack(3 To N)দিয়ে শূন্য * এবং ** Levelদিয়ে শুরু করুন 2initial লুপ কল শেষেNextPerm , যা মিথ্যা ফিরে আসবে।

* ভিবি আপনার জন্য এটি করবে।

** এটিকে অপ্রয়োজনীয় করার জন্য আপনি নেক্সটপার্মকে কিছুটা পরিবর্তন করতে পারেন, তবে এটি এর মতো পরিষ্কার।

Option Explicit

Function NextPerm(Perm() As Long, Stack() As Long, Level As Long) As Boolean
Dim N As Long
If Level = 2 Then
    Swap Perm(1), Perm(2)
    Level = 3
Else
    While Stack(Level) = Level - 1
        Stack(Level) = 0
        If Level = UBound(Stack) Then Exit Function
        Level = Level + 1
    Wend
    Stack(Level) = Stack(Level) + 1
    If Level And 1 Then N = 1 Else N = Stack(Level)
    Swap Perm(N), Perm(Level)
    Level = 2
End If
NextPerm = True
End Function

Sub Swap(A As Long, B As Long)
A = A Xor B
B = A Xor B
A = A Xor B
End Sub

'This is just for testing.
Private Sub Form_Paint()
Const Max = 8
Dim A(1 To Max) As Long, I As Long
Dim S(3 To Max) As Long, J As Long
Dim Test As New Collection, T As String
For I = 1 To UBound(A)
    A(I) = I
Next
Cls
ScaleLeft = 0
J = 2
Do
    If CurrentY + TextHeight("0") > ScaleHeight Then
        ScaleLeft = ScaleLeft - TextWidth(" 0 ") * (UBound(A) + 1)
        CurrentY = 0
        CurrentX = 0
    End If
    T = vbNullString
    For I = 1 To UBound(A)
        Print A(I);
        T = T & Hex(A(I))
    Next
    Print
    Test.Add Null, T
Loop While NextPerm(A, S, J)
J = 1
For I = 2 To UBound(A)
    J = J * I
Next
If J <> Test.Count Then Stop
End Sub

অন্যান্য পদ্ধতি বিভিন্ন লেখক বর্ণনা করেছেন। নুথ দুটি বর্ণনা করেছেন, একটি লেবেসিক অর্ডার দেয় তবে জটিল এবং ধীর, অন্যটি সরল পরিবর্তনের পদ্ধতি হিসাবে পরিচিত। জি গাও এবং ডায়ানজান ওয়াং একটি আকর্ষণীয় কাগজও লিখেছিলেন।


2

পাইথনের এই কোডটি allowed_charactersসেট [0,1]ও 4 ক্যারেক্টার সর্বাধিক সহ কল ​​করা হলে 2 ^ 4 ফলাফল উত্পন্ন করতে পারে:

['0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111', '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111']

def generate_permutations(chars = 4) :

#modify if in need!
    allowed_chars = [
        '0',
        '1',
    ]

    status = []
    for tmp in range(chars) :
        status.append(0)

    last_char = len(allowed_chars)

    rows = []
    for x in xrange(last_char ** chars) :
        rows.append("")
        for y in range(chars - 1 , -1, -1) :
            key = status[y]
            rows[x] = allowed_chars[key] + rows[x]

        for pos in range(chars - 1, -1, -1) :
            if(status[pos] == last_char - 1) :
                status[pos] = 0
            else :
                status[pos] += 1
                break;

    return rows

import sys


print generate_permutations()

আশা করি এটি আপনার কাজে আসবে। যে কোনও চরিত্রের সাথে কাজ করে, কেবল সংখ্যা নয়


এটি অনুমতি ছাড়াই নয় বরং সাবসেট নির্বাচন, যেমন এবিসি এবং 001 = সি, যখন একটি বৈধ অনুমানের তিনটি অক্ষর থাকতে হবে।
Schultz9999

আহ? দুঃখিত আপনি কি বলেন তা আমি বুঝতে পারছি না। আপনি যদি এটির স্থির সংস্করণটি স্থির করেন তবে আমি
উইকিটিকে


0

যদিও এটি আপনার প্রশ্নের সঠিক উত্তর দেয় না, একই দৈর্ঘ্যের কয়েকটি স্ট্রিং থেকে চিঠিগুলির প্রতিটি ক্রমান্বয়ে উত্পন্ন করার একটি উপায় এখানে: উদাহরণস্বরূপ, যদি আপনার শব্দগুলি "কফি", "জুমলা" এবং "মুডল" থাকে তবে আপনি করতে পারেন "কুডল", "joodee", "joffle", ইত্যাদি মত আউটপুট আশা

মূলত, সংমিশ্রণের সংখ্যা হ'ল (শব্দের সংখ্যা) এর পাওয়ার (প্রতি শব্দের অক্ষরের সংখ্যা)। সুতরাং, 0 এবং সংমিশ্রণের সংখ্যার মধ্যে একটি এলোমেলো সংখ্যা চয়ন করুন - 1, সেই সংখ্যাটিকে বেস (শব্দের সংখ্যা) এ রূপান্তর করুন, তারপরে সেই সংখ্যার প্রতিটি অঙ্কটি নির্দেশক হিসাবে ব্যবহার করুন যা পরবর্তী শব্দের থেকে পরবর্তী বর্ণটি গ্রহণ করবে।

যেমন: উপরের উদাহরণে। 3 শব্দ, 6 অক্ষর = 729 সংমিশ্রণ। একটি এলোমেলো সংখ্যা চয়ন করুন: 465. বেস 3 তে রূপান্তর করুন: 122020. শব্দ 1 এর প্রথম অক্ষরটি নিন, 2 য় শব্দ থেকে 2 য়, 2 র্থ শব্দ থেকে 2 র্থ, 0 শব্দ থেকে ... এবং আপনি পাবেন ... "জওফেল"।

আপনি যদি সমস্ত অনুমতি চান, কেবল 0 থেকে 728 পর্যন্ত লুপ করুন course অবশ্যই, আপনি যদি কেবল একটি এলোমেলো মান বেছে নিচ্ছেন তবে অক্ষরের উপর লুপ করা অনেক সহজ কম বিভ্রান্তিকর উপায়। এই পদ্ধতিটি আপনাকে পুনরাবৃত্তি এড়াতে দেয়, আপনার যদি সমস্ত অনুমোদন চান তবে প্লাস এটি আপনাকে ম্যাথস (টিএম) জানার মতো দেখায় !

সংমিশ্রণের সংখ্যা যদি অতিরিক্ত হয় তবে আপনি এটিকে ছোট ছোট শব্দের একটি ধারা হিসাবে বিভক্ত করতে পারেন এবং শেষে তাদের সাথে সংলগ্ন করতে পারেন।


0

সি # পুনরাবৃত্তি:

public List<string> Permutations(char[] chars)
    {
        List<string> words = new List<string>();
        words.Add(chars[0].ToString());
        for (int i = 1; i < chars.Length; ++i)
        {
            int currLen = words.Count;
            for (int j = 0; j < currLen; ++j)
            {
                var w = words[j];
                for (int k = 0; k <= w.Length; ++k)
                {
                    var nstr = w.Insert(k, chars[i].ToString());
                    if (k == 0)
                        words[j] = nstr;
                    else
                        words.Add(nstr);
                }
            }
        }
        return words;
    }

0
def gen( x,y,list): #to generate all strings inserting y at different positions
list = []
list.append( y+x )
for i in range( len(x) ):
    list.append( func(x,0,i) + y + func(x,i+1,len(x)-1) )
return list 

def func( x,i,j ): #returns x[i..j]
z = '' 
for i in range(i,j+1):
    z = z+x[i]
return z 

def perm( x , length , list ): #perm function
if length == 1 : # base case
    list.append( x[len(x)-1] )
    return list 
else:
    lists = perm( x , length-1 ,list )
    lists_temp = lists #temporarily storing the list 
    lists = []
    for i in range( len(lists_temp) ) :
        list_temp = gen(lists_temp[i],x[length-2],lists)
        lists += list_temp 
    return lists

0
def permutation(str)
  posibilities = []
  str.split('').each do |char|
    if posibilities.size == 0
      posibilities[0] = char.downcase
      posibilities[1] = char.upcase
    else
      posibilities_count = posibilities.length
      posibilities = posibilities + posibilities
      posibilities_count.times do |i|
        posibilities[i] += char.downcase
        posibilities[i+posibilities_count] += char.upcase
      end
    end
  end
  posibilities
end

এখানে আমার পুনরাবৃত্তিমূলক সংস্করণ নেওয়া আছে



0

ঠিক আছে এখানে একটি মার্জিত, পুনরাবৃত্তিযোগ্য, ও (এন!) সমাধান:

public static StringBuilder[] permutations(String s) {
        if (s.length() == 0)
            return null;
        int length = fact(s.length());
        StringBuilder[] sb = new StringBuilder[length];
        for (int i = 0; i < length; i++) {
            sb[i] = new StringBuilder();
        }
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            int times = length / (i + 1);
            for (int j = 0; j < times; j++) {
                for (int k = 0; k < length / times; k++) {
                    sb[j * length / times + k].insert(k, ch);
                }
            }
        }
        return sb;
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.