【1题待完成】CS入门学习笔记4-MIT 6.00.1x

Week 2 Problem Set

1. Assume s is a string of lower case characters.

Write a program that counts up the number of vowels contained in the string s. Valid vowels are: ‘a’, ‘e’, ‘i’, ‘o’, and ‘u’. For example, if s = ‘azcbobobegghakl’, your program should print:
“Number of vowels: 5”**

使用for循环:

n = 0 
s = 'aabbcceeoo'
for i in range(len(s)):
    if s[i] in 'aeiou':
        n = n + 1
    i = i + 1
print('Number of vowels:' + str(n))

使用while循环:

n = 0 
s = 'aabbeeoo'
i = 0
while i <= len(s)-1:
    if s[i] in 'aeiou':
        n = n + 1
    i = i + 1
print('Number of vowels:' + str(n))

小结:
len(s)会得出的是整个字符串的位数n,而range(len(s))返回的会是0–n-1, s[i]中的i的取值应是0–n-1。由此会出现while与for循环在i的取值上的不同写法。

2. Assume s is a string of lower case characters.

Write a program that prints the number of times the string ‘bob’ occurs in s. For example, if s = ‘azcbobobegghakl’, then your program should print
“Number of times bob occurs is: 2”

一开始写的:

n = 0 
s = 'azcbobobobegghakl'
i = 0
while i <= len(s)-1:
    if s[i] == 'b' and s[i+1] == 'o' and s[i+2] == 'b':
        n = n + 1
    i = i + 1
print('Number of times bob occurs is:' + str(n))

提交后发现当s='obobobontsbboobiobobd’或 s='eobobgbobqoboboboobboobbobobbbobb’时会报错,意识到问题:当在倒数第三位及之后出现b时,if语句中s[i+2]这个判断便会“string index out of range”,所以应当把i限定在len(s)-3之内,把bob当成一个整体,用它的开头去从前往后寻找,但用它的结尾去给寻找加上结束的限制。

代码修订后如下:

n = 0 
s = 'obobobontsbboobiobobd'
i = 0
while i <= len(s)-3:
    if s[i] == 'b' and s[i+1] == 'o' and s[i+2] == 'b':
        n = n + 1
    i = i + 1
print('Number of times bob occurs is: ' + str(n))

3. 【待完成】Assume s is a string of lower case characters.

Write a program that prints the longest substring of s in which the letters occur in alphabetical order. For example, if s = ‘azcbobobegghakl’, then your program should print
“Longest substring in alphabetical order is: beggh”
In the case of ties, print the first substring. For example, if s = ‘abcbcd’, then your program should print
“Longest substring in alphabetical order is: abc”

4. 【疑问解决】Problem 2: Paying Debt Off In a Year (15 满分)

Now write a program that calculates the minimum fixed monthly payment needed in order pay off a credit card balance within 12 months. By a fixed monthly payment, we mean a single number which does not change each month, but instead is a constant amount that will be paid each month.

In this problem, we will not be dealing with a minimum monthly payment rate.

The following variables contain values as described below:

balance - the outstanding balance on the credit card

annualInterestRate - annual interest rate as a decimal

The program should print out one line: the lowest monthly payment that will pay off all debt in under 1 year, for example:

Lowest Payment: 180

Assume that the interest is compounded monthly according to the balance at the end of the month (after the payment for that month is made). The monthly payment must be a multiple of $10 and is the same for all months. Notice that it is possible for the balance to become negative using this payment scheme, which is okay. A summary of the required math is found below:

Monthly interest rate = (Annual interest rate) / 12.0
Monthly unpaid balance = (Previous balance) - (Minimum monthly payment)
Updated balance each month = (Monthly unpaid balance) + (Monthly interest rate x Monthly unpaid balance)

我是用数学方法先自己手算出了公式:
u b 12 = ( 1 + r 12 ) 11 b 0 ( 1 + r 1 + r 2 + . . . . . . . + r 10 + r 11 ) P ub_{12}=(1+\frac{r}{12})^{11}*b_0 - (1+r_1+r_2+.......+r_{10}+r_{11})*P

然后直接用此公式敲了代码,希望能知道有没有直接用代码解决的?

balance = 3926
annualInterestRate = 0.2
r = 1.0 + annualInterestRate/12
p = 10
tr = 0.0
ub = balance
for i in range(12):
    tr = tr + r**i
while ub >= 0:
    p = p + 10
    ub = r**11 * balance - tr * p

print('Lowest Payment: '+ str(p))

【修订见后】自己尝试写了一下直接用代码来计算的,陷入for循环中无法自拔了,有待研究:

balance = 3926
annualInterestRate = 0.2
r = 1.0 + annualInterestRate/12
p = 10
b = balance
ub = b - p
while ub >= 0:
    for i in range(1,12):
        b =  ub * r
        ub = b - p
        i = i + 1
        print('ub= '+ str(ub))
    p = p + 10
print('Lowest Payment: '+ str(p))

【修订版】参考了别人的答案,将b=balance这一步移至了while语句中便解决了,原理尚未知。

balance = 3926
annualInterestRate = 0.2
r = 1.0 + annualInterestRate/12.0
p = 0
b = 1
while b >= 0:
    p += 10
    b = balance    
    for i in range(1,12):
        b =  (b-p) * r
        print(str(b))
    
print('Lowest Payment: '+ str(p))

上述两段代码的差别在于,当把b=balance放在while外面时,只是一个初始值,那么每次进while循环的b都是在for循环一遍之后被修改过了的值,所以并不是我想要的。当把b=balance放在while中时,才能保证每一次for循环开始是b的值为balance的值。所以我之前写的代码并未正确的表达题目逻辑。

二分法计算:

balance = 320000
annualInterestRate = 0.2
r = 1.0 + annualInterestRate/12
lo = balance/12
hi = balance * (1+annualInterestRate/12.0)**12 / 12.0
p = (lo+hi)/2.0
epsilon = 0.001
tr = 0.0

for i in range(12):
    tr = tr + r**i
    
ub = r**11 * balance - tr * p

while abs(ub) >= epsilon:
    if ub < 0:
        hi = p
    else :
        lo = p
    p = (lo+hi)/2.0
    ub = r**11 * balance - tr * p
p = float('%.2f' % p) 
print('Lowest Payment: '+ str(p))

一开始总是陷入全局变量p的值不改变,造成hi=lo而ub无法取到足够小的尴尬情境中,后来不知怎么的就好了…
新学习了一个保留小数的方法:
float(’%.2f’ % p) 或 print(’%.2f’ % p),2是指保留两位小数,用途应该是与round(p,2)类似的。

猜你喜欢

转载自blog.csdn.net/qq_43198462/article/details/93718579