2008-12-27 10 views
1

J'ai une chaîne (de longueur sous-déterminée) que je veux copier plusieurs fois en remplaçant un caractère à la fois d'un tableau (de longueur sous-bornée) de caractères.Remplacer les caractères chaîne du tableau

dire J'ai donc cette chaîne: 'aa'
Et ce tableau: [ 'a', 'b', 'c', 'd']

après un peu de magie pour-boucle des choses il y aurait être un tableau comme: ['aa', 'ab', 'ac', 'ad', 'ba', 'bb' ... 'dc', 'dd']

Comment voulez-vous cela? J'ai essayé quelque chose en utilisant trois boucles, mais je n'arrive pas à l'obtenir.

Modifier
La dépendance à l'égard de la chaîne est le suivant:

Dis la chaîne est: 'ba'
, la sortie doit être: [ 'ba', 'bb', 'bc' , 'bd', 'ca' ... 'dd']

Répondre

2

Si un ordre de chaînes dans le tableau de résultat n'a pas d'importance et tous les caractères de la chaîne initiale sont dans le tableau de substitution alors:

#!/usr/bin/env python 
from itertools import product 

def allreplacements(seed, replacement_chars): 
    assert all(c in replacement_chars for c in seed) 
    for aset in product(replacement_chars, repeat=len(seed)): 
     yield ''.join(aset) 

print(list(allreplacements('ba', 'a b c d'.split()))) 
# ['aa', 'ab', 'ac', 'ad', 'ba', 'bb', 'bc', 'bd', 'ca', 'cb', 'cc', 
# 'cd', 'da', 'db', 'dc', 'dd'] 

est ici une solution pour un gener al cas. Les remplacements sont effectués dans un ordre lexicographique:

#!/usr/bin/env python 
from itertools import product 

def allreplacements(seed, replacement_chars): 
    """Generate all possible replacements (with duplicates).""" 
    masks = list(product(range(2), repeat=len(seed))) # e.g., 00 01 10 11 
    for subs in product(replacement_chars, repeat=len(seed)): 
     for mask in masks: 
      # if mask[i] == 1 then replace seed[i] by subs[i] 
      yield ''.join(s if m else c for s, m, c in zip(subs, mask, seed)) 

def del_dups(iterable): 
    """Remove duplicates while preserving order. 

    http://stackoverflow.com/questions/89178/in-python-what-is-the-fastest-algorithm-for-removing-duplicates-from-a-list-so#282589 
    """ 
    seen = {} 
    for item in iterable: 
     if item not in seen: 
      seen[item] = True 
      yield item 

print(list(del_dups(allreplacements('ba', 'abcd')))) 
print(list(del_dups(allreplacements('ef', 'abcd')))) 
# ['ba', 'aa', 'bb', 'ab', 'bc', 'ac', 'bd', 'ad', 'ca', 'cb', 'cc', 
# 'cd', 'da', 'db', 'dc', 'dd'] 

# ['ef', 'ea', 'af', 'aa', 'eb', 'ab', 'ec', 'ac', 'ed', 'ad', 'bf', 
# 'ba', 'bb', 'bc', 'bd', 'cf', 'ca', 'cb', 'cc', 'cd', 'df', 'da', 
# 'db', 'dc', 'dd'] 
+0

Wow. J'aime les générateurs autant que n'importe qui, mais cela ressemble à un exemple de "Math Made Difficult". –

+0

Sans générateurs c'est juste: 'print map (''.join, product ('abcd', repeat = len ('ba'))) ' – jfs

0

La question serait plus claire si la chaîne et le tableau ne contiennent pas un 'a'. La sortie désirée ne montre aucune dépendance à la chaîne d'entrée.

+0

Merci Je clearified ma question –

0

Um, deux pour les boucles devrait le faire: Python pseudocode--

a = "abcd" 
b = "ba" 
res = [] 
for i in a:   # i is "a", "b", ... 
    for j in b:   # j is "b", "a" 
     res.append(i+j) # [ "ab", "bb",...] 
return res 

[mise à jour:. Erreur typographique stupide corrigée]

+0

Vouliez-vous dire 'res.append (i + j)'? Et c'est faux. Les chaînes de résultats se terminent toujours par un caractère de 'b'. – jfs

+0

Oui, merci, corrigé. Et la chaîne de résultat se termine toujours par un caractère de b. –

+0

Le tableau de résultats correct pour l'entrée donnée doit contenir des chaînes telles que 'bc', 'cc', 'bd', 'dd', .. Votre code ne les produit jamais. – jfs

0

Vous pouvez utiliser le code suivant de deux façons:

  1. pour obtenir toutes les chaînes comme un tableau
  2. pour tirer les cordes une à la fois

Pour l'utilisation (1), appelez la méthode getStrings() (autant de fois que vous le souhaitez).

Pour une utilisation (2), appelez la méthode next()seulement aussi longtemps que hasNext() renvoie true. (La mise en œuvre d'une méthode reset() est laissé comme un exercice pour le lecteur! ;-)

package com.so.demos; 

import java.util.ArrayList; 
import java.util.List; 

public class StringsMaker { 

    private String seed; // string for first value 
    private char[] options; // allowable characters 

    private final int LAST_OPTION; // max options index 
    private int[] indices;   // positions of seed chars in options 
    private int[] work;    // positions of next string's chars 
    private boolean more;   // at least one string left 

    public StringsMaker(String seed, char[] options) { 
     this.seed = seed; 
     this.options = options; 
     LAST_OPTION = options.length - 1; 
     indices = new int[seed.length()]; 
     for (int i = 0; i < indices.length; ++i) { 
      char c = seed.charAt(i); 
      for (int j = 0; j <= LAST_OPTION; ++j) { 
       if (options[j] == c) { 
        indices[i] = j; 
        break; 
       } 
      } 
     } 
     work = indices.clone(); 
     more = true; 
    } 

    // is another string available? 
    public boolean hasNext() { 
     return more; 
    } 

    // return current string, adjust for next 
    public String next() { 
     if (!more) { 
      throw new IllegalStateException(); 
     } 
     StringBuffer result = new StringBuffer(); 
     for (int i = 0; i < work.length; ++i) { 
      result.append(options[work[i]]); 
     } 
     int pos = work.length - 1; 
     while (0 <= pos && work[pos] == LAST_OPTION) { 
      work[pos] = indices[pos]; 
      --pos; 
     } 
     if (0 <= pos) { 
      ++work[pos]; 
     } else { 
      more = false; 
     } 
     return result.toString(); 
    } 

    // recursively add individual strings to result 
    private void getString(List<String> result, int position, String prefix) { 
     if (position == seed.length()) { 
      result.add(prefix); 
     } else { 
      for (int i = indices[position]; i < options.length; ++i) { 
       getString(result, position + 1, prefix + options[i]); 
      } 
     } 
    } 

    // get all strings as array 
    public String[] getStrings() { 
     List<String> result = new ArrayList<String>(); 
     getString(result, 0, ""); 
     return result.toArray(new String[result.size()]); 
    } 

} 
Questions connexes