如何获得一系列字母的所有可能模式
可能重复:
有没有更好的方法来排列字符串?
让我们说我有这些信件
A B C D
我希望在一个4个字母长的字符串中得到这些字母的每一个可能的模式/组合。
AAAA
咩咩咩
畜牧业协会
daaa
ABAA
ACAA
ACAD
ABBA
等等。
我可以用什么循环或模式列出每种可能的组合?
我在C#中写这个,但是C ++和javascript中的例子也是受欢迎的。
我目前的想法只为每个字母增加一个字母。 然后向右移动一次并重复。 这不包括像这样的模式。
ABBA
您可以使用LINQ轻松完成:
string[] items = {"a", "b", "c", "d"}; var query = from i1 in items from i2 in items from i3 in items from i4 in items select i1 + i2 + i3 + i4; foreach(var result in query) Console.WriteLine(result);
如果你不知道你想要四个组合,你可以用更多的工作来计算任意笛卡尔积:
http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
这里只有一个for循环
var one = ['a','b','c','d']; var length = one.length; var total = Math.pow(length, length); var pow3 = Math.pow(length,3); var pow2 = Math.pow(length,2); for(var i = 0; i
这是一个简单的低效方法:
var one = ['a','b','c','d']; var i,j,k,l; var len = 4; for(i=0;i
类似的C#:
var one = new[] {'a','b','c','d'}; var len = one.Length; for(var i=0;i
只是为了它,它是javascript中任意数量字母的通用解决方案。
有趣的是,谷歌浏览器希望翻译“马来语”的输出。
var letters = ['a', 'b', 'c', 'd']; var letterCount = letters.length; var iterations = Math.pow(letterCount, letterCount); for (var i = 0; i < iterations; i++) { var word = ""; for (var j = 0; j < letterCount; j++) { word += letters[Math.floor(i / Math.pow(letterCount, j)) % letterCount]; } document.write(word + "
"); }
递归C#实现:
public IEnumerable CreateCombinations(IEnumerable input, int length) { foreach (var c in input) { if (length == 1) yield return c.ToString(); else { foreach (var s in CreateCombinations(input, length - 1)) yield return c.ToString() + s; } } }
应该允许任意数量的字符和任何所需的字符串长度(直到堆栈溢出:))
使用它:
foreach (var s in CreateCombinations("abcd", 4)) { Console.WriteLine(s); }
结果是:
aaaa aaab aaac aaad aaba aabb aabc aabd aaca ... dddd
我使用递归来到这个javascript解决方案。 无论如何这些约束并不是真的很贵(只有4 ^ 4个电话)
(function() { var combinations = []; (function r(s) { s = s || ''; if (s.length === 4) { combinations[combinations.length] = s; return; } r(s + 'a'); r(s + 'b'); r(s + 'c'); r(s + 'd'); })(); console.log(combinations); })();
输出是
["aaaa", "aaab", "aaac", "aaad",...., "dddc", "dddd"]
这也可能有用;)
var letters = new[] {'a','b','c','d'}; Random random = new Random(); HashSet results = new HashSet (); while(results.Count < 256) { results.Add(letters[random.Next(4)] + letters[random.Next(4)] + letters[random.Next(4)] + letters[random.Next(4)]); } results.ToList().ForEach(Console.WriteLine);
在任何给定的n中LINQ中的一个线程:
var letters = new[] { "a", "b", "c", "d" }; int n = 4; var z = Enumerable.Range(1, n) .Select(x => letters.AsEnumerable()) .Aggregate((g,h) => g.Join(h, _ => true, _ => true, (a, b) => a + b));
你有一个带2个2个字母的字母表,所以每个字母恰好表示两位,因此字母表示8位。 现在,只需枚举所有值即可。 在pCeudocode中:
static const char alphabet[4] = { 'a', 'b', 'c', 'd' }; for (unsigned int i = 0; i != 256; ++i) { for (unsigned int k = 0; k != 4; ++k) { print(alphabet[(i >> (2*k)) % 4]); } }
这里256 = 2 2×4 ,所以你可以很容易地推广这个方案。
一个简单,直接的JavaScript解决方案(带有大括号的季节):
var letters = ['a', 'b', 'c', 'd'], len=letters.length; for (var i=len; i--;) for (var j=len; j--;) for (var k=len; k--;) for (var l=len; l--;) console.log (letters[i] + letters[j] + letters[k] + letters[l]);
使用递归,动作委托和Lambdas! (纯娱乐)
using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { List letters = new List () { 'a', 'b', 'c', 'd' }; List words = new List (); Action, string, List> recursiveLetter = null; recursiveLetter = (availLetters, word, newWords) => { if (word.Length < availLetters.Count()) { availLetters.ToList() .ForEach(currentletter => recursiveLetter(availLetters, word + currentletter, newWords)); } else { newWords.Add(word); } }; recursiveLetter(letters, string.Empty, words); // ALL THE MAGIC GO! words.ForEach(word => Console.WriteLine(word)); Console.ReadKey(); } } }
C中的实现
#include #define WORD_LEN 5 #define ALPHA_LEN 4 char alphabet[ALPHA_LEN] = {'a', 'b', 'c', 'd'}; int w[WORD_LEN] = {}; void print_word() { int i; char s[WORD_LEN + 1]; for(i = 0; i < WORD_LEN; i++) { s[i] = alphabet[w[i]]; } s[WORD_LEN] = '\0'; puts(s); } int increment_word() { int i; for(i = 0; i < WORD_LEN; i++) { if(w[i] < ALPHA_LEN - 1) { w[i]++; return 1; } else { w[i] = 0; } } return 0; } int main() { int i; do { print_word(); } while (increment_word()); }
另一个基于Linq的答案:
List items = new List () {"a", "b", "c", "d"}; items.ForEach(i1 => items.ForEach(i2 => items.ForEach(i3 => items.ForEach(i4 => Console.WriteLine(i1 + i2 + i3 + i4) ) ) ) );
Haskell可能有最短的程序:
sequence (replicate 4 "abcd")
replicate 4 "abcd"
创建一个重复"abcd"
四次的列表。 sequence
是一种非常通用的多态moadic操作,有许多用途,其中包括生成列表列表的笛卡尔积。
可以使用C#或其他.NET语言复制此解决方案。 Eric Lippert的LINQ解决方案对应于这个Haskell解决方案:
items = ["a", "b", "c", "d"] query = do i1 <- items i2 <- items i3 <- items i4 <- items return (i1 ++ i2 ++ i3 ++ i4)
如果你比较它们,那么请注意LINQ from ... in
灵感来自Haskell的<-
,而LINQ的select
是Haskell的return
。
Haskell单线解决方案与较长的解决方案之间的关系可以通过编写我们自己的sequence
定义来实现:
sequence' [] = return [] sequence' (m:ms) = do x <- m xs <- sequence' ms return (x:xs)
在LINQ术语中, sequence
函数允许您使用列表from ix in items
语句替换from ix in items
的重复from ix in items
,从中可以选择每个项目。
编辑:一个朋友只是打败了我(嗯,一行除了import
):
import Control.Monad replicateM 4 "abcd"
在Python中:
items = [“a”,“b”,“c”,“d”]
打印[a + b + c + d表示项目中的项目中的b项目中项目中的项目中的c项目]
必须有一个erlang列表理解
就像是
Value = "abcd". [ [A] ++ [B] ++ [C] ++ [D] || A <- Value, B <- Value, C <- Value, D <- Value ].