Python 算法奇怪的程序
Python program with strange algorithm
我真的不知道如何解释它,但我需要编写一个 Python 程序来输出:
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
谁能帮我解释一下该怎么做?
谢谢:)
看起来这个程序需要 运行 像这样:
output first number
output second number
output first-second numbers
output third number
output fourth number
output third-fourth numbers
output first to fourth numbers
(same for five to eight)
output all eight
想一想这里的模式,看看能不能解决!
好的,一种解决方案如下:
lst = list(range(1,9))
def func(l):
lst_str = list(map(str, lst))
for i in l:
print(i)
for dvd in (2, 4, 8):
if i % dvd == 0:
print("-".join(lst_str[i-dvd:i]))
func(lst)
输出
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
这对于其他系列会失败,所以也许我们要检查它在列表。
例如:
lst = list(range(9,17))
def func(l):
lst_str = list(map(str, lst))
for n, i in enumerate(l):
print(i)
n += 1
for dvd in (2, 4, 8):
if n % dvd == 0:
print("-".join(lst_str[n-dvd:n]))
func(lst)
输出
9
10
9-10
11
12
11-12
9-10-11-12
13
14
13-14
15
16
15-16
13-14-15-16
9-10-11-12-13-14-15-16
您可以将其扩展到更多的 2 次方,因此您可以使用 [2**n for n in range(1,max_exp + 1)]
而不是仅针对 (2, 4, 8)
进行迭代,其中 max_exp
是您选择的输入
我意识到问题已经解决并且已经选择了答案,但是我想到了一个更通用的算法,我觉得有必要分享一下。我们重复连接以前的模式(由“-”分隔),并且对于我们的迭代次数可被其整除的 2 的每个完美幂,这种连接发生 1x。因此,通过一些位检查和堆栈操作,我们可以很容易地将问题抽象成一个解决方案,该解决方案将适用于任何大小的输入、任何字符集等,甚至在非二次方大小的情况下也表现良好输入。
def print_patterns(alphabet, delimiter="-"):
stack = []
def push(pattern):
print(pattern)
stack.append(pattern)
def pop():
pat1 = stack.pop()
pat2 = stack.pop()
return f"{pat2}{delimiter}{pat1}"
for index, char in enumerate(alphabet, 1):
push(char)
for bit in reversed(bin(index)):
if bit != '0':
break
push(pop())
示例输出:
>>> print_patterns("12345678")
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
还有一个边缘案例:
>>> print_patterns("abcdef", "*")
a
b
a*b
c
d
c*d
a*b*c*d
e
f
e*f
这里是 的一个实现,使用递归生成器:
def f(s):
if len(s) >= 2:
m = (len(s)+1)//2
yield from f(s[:m])
yield from f(s[m:])
yield '-'.join(iter(s))
测试:
>>> print('\n'.join( f('abcd') ))
a
b
a-b
c
d
c-d
a-b-c-d
>>> print('\n'.join( f(''.join(map(str, range(1,9)))) ))
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
我真的不知道如何解释它,但我需要编写一个 Python 程序来输出:
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
谁能帮我解释一下该怎么做?
谢谢:)
看起来这个程序需要 运行 像这样:
output first number
output second number
output first-second numbers
output third number
output fourth number
output third-fourth numbers
output first to fourth numbers
(same for five to eight)
output all eight
想一想这里的模式,看看能不能解决!
好的,一种解决方案如下:
lst = list(range(1,9))
def func(l):
lst_str = list(map(str, lst))
for i in l:
print(i)
for dvd in (2, 4, 8):
if i % dvd == 0:
print("-".join(lst_str[i-dvd:i]))
func(lst)
输出
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
这对于其他系列会失败,所以也许我们要检查它在列表。 例如:
lst = list(range(9,17))
def func(l):
lst_str = list(map(str, lst))
for n, i in enumerate(l):
print(i)
n += 1
for dvd in (2, 4, 8):
if n % dvd == 0:
print("-".join(lst_str[n-dvd:n]))
func(lst)
输出
9
10
9-10
11
12
11-12
9-10-11-12
13
14
13-14
15
16
15-16
13-14-15-16
9-10-11-12-13-14-15-16
您可以将其扩展到更多的 2 次方,因此您可以使用 [2**n for n in range(1,max_exp + 1)]
而不是仅针对 (2, 4, 8)
进行迭代,其中 max_exp
是您选择的输入
我意识到问题已经解决并且已经选择了答案,但是我想到了一个更通用的算法,我觉得有必要分享一下。我们重复连接以前的模式(由“-”分隔),并且对于我们的迭代次数可被其整除的 2 的每个完美幂,这种连接发生 1x。因此,通过一些位检查和堆栈操作,我们可以很容易地将问题抽象成一个解决方案,该解决方案将适用于任何大小的输入、任何字符集等,甚至在非二次方大小的情况下也表现良好输入。
def print_patterns(alphabet, delimiter="-"):
stack = []
def push(pattern):
print(pattern)
stack.append(pattern)
def pop():
pat1 = stack.pop()
pat2 = stack.pop()
return f"{pat2}{delimiter}{pat1}"
for index, char in enumerate(alphabet, 1):
push(char)
for bit in reversed(bin(index)):
if bit != '0':
break
push(pop())
示例输出:
>>> print_patterns("12345678")
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8
还有一个边缘案例:
>>> print_patterns("abcdef", "*")
a
b
a*b
c
d
c*d
a*b*c*d
e
f
e*f
这里是
def f(s):
if len(s) >= 2:
m = (len(s)+1)//2
yield from f(s[:m])
yield from f(s[m:])
yield '-'.join(iter(s))
测试:
>>> print('\n'.join( f('abcd') ))
a
b
a-b
c
d
c-d
a-b-c-d
>>> print('\n'.join( f(''.join(map(str, range(1,9)))) ))
1
2
1-2
3
4
3-4
1-2-3-4
5
6
5-6
7
8
7-8
5-6-7-8
1-2-3-4-5-6-7-8