我有一个字符串27AAGCB5913L2ZF
。如果字符串中出现A
或J
或K
中的任何一个,那么我需要将它们更改为三个字母的所有可能组合。如果我将上面的字符串输入传递给程序,那么输出应该像这样
27AAGCB5913L2ZF
27AJGCB5913L2ZF
27AKGCB5913L2ZF
27JAGCB5913L2ZF
27KAGCB5913L2ZF
27KJGCB5913L2ZF
27JKGCB5913L2ZF
27JJGCB5913L2ZF
27KKGCB5913L2ZF
字母可以出现在字符串中的任何位置。如果仅出现一个字母,则必须依次用A
,J
和K
替换。例如,字符串27ABGCB5913L2ZF
的输出应如下
27ABGCB5913L2ZF
27JBGCB5913L2ZF
27kBGCB5913L2ZF
我可以用这样的代码搜索给定的字符
while ( $string =~ /(B)/g ) {
say $1, ' at ', pos $string;
}
如果在任何位置上可以有任意数量的A
,J
或K
,如何生成所有可能的字符串?
答案 0 :(得分:3)
这可以在Perl中使用glob
运算符来完成。 glob
用于查找匹配文件,但是如果模式中不包含通用通配符(*
,?
或[...]
),则它将简单地返回所有可能的匹配项,无论它们是否以文件形式存在
此Perl代码使用替换方式通过将所有出现的A
,J
或K
替换为多重模式{A,J,K}
来形成全局模式。将结果提交到glob
会给我们提供所需的输出
use strict;
use warnings 'all';
use feature 'say';
for my $s ( qw/ 27AAGCB5913L2ZF 27KBGCB5913L2ZF / ) {
(my $patt = $s) =~ s/[AJK]/{A,J,K}/g;
say for glob $patt;
say "";
}
27AAGCB5913L2ZF
27AJGCB5913L2ZF
27AKGCB5913L2ZF
27JAGCB5913L2ZF
27JJGCB5913L2ZF
27JKGCB5913L2ZF
27KAGCB5913L2ZF
27KJGCB5913L2ZF
27KKGCB5913L2ZF
27ABGCB5913L2ZF
27JBGCB5913L2ZF
27KBGCB5913L2ZF
答案 1 :(得分:2)
您想要的关键字母A
,J
和K
的组合的集合称为
Cartesian product。
在Python中,您可以使用
itertools.product
生成它们。
首先,我们需要找到输入字符串中所有关键字母的位置。使用内置的简单方法
enumerate
功能。一旦知道了这些位置以及该字符串包含多少个关键字母,我们就可以生成笛卡尔乘积的每个项目,替换这些关键字母,然后打印新的字符串。
在Python中,字符串是不可变的(无法更改),因此我将字符串转换为字符列表,替换键位置中的字符,然后使用
str.join
方法。
以下代码将同时适用于Python的版本2和版本3
from itertools import product
def make_patterns(s):
keyletters = 'AJK'
# Convert input string into a list so we can easily substitute letters
seq = list(s)
# Find indices of key letters in seq
indices = [ i for i, c in enumerate(seq) if c in keyletters ]
# Generate key letter combinations & place them into the list
for t in product(keyletters, repeat=len(indices)):
for i, c in zip(indices, t):
seq[i] = c
print(''.join(seq))
# Test
data = (
'1ABC2',
'27AAGCB5913L2ZF',
'3A4J',
'5K67KA',
)
for s in data:
print('\nInput:', s)
make_patterns(s)
Input: 1ABC2
1ABC2
1JBC2
1KBC2
Input: 27AAGCB5913L2ZF
27AAGCB5913L2ZF
27AJGCB5913L2ZF
27AKGCB5913L2ZF
27JAGCB5913L2ZF
27JJGCB5913L2ZF
27JKGCB5913L2ZF
27KAGCB5913L2ZF
27KJGCB5913L2ZF
27KKGCB5913L2ZF
Input: 3A4J
3A4A
3A4J
3A4K
3J4A
3J4J
3J4K
3K4A
3K4J
3K4K
Input: 5K67KA
5A67AA
5A67AJ
5A67AK
5A67JA
5A67JJ
5A67JK
5A67KA
5A67KJ
5A67KK
5J67AA
5J67AJ
5J67AK
5J67JA
5J67JJ
5J67JK
5J67KA
5J67KJ
5J67KK
5K67AA
5K67AJ
5K67AK
5K67JA
5K67JJ
5K67JK
5K67KA
5K67KJ
5K67KK
稍作更改,便可以将函数转换为生成器。这样一来,您就可以轻松地遍历输出字符串,或者根据需要将其转换为列表。
from itertools import product
def make_patterns(s):
keyletters = 'AJK'
# Convert input string into a list so we can easily substitute letters
seq = list(s)
# Find indices of key letters in seq
indices = [i for i, c in enumerate(seq) if c in keyletters]
# Generate key letter combinations & place them into the list
for t in product(keyletters, repeat=len(indices)):
for i, c in zip(indices, t):
seq[i] = c
yield ''.join(seq)
# Test
print(list(make_patterns('A12K')))
for s in make_patterns('3KJ4'):
print(s)
['A12A', 'A12J', 'A12K', 'J12A', 'J12J', 'J12K', 'K12A', 'K12J', 'K12K']
3AA4
3AJ4
3AK4
3JA4
3JJ4
3JK4
3KA4
3KJ4
3KK4
答案 2 :(得分:0)
这是Perl中的递归解决方案:
my $str = '27AAGCB5913L2ZF';
my @replace = qw (A J K);
print_string( $str);
sub print_string {
my ( $str, $replace, $start) = @_;
if (defined $replace) {
substr( $str, $start, 1) = $replace;
}
else {
$start = -1;
}
pos( $str) = $start +1;
if ($str =~ /\G.*?(A|J|K)/g) {
my $cur_start = $-[-1];
print_string( $str, $_, $cur_start) for @replace;
}
else {
say $str;
}
}
输出:
27AAGCB5913L2ZF
27AJGCB5913L2ZF
27AKGCB5913L2ZF
27JAGCB5913L2ZF
27JJGCB5913L2ZF
27JKGCB5913L2ZF
27KAGCB5913L2ZF
27KJGCB5913L2ZF
27KKGCB5913L2ZF
答案 3 :(得分:0)
一个简短的解决方案:
首先将字符串拆分为可能出现在每个位置的字符元组
>>> s = "27AAGCB5913L2ZF"
>>> p2 = [("A","J","K") if c in "AJK" else (c,) for c in s]
>>> p2
[('2',), ('7',), ('A', 'J', 'K'), ('A', 'J', 'K'), ('G',), ('C',), ('B',), ('5',), ('9',), ('1',), ('3',), ('L',), ('2',), ('Z',), ('F',)]
然后此函数会将元组列表重新组合为字符串:
def assemble(t, s=''):
if t:
for c in t[0]:
assemble(t[1:], s+c)
else:
print(s)
>>> assemble(p2)
27AAGCB5913L2ZF
27AJGCB5913L2ZF
27AKGCB5913L2ZF
27JAGCB5913L2ZF
27JJGCB5913L2ZF
27JKGCB5913L2ZF
27KAGCB5913L2ZF
27KJGCB5913L2ZF
27KKGCB5913L2ZF