Подтвердить что ты не робот

Как получить все возможные образцы массива букв

Возможный дубликат:
Есть ли какие-нибудь лучшие методы для перестановки строки?

Допустим, у меня есть буквы

a b c d

и я хочу получить каждый возможный шаблон/комбинацию этих букв в строке длиной 4 буквы.

aaaa

baaa

caaa

дааа

abaa

ACAA

acad

авва

и т.д.

Какой цикл или шаблон можно использовать для отображения каждой комбинации?

Я пишу это на С#, но примеры в С++ и javascript также приветствуются.

Моя текущая идея только увеличивает одну букву для каждой буквы. Затем сдвигается вправо один раз и повторяется. Это не распространяется на такие шаблоны, как.

авва

4b9b3361

Ответ 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 ].