Как получить все возможные образцы массива букв
Возможный дубликат:
Есть ли какие-нибудь лучшие методы для перестановки строки?
Допустим, у меня есть буквы
a b c d
и я хочу получить каждый возможный шаблон/комбинацию этих букв в строке длиной 4 буквы.
aaaa
baaa
caaa
дааа
abaa
ACAA
acad
авва
и т.д.
Какой цикл или шаблон можно использовать для отображения каждой комбинации?
Я пишу это на С#, но примеры в С++ и javascript также приветствуются.
Моя текущая идея только увеличивает одну букву для каждой буквы. Затем сдвигается вправо один раз и повторяется. Это не распространяется на такие шаблоны, как.
авва
Ответы
Ответ 1
Вы можете сделать это очень легко с помощью 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
Ответ 2
Здесь один с одним только для цикла
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<total; i++)
console.log(one[Math.floor(i/pow3)],
one[Math.floor(i/pow2)%length],
one[Math.floor(i/length)%length],
one[i%length]);
Вот простой неэффективный метод:
var one = ['a','b','c','d'];
var i,j,k,l;
var len = 4;
for(i=0;i<len;i++) {
for(j=0;j<len;j++) {
for(k = 0; k < len; k++) {
for(l = 0; l<len; l++) {
console.log(one[i], one[j], one[k], one[l]);
}
}
}
}
Аналогичный С#:
var one = new[] {'a','b','c','d'};
var len = one.Length;
for(var i=0;i<len;i++) {
for(var j=0;j<len;j++) {
for(var k = 0; k < len; k++) {
for(var l = 0; l<len; l++) {
Console.Write(one[i] + one[j] + one[k] + one[l]);
}
}
}
}
Ответ 3
Просто для этого, здесь общее решение для любого количества букв в javascript.
http://jsfiddle.net/U9ZkX/
Интересно, что google chrome хотел бы перевести вывод из "Malay".
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 + "<br>");
}
Ответ 4
Рекурсивная реализация С#:
public IEnumerable<string> CreateCombinations(IEnumerable<char> 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
Ответ 5
Я пришел к этому решению 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"]
Ответ 6
Это, вероятно, тоже будет работать;)
var letters = new[] {'a','b','c','d'};
Random random = new Random();
HashSet<string> results = new HashSet<string>();
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);
Ответ 7
Один вкладыш в LINQ для любого заданного n:
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));
Ответ 8
У вас есть алфавит с 2 2 буквами, поэтому каждая буква выражает ровно два бита, и, таким образом, буквы выражают восемь бит. Теперь это простой вопрос перечисления всех значений. В 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 & times; 4 поэтому вы можете легко обобщить эту схему.
Ответ 9
Простое, простое решение 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]);
Ответ 10
Использование Recursion, Action Delegate и Lambdas!!! (просто для удовольствия)
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
List<char> letters = new List<char>() { 'a', 'b', 'c', 'd' };
List<string> words = new List<string>();
Action<IEnumerable<char>, string, List<string>> 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();
}
}
}
Ответ 11
Реализация в C
#include <stdio.h>
#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());
}
Ответ 12
Другой ответ Linq:
List<string> items = new List<string>() {"a", "b", "c", "d"};
items.ForEach(i1 =>
items.ForEach(i2 =>
items.ForEach(i3 =>
items.ForEach(i4 =>
Console.WriteLine(i1 + i2 + i3 + i4)
)
)
)
);
Ответ 13
У Haskell может быть самая короткая программа здесь:
sequence (replicate 4 "abcd")
replicate 4 "abcd"
создает список, который повторяется "abcd"
четыре раза. sequence
- очень общая, полиморфная, мозаичная операция, которая имеет много применений, среди которых есть декартовые продукты списков списков.
Возможно дублирование этого решения на С# или других языках .NET. Эрик Липперт Решение 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
только списком списков, из которых можно выбрать каждый элемент.
РЕДАКТИРОВАТЬ: друг просто избил меня при однократном выравнивании (ну, одна строка, кроме import
):
import Control.Monad
replicateM 4 "abcd"
Ответ 14
В Python:
items = [ "a", "b", "c", "d" ]
напечатать [a + b + c + d для предметов для b в пунктах для c в пунктах для d в элементах]
Ответ 15
Должно быть понимание списка erlang
Что-то вроде
Value = "abcd".
[ [A] ++ [B] ++ [C] ++ [D] || A <- Value, B <- Value, C <- Value, D <- Value ].