Arrays 替换数组中的字符串
我有一个字符串(长度未定),我想多次复制它,每次从一个字符数组(长度未定)中替换一个字符 假设我有这个字符串:“aa”Arrays 替换数组中的字符串,arrays,for-loop,Arrays,For Loop,我有一个字符串(长度未定),我想多次复制它,每次从一个字符数组(长度未定)中替换一个字符 假设我有这个字符串:“aa” 这个数组:['a','b','c','d'] 经过一些循环的魔法之后,会有一个数组,比如:['aa','ab','ac','ad','ba','bb','dc','dd'] 你会怎么做?我尝试了一些使用三个for循环的方法,但我似乎无法得到它 编辑 对字符串的依赖关系如下所示: 假设字符串为:“ba” 然后输出应该是:['ba','bb','bc','bd','ca','dd'
这个数组:['a','b','c','d'] 经过一些循环的魔法之后,会有一个数组,比如:['aa','ab','ac','ad','ba','bb','dc','dd'] 你会怎么做?我尝试了一些使用三个for循环的方法,但我似乎无法得到它 编辑
对字符串的依赖关系如下所示: 假设字符串为:“ba”
然后输出应该是:['ba','bb','bc','bd','ca','dd']如果字符串和数组都不包含'a',问题会更清楚。所需的输出不显示对输入字符串的任何依赖关系。嗯,两个for循环应该可以做到这一点:Python伪代码--
[更新:dumb typo corrected.]如果结果数组中字符串的顺序无关紧要,并且初始字符串中的所有字符都在替换数组中,则:
#!/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']
这是一个一般情况的解决方案。替换按字典顺序执行:
#!/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']
您可以通过两种方式使用以下代码:
getStrings()
对于用法(2),只要hasNext()
返回true,就只调用next()
方法。(实现reset()
方法留给读者作为练习!;-)
package com.so.demos;
导入java.util.ArrayList;
导入java.util.List;
公共级架线机{
私有字符串种子;//第一个值的字符串
私有字符[]选项;//允许的字符
private final int LAST_OPTION;//最大选项索引
私有int[]索引;//选项中种子字符的位置
private int[]work;//下一个字符串的字符位置
private boolean more;//至少剩下一个字符串
公共StringsMaker(字符串种子,字符[]选项){
这个种子=种子;
this.options=选项;
最后一个选项=options.length-1;
索引=新的整数[seed.length()];
对于(int i=0;i 对于(int j=0;j)您是指res.append(i+j)
?这是错误的。结果字符串总是以b
中的一个字符结尾。是的,谢谢,更正了。结果字符串总是以b中的一个字符结尾。给定输入的正确结果数组应该包含诸如“bc”、“cc”、“bd”、“dd”之类的字符串……您的代码永远不会生成它们。哇,我喜欢生成器,就像一个是的,但这看起来像是“数学变得困难”中的一个例子。没有生成器,它只是:打印地图(''.join,product('abcd',repeat=len('ba'))
#!/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']
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()]);
}
}