1. Obtaining a sum from a subsequence of digits
Obtaining a sum from a subsequence of digits
Write a program sum_of_digits.py that prompts the user for two numbers, say available_digits and desired_sum, and outputs the number of ways of selecting digits from available_digits that
sum up to desired_sum. For 4 solutions:
--one solution is obtained by selecting 1 and both occurrences of 2 (1 + 2 + 2 = 5);
--one solution is obtained by selecting 1 and 4 (1 + 4 = 5);
--one solution is obtained by selecting the first occurrence of 2 and 3 (2 + 3 = 5);
--one solution is obtained by selecting the second occurrence of 2 and 3 (2 + 3 = 5).
#DP solution:
#available_digits = 1 2 2 3 4, sum = 5
# 1 2 3 4 5 (sum)
#1 1,1 1,1 1,1 1,1 1,1 (第一個(gè)數(shù)字是sum值,第二個(gè)數(shù)字是路徑數(shù)量)
#2 1,1 2,1 3,1 3,1 3,1
#2 1,1 2,2 3,2 4,1 5,1
#3 1,1 2,2 3,3 4,2 5,3
#4 1,1 2,2 3,3 4,3 5,4
#digits
#digits = [1, 2, 2, 3, 4]
#default: cell[0] = digits[0] * sum
##cell[i][j] = max(cell[i - 1][j], cell[i - 1][j - digits[i]] + digits[i])
##路徑數(shù)量分情況討論,如下面的代碼,如果本行的digits數(shù)值與某個(gè)cell中上一行同一位置的數(shù)值相等,則本行這個(gè)cell中的路徑數(shù)量等于上一行對(duì)應(yīng)位置的路徑數(shù)量加1
#def printcell():
# for i in range(nrow):
# for j in range(ncolumn):
# print(cell[i][j], end = ' ')
# print()
digits = input('Input a number that we will use as available digits: ')
desired_sum = int(input('Input a number that represents the desired sum: '))
digits = [int(e) for e in sorted(digits)]
nrow = len(digits)
ncolumn = desired_sum
cell = [[[0, 0] for _ in range(ncolumn)] for _ in range(nrow)]
#創(chuàng)建一個(gè)網(wǎng)格,行數(shù)等于輸入的可用數(shù)字的長(zhǎng)度,列數(shù)等于輸入的總和,也就是說以1為步長(zhǎng)構(gòu)建column。網(wǎng)格default值為0,以及一個(gè)記錄path組成方式數(shù)量的空list
for j in range(ncolumn):
if j + 1 >= digits[0]:
cell[0][j][0] = digits[0]
cell[0][j][1] = 1
else:
cell[0][j][0] = 0
cell[0][j][1] = 0
#創(chuàng)建第一行的default值,如果比某列sum值大則設(shè)置為0,否則則設(shè)置為digits第一個(gè)值
for i in range(1, nrow):
for j in range(ncolumn):
if digits[i] > j + 1:
cell[i][j][0] = cell[i - 1][j][0]
cell[i][j][1] = cell[i - 1][j][1]
elif digits[i] == j + 1:
cell[i][j][0] = digits[i]
if cell[i - 1][j][0] == digits[i]:
cell[i][j][1] = cell[i - 1][j][1] + 1
else:
cell[i][j][1] = 1
else:
a = cell[i - 1][j][0]
b = cell[i - 1][j - digits[i]][0] + digits[i]
if a == b:
cell[i][j][0] = a
cell[i][j][1] = cell[i - 1][j][1] + cell[i - 1][j - digits[i]][1]
else:
if a > b:
cell[i][j][0] = a
cell[i][j][1] = cell[i - 1][j][1]
else:
cell[i][j][0] = b
cell[i][j][1] = cell[i - 1][j - digits[i]][1]
# printcell()
if cell[-1][-1][0] == desired_sum:
solution = cell[-1][-1][1]
else:
solution = 0
if solution == 0:
print('There is no solution.')
elif solution == 1:
print('There is a unique solution.')
else:
print('There are %d solutions.' % solution)
2. Merging two strings into a third one
Say that two strings s1 and s2 can be merged into a third string s3 if s3 is obtained from s1 by inserting arbitrarily in s1 the characters in s2, respecting their order. For instance, the two strings ab and cd can be merged into abcd, or cabd, or cdab, or acbd, or acdb, ..., but not into adbc nor into cbda. Write a program merging_strings.py that prompts the user for 3 strings and displays the output as follows:
--If no string can be obtained from the other two by merging, then the program outputs that there is no solution.
--Otherwise, the program outputs which of the strings can be obtained from the other two by merging.
str1 = input('Please input the first string: ')
str2 = input('Please input the second string: ')
str3 = input('Please input the third string: ')
if len(str1) > len(str2):
if len(str1) > len(str3):
last = str1
if str2 > str3:
first, second = str3, str2
else:
first, second = str2, str3
else:
last, first, second = str3, str2, str1
else:
if len(str2) > len(str3):
last = str2
if str1 > str3:
first, second = str3, str1
else:
first, second = str1, str3
else:
last, first, second = str3, str1, str2
#按照字符串從段到長(zhǎng)順序分別賦給first, second, last
def merge(first, second, last):
if not first and second == last:
return True
if not second and first == last:
return True
if not first and not second:
return False
if second[0] == last[0] and merge(first, second[1:], last[1:]):
return True
#因?yàn)閟econd是第二長(zhǎng)的,所以必須放在first的判斷前面,以保證index不溢出
if first[0] == last[0] and merge(first[1:], second, last[1:]):
return True
return False
if merge(first, second, last):
if last == str1:
output = 'first'
elif last == str2:
output = 'second'
else:
output = 'third'
print('The %s string can be obtained by merging the other two.' % output)
else:
print('No solution.')
3. Longest sequence of consecutive letters
Write a program longest_sequence.py that prompts the user for a string w of lowercase letters and outputs the longest sequence of consecutive letters that occur in w, but with possibly other letters in between, starting as close as possible to the beginning of w.
string = input('Please input a string of lowercase letters: ')
l = [ord(i) for i in string]
#將輸入的字符串轉(zhuǎn)化為對(duì)應(yīng)的integer,方便后續(xù)比較,判斷是否連續(xù)
l = list(set(sorted(l)))
#將integer的list排序,去重
start, longest, length, result = l[0], [l[0]], 1, [l[0]]
#初始化,設(shè)置連續(xù)integer開始的位置是第一個(gè)integer,最長(zhǎng)的連續(xù)integer是第一個(gè)integer,最長(zhǎng)長(zhǎng)度是1,最長(zhǎng)連續(xù)integer記錄是第一個(gè)integer
for i in range(1, len(l)):
if l[i] == l[i - 1] + 1:
longest.append(l[i])
#如果當(dāng)前數(shù)字和前面數(shù)字連續(xù),則longest記錄值增加一個(gè)當(dāng)前integer
else:
if len(longest) > length:
result = longest
length = len(longest)
#如果當(dāng)前數(shù)字和前面不再連續(xù),判斷l(xiāng)ongest中的最長(zhǎng)連續(xù)數(shù)字長(zhǎng)度是否比result中的記錄長(zhǎng)
#如果長(zhǎng),則改寫result和最長(zhǎng)length
start, longest = l[i], [l[i]]
#重置開始的位置為當(dāng)前integer,longest中只有當(dāng)前integer一個(gè)元素
if i == len(l) - 1 and len(longest) > length:
result = longest
length = len(longest)
#如果是最后一個(gè)l中的元素,還要判斷當(dāng)前的連續(xù)數(shù)字長(zhǎng)度是否是最長(zhǎng)的
solution = ''
for i in result:
solution += chr(i)
#將最長(zhǎng)連續(xù)數(shù)字轉(zhuǎn)換為對(duì)應(yīng)的字母輸出
print('The solution is: %s' % solution)