关于for循环:从数组中替换字符串字符

Replace string characters from array

我有一个字符串(短于限定长度),我想从一个字符数组(短于限定长度)中复制多次,每次替换一个字符。

假设我有这根线:"aa"此数组:【a'、【b'、【c'、【d'】

经过一些循环的魔法之后,会有一个数组,比如:''aa'、'ab'、'ac'、'ad'、'ba'、'bb'…'D'',D''

你会怎么做?我试过用三个做回路的方法,但我好像不明白。

编辑对字符串的依赖关系如下:

说绳子是"ba"那么输出应该是:【ba】、【bb】、【bc】、【bd】、【ca’……"DD’


如果结果数组中的字符串顺序无关紧要,并且初始字符串中的所有字符都在替换数组中,则:

1
2
3
4
5
6
7
8
9
10
11
#!/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']

这是一个一般案例的解决方案。替换按词典顺序执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/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']


您可以通过两种方式使用以下代码:

  • 以数组形式获取所有字符串
  • 一次拉一根绳子
  • 对于用法(1),调用getStrings()方法(根据需要多次调用)。

    对于用法(2),只要hasNext()返回true,就调用next()方法。(实现reset()方法留给读者作为练习!;-)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    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()]);
        }

    }


    嗯,两个for循环应该这样做:python伪代码--

    1
    2
    3
    4
    5
    6
    7
    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

    [更新:更正了愚蠢的拼写错误。]


    如果字符串和数组都不包含"a",则问题会更清楚。所需的输出不显示对输入字符串的任何依赖关系。