जवाबों:
इसे करने बहुत सारे तरीके हैं। सामान्य विधियाँ पुनरावर्तन, संस्मरण या गतिशील प्रोग्रामिंग का उपयोग करती हैं। मूल विचार यह है कि आप लंबाई 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) * लेन (ओरिजिनल स्ट्रिंग) प्रविष्टियाँ होंगे।
बैकट्रैकिंग का उपयोग करना बेहतर है
#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;
}
आपको बहुत सारे तार मिलने जा रहे हैं, यह सुनिश्चित करने के लिए ...
जहाँ x और y यह है कि आप उन्हें कैसे परिभाषित करते हैं और r हम कितने अक्षर से चुन रहे हैं - यदि मैं आपको सही ढंग से समझ रहा हूँ। आपको निश्चित रूप से इन्हें उत्पन्न करना चाहिए और मैला नहीं होना चाहिए और कहना चाहिए, एक पावरसेट उत्पन्न करें और फिर स्ट्रिंग्स की लंबाई को फ़िल्टर करें।
निम्नलिखित निश्चित रूप से इन उत्पन्न करने का सबसे अच्छा तरीका नहीं है, लेकिन यह एक तरफ एक दिलचस्प है, कोई नहीं-कम।
नुथ (खंड 4, 2, 7.2.1.3) हमें बताता है कि (एस, टी) -कम्बिनेशन एस + 1 चीजों के बराबर है जो एक समय में दोहराव के साथ लिया जाता है - (ए, टी) -combination संकेतन का उपयोग किया जाता है नथ जो बराबर है । हम पहले बाइनरी रूप में प्रत्येक (एस, टी) -combination (इसलिए, लंबाई (एस + टी)) और प्रत्येक 1 के बाईं ओर 0 की संख्या की गिनती करके यह पता लगा सकते हैं।
10001000011101 -> क्रमचय बनता है: {0, 3, 4, 4, 4, 1}
नथ, पायथन उदाहरण के अनुसार गैर पुनरावर्ती समाधान:
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)
"54321"
केवल एक स्ट्रिंग के साथ कोशिश करते हैं (स्वयं) दिखाया गया है।
nextPermutation()
यह स्टेटलेस है - यह केवल इनपुट को क्रमबद्ध करने के लिए लेता है और अनुक्रमित पुनरावृति से पुनरावृत्ति में बनाए नहीं रखा जाता है। यह ऐसा मानकर आरंभ करने में सक्षम है कि प्रारंभिक इनपुट को क्रमबद्ध किया गया था और अनुक्रमणिका ( k0
और l0
) को खोजने के आधार पर, जहां ऑर्डर बनाए रखा गया है। "54321" -> "12345" जैसे इनपुट को छाँटने से इस एल्गोरिथम को सभी अपेक्षित क्रमपरिवर्तन खोजने में मदद मिलेगी। लेकिन चूंकि यह उन सभी अनुक्रमों के लिए उन अनुक्रमणिकाओं को फिर से खोजने के लिए अतिरिक्त काम करता है जो इसे उत्पन्न करते हैं, इस गैर-पुनरावृत्ति को करने के अधिक कुशल तरीके हैं।
आप देख सकते हैं " सेट के सबलेट्स को कुशलतापूर्वक एनुमरेट करना , जो एक एल्गोरिथ्म का वर्णन करता है कि आप क्या चाहते हैं - जल्दी से लंबाई x से y तक एन वर्णों के सभी सबसेट उत्पन्न करते हैं। इसमें C का कार्यान्वयन शामिल है।
प्रत्येक सबसेट के लिए, आपको अभी भी सभी क्रमचय उत्पन्न करने होंगे। उदाहरण के लिए यदि आप "abcde" से 3 वर्ण चाहते थे, तो यह एल्गोरिथ्म आपको "abc", "abd", "abe" देगा ... लेकिन आपको "acb", "bac" प्राप्त करने के लिए प्रत्येक को अनुमति देनी होगी, "बीका", आदि।
सर्प के उत्तर पर आधारित कुछ कार्य जावा कोड :
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);
}
}
यहाँ C # में एक सरल समाधान है।
यह किसी दिए गए स्ट्रिंग के केवल अलग-अलग क्रमांकन उत्पन्न करता है।
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;
}
}
यहाँ बहुत सारे अच्छे उत्तर हैं। मैं C ++ में एक बहुत ही सरल पुनरावर्ती समाधान भी सुझाता हूं।
#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;
});
}
नोट : बार-बार वर्णों के साथ तार अद्वितीय क्रमपरिवर्तन उत्पन्न नहीं करेंगे।
मैं सिर्फ रूबी में यह जल्दी मार पड़ी है:
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
आप क्रमपरिवर्तन प्रकार के कार्यों में निर्मित के लिए भाषा एपीआई में देख सकते हैं, और आप अधिक अनुकूलित कोड लिखने में सक्षम हो सकते हैं, लेकिन यदि संख्या सभी उच्च हैं, तो मुझे यकीन नहीं है कि बहुत सारे परिणाम होने के आसपास एक रास्ता है ।
वैसे भी, कोड के पीछे विचार लंबाई 0 के स्ट्रिंग के साथ शुरू होता है, फिर लंबाई Z के सभी तारों पर नज़र रखें जहां Z पुनरावृत्ति में वर्तमान आकार है। फिर, प्रत्येक स्ट्रिंग पर जाएं और प्रत्येक स्ट्रिंग पर प्रत्येक वर्ण को जोड़ दें। अंत में, एक्स थ्रेशोल्ड के नीचे से किसी को हटा दें और परिणाम वापस करें।
मैंने इसे संभावित अर्थहीन इनपुट (अशक्त चरित्र सूची, एक्स और वाई के अजीब मूल्यों आदि) के साथ परीक्षण नहीं किया।
यह कॉमन लिस्प में माइक के रूबी संस्करण का अनुवाद है:
(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)))))
यहाँ एक सरल शब्द है C # पुनरावर्ती समाधान:
तरीका:
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);
... और यहाँ C संस्करण है:
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;
}
परमिट (ABC) -> एपरम (BC) -> एपरम [B.perm (C)] -> एपरम [( * B C), (C B * )] -> [( * A BC ), (बी ए सी), (BC ए * ), ( * एक सीबी), (सी ए बी), (सीबी ए * )] डुप्लिकेट जब प्रत्येक वर्णमाला की जांच डालने को देखने के लिए दूर करने के लिए करता है, तो एक ही वर्णमाला के साथ पिछले स्ट्रिंग समाप्त होता है (क्यों? -सेक्स)
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;
}
सभी क्रमपरिवर्तन संट्स डुप्लिकेट प्रिंट करता है
C ++ में पुनरावर्ती समाधान
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;
}
}
}
पर्ल में, यदि आप अपने आप को निचली वर्णमाला तक सीमित रखना चाहते हैं, तो आप ऐसा कर सकते हैं:
my @result = ("a" .. "zzzz");
यह लोअरकेस वर्णों का उपयोग करके 1 और 4 वर्णों के बीच सभी संभावित तार देता है। अपरकेस के लिए, परिवर्तन "a"
करने के लिए"A"
और के "zzzz"
लिए"ZZZZ"
।
मिश्रित-मामले के लिए यह बहुत कठिन हो जाता है, और शायद पर्ल के बिलिन ऑपरेटरों में से एक के साथ ऐसा करने योग्य नहीं है।
रूबी का जवाब है कि काम करता है:
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")
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;
}
}
निम्नलिखित जावा पुनरावर्तन किसी दिए गए स्ट्रिंग के सभी क्रमांकन को प्रिंट करता है:
//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);
}
}
उपरोक्त "permut" विधि का अद्यतन संस्करण है जो n बनाता है! (n factorial) उपरोक्त विधि की तुलना में कम पुनरावर्ती कॉल
//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()));
}
}
मुझे यकीन नहीं है कि आप पहली बार में ऐसा क्यों करना चाहेंगे। एक्स और वाई के किसी भी बड़े बड़े मूल्यों के लिए परिणामी सेट बहुत बड़ा होगा, और एक्स और / या वाई के रूप में तेजी से बड़ा हो जाएगा।
कहते हैं कि आपके वर्णों का सेट संभव वर्णमाला के 26 लोअरकेस अक्षर हैं, और आप अपने आवेदन को उन सभी अनुमतियों को उत्पन्न करने के लिए कहते हैं जहां लंबाई = 5. मान लें कि आप स्मृति से बाहर नहीं भागते हैं, तो आपको 11,881,376 (यानी 26 की शक्ति प्राप्त होगी) 5) वापस तार। उस लम्बाई को 6 तक उछालें, और आपको 308,915,776 तार वापस मिलेंगे। ये संख्या बहुत तेज़ी से दर्द करती है।
यहाँ एक समाधान है जिसे मैंने जावा में एक साथ रखा है। आपको दो रनटाइम तर्क (एक्स और वाई के अनुरूप) प्रदान करने की आवश्यकता होगी। मज़े करो।
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);
}
}
}
}
यहाँ एक गैर-पुनरावर्ती संस्करण है, जो कि जावास्क्रिप्ट में आया था। यह नुथ के गैर-पुनरावर्ती ऊपर से आधारित नहीं है, हालांकि इसमें तत्व स्वैपिंग में कुछ समानताएं हैं। मैंने 8 तत्वों तक के इनपुट सरणियों के लिए इसकी शुद्धता को सत्यापित किया है।
एक त्वरित अनुकूलन out
एरे को प्री-फ्लाइंग और टालना होगा push()
।
मूल विचार है:
एकल स्रोत सरणी को देखते हुए, सरणियों का पहला नया सेट उत्पन्न करें जो बदले में प्रत्येक बाद के तत्व के साथ पहले तत्व को स्वैप करता है, हर बार अन्य तत्वों को छोड़ देता है। उदाहरण: 1234 दिया गया, 1234, 2134, 3214, 4231 उत्पन्न करें।
नए पास के लिए बीज के रूप में पिछले पास से प्रत्येक सरणी का उपयोग करें, लेकिन पहले तत्व को स्वैप करने के बजाय, दूसरे तत्व के साथ दूसरे तत्व को स्वैप करें। इस समय, आउटपुट में मूल सरणी शामिल न करें।
चरण 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;
}
रूबी में:
str = "a"
100_000_000.times {puts str.next!}
यह काफी तेज है, लेकिन इसमें कुछ समय लगने वाला है =)। बेशक, आप "आआआआआआ" शुरू कर सकते हैं यदि छोटे तार आपके लिए दिलचस्प नहीं हैं।
मैंने वास्तविक प्रश्न का गलत अर्थ निकाला हो सकता है - किसी एक पोस्ट में ऐसा लगता है जैसे कि आपको स्ट्रिंग्स के एक ब्रूटफोर्स लाइब्रेरी की आवश्यकता है, लेकिन मुख्य प्रश्न में यह लगता है कि आपको किसी विशेष स्ट्रिंग को क्रमबद्ध करने की आवश्यकता है।
आपकी समस्या कुछ हद तक इसी तरह की है: http://beust.com/weblog/archives/000491.html (सभी पूर्णांकों की सूची जिसमें कोई भी अंक खुद को दोहराता नहीं है, जिसके परिणामस्वरूप संपूर्ण भाषाओं को हल करने में बहुत कुछ मिला, ocaml लड़का क्रमपरिवर्तन का उपयोग कर रहा है, और कुछ जावा व्यक्ति अभी तक एक अन्य समाधान का उपयोग कर रहा है)।
मुझे आज इसकी आवश्यकता थी, और हालांकि पहले से दिए गए उत्तर ने मुझे सही दिशा में इंगित किया, वे काफी नहीं थे जो मैं चाहता था।
हीप की विधि का उपयोग करके यहां एक कार्यान्वयन है। सरणी की लंबाई कम से कम 3 होनी चाहिए और व्यावहारिक विचारों के लिए 10 या उससे अधिक नहीं होनी चाहिए, जो आप करना चाहते हैं, धैर्य और घड़ी की गति पर निर्भर करता है।
इससे पहले कि आप अपने लूप में प्रवेश करें, Perm(1 To N)
पहले क्रमपरिवर्तन के साथ प्रारंभ करें, Stack(3 To N)
शून्य के साथ *, और ** के Level
साथ 2
। लूप कॉल के अंत में NextPerm
, जब हम कर रहे हैं झूठे वापस आ जाएगी।
* VB आपके लिए वही करेगा।
** आप इसे अनावश्यक बनाने के लिए नेक्स्टपर्म को थोड़ा बदल सकते हैं, लेकिन यह इस तरह से स्पष्ट है।
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
अन्य तरीकों का वर्णन विभिन्न लेखकों द्वारा किया गया है। नुथ दो का वर्णन करता है, एक शाब्दिक क्रम देता है, लेकिन जटिल और धीमा है, दूसरे को सादे परिवर्तनों की विधि के रूप में जाना जाता है। जी गाओ और डियानजुन वांग ने एक दिलचस्प पेपर भी लिखा।
अजगर में यह कोड, जब 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()
आशा है कि यह आपके लिए उपयोगी है। किसी भी वर्ण के साथ काम करता है, न केवल संख्या
यहां एक लिंक दिया गया है जो बताता है कि स्ट्रिंग के क्रमपरिवर्तन कैसे प्रिंट करें। http://nipun-linuxtips.blogspot.in/2012/11/print-all-permutations-of-characters-in.html
यद्यपि यह आपके प्रश्न का सटीक उत्तर नहीं देता है, यहाँ एक ही लंबाई के कई तार से अक्षरों के प्रत्येक क्रमपरिवर्तन को उत्पन्न करने का एक तरीका है: उदाहरण के लिए, यदि आपके शब्द "कॉफ़ी", "जुमला" और "मूडल" हैं, तो आप कर सकते हैं उम्मीद है कि "कूडल", "जोदे", "जोफले", आदि जैसे उत्पादन।
मूल रूप से, संयोजनों की संख्या (शब्दों की संख्या) की शक्ति (प्रति शब्द अक्षरों की संख्या) है। तो, 0 और संयोजनों की संख्या के बीच एक यादृच्छिक संख्या चुनें - 1, उस संख्या को आधार (शब्दों की संख्या) में परिवर्तित करें, फिर उस संख्या के प्रत्येक अंक को संकेतक के रूप में उपयोग करें जिसके लिए अगले अक्षर से शब्द लेना है।
उदाहरण के लिए: उपरोक्त उदाहरण में। 3 शब्द, 6 अक्षर = 729 संयोजन। एक यादृच्छिक संख्या चुनें: 465. आधार 3 में परिवर्तित करें: 122020. शब्द 1 से पहला अक्षर लें, 2 शब्द से 2, 3 से शब्द 2, 4 से शब्द 0 ... और आपको मिलता है ... "joofle"।
यदि आप सभी क्रमपरिवर्तन चाहते थे, तो बस 0 से 728 तक लूप करें। बेशक, यदि आप सिर्फ एक यादृच्छिक मूल्य चुन रहे हैं, तो बहुत सरल कम-भ्रमित तरीका अक्षरों पर लूप होगा। यह विधि आपको पुनरावृत्ति से बचने की अनुमति देती है, क्या आपको सभी क्रमपरिवर्तन चाहिए, साथ ही यह आपको वैसा ही दिखता है जैसे आप मैथ्स (टीएम) जानते हैं !
यदि संयोजनों की संख्या अत्यधिक है, तो आप इसे छोटे शब्दों की एक श्रृंखला में तोड़ सकते हैं और अंत में उन्हें संक्षिप्त कर सकते हैं।
सी # पुनरावृत्त:
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;
}
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
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
यहाँ मेरा एक गैर पुनरावर्ती संस्करण पर ले रहा है
पायथोनिक समाधान:
from itertools import permutations
s = 'ABCDEF'
p = [''.join(x) for x in permutations(s)]
यहाँ एक सुंदर, गैर-पुनरावर्ती, ओ (एन!) समाधान है:
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;
}