美文网首页python热爱者Python新世界
百道Python入门级练习题(新手友好)第四回合——求矩阵各列最

百道Python入门级练习题(新手友好)第四回合——求矩阵各列最

作者: 轻松学Python111 | 来源:发表于2018-10-19 21:49 被阅读5次

题目描述

【问题描述】
编写程序实现:用3*5的整型矩阵a接收标准输入的数据,计算数组a的每列元素的最大值,并将第i列最大值存入max相应的第i个元素。
【输入形式】
标准输入的每一行表示矩阵a中的一行数据,以空格作为间隔。
【输出形式】
标准输出的一行表示max中的元素,用空格作为间隔;若输入数据不合法(如:小数或某一行数据少于5个),则输出”illegal input”。
【样例输入】
1 2 3 4 5
6 7 8 9 0
3 5 7 9 1
【样例输出】
6 7 8 9 5

知识点

矩阵
整数矩阵的输入
遍历矩阵元素
for循环

解法

下面的讲解分两步,首先讲不考虑非法输入的解法;接着讲考虑非法输入的解法。 你做题的时候,也可以分步骤完成解题。这是值得借鉴的解题技巧。Python学习资料或者需要代码、视频加这个群吧548加上377还有875 都在这里了。

不考虑非法输入的解法

1. 输入矩阵

imtx = [] #定义矩阵
for r in range(3): #循环3次,每次读入一行
#输入第r+1行row
row = [] #准备row列表,用来存储一行
line = input() #读入一行
n_strs = line.split() #['1', '2', '3', '4', '5']

for s in n_strs:
    t = int(s)
    row.append(t)   #row = [1, 2, 3, 4, 5]
# print("row=", row)
imtx.append(row)

print(imtx)

2. 求各列最大值

zdz_list = []
for c in range(5):
#求第c+1列的最大值
zdz = imtx[0][c]
for r in range(1, 3):
if imtx[r][c] > zdz:
zdz = imtx[r][c]

zdz_list.append(zdz)

3. 输出各列最大值

for n in zdz_list:
print(n, end=' ')1234567891011121314151617181920212223242526272829

对以上程序代码,说明如下:

  1. 程序分3大步。标有1, 2, 3的注释行描述其后各行代码的作用。

    1. 输入矩阵

    2. 求各列最大值

    3. 输出各列最大值

  2. 第1大步是输入矩阵。你要熟悉这段代码。可以多读几遍,写几遍。下面给出一个有问题的写法。

imtx = [] #定义矩阵
for r in range(3): #循环3次,每次读入一行
#输入第r+1行row
row = [] #准备row列表,用来存储一行
line = input() #读入一行
n_strs = line.split() #['1', '2', '3', '4', '5']

c = 0
for s in n_strs:
    t = int(s)
    imtx[r][c] = t
    c += 1123456789101112

这一段代码问题在于,imtx是空列表,imtx[r][c] = t 这一行有错误,因为imtx[r]这个元素是不存在的,也没有它的存储空间。这与Java, C/C++有点不一样,后两种语言会预定义一个3行4列的矩阵,即使元素没有存进去,元素是有存储空间的。

  1. 第17行,zdz_list用来存储各列的最大值。由于有多个最大值,所以要用到列表。
  2. 第18行到第25行,构成外层for循环。外层for循环执行一轮,就求得矩阵的一列的最大值。第25行把所求得的最大值加入到zdz_list尾部。
  3. zdz用来保存当前列(正在计算最大值的列)的最大值。第20行把zdz初始化为该列的第一个元素的值。我们不能把zdz初始化为0,这有可能得到错误的最大值。假如,当前列矩阵元素的值都小于0,那么我们得到了错误的最大值,即0。
  4. 第21到23行,构成内层for循环。内层for循环执行一轮,就拿zdz的值,即当前的最大值,与当前列的下一行元素比较。
  5. 第29行,print函数的第2个参数“end= ’ ’ ”的意图是向print函数的名字叫做end的参数传递空格字符(’ ‘),作用是在输出元素的值的时候,其后跟一个空格。假如没有第2个参数,那么在输出元素的值的时候,其后会跟一个换行符,产生换行输出效果。

考虑非法输入的解法

有两种非法输入需要考虑。第一种是输入的一行不足5个元素。第二种是输出的某个元素不是整数。
如何检查第一种非法输入呢?我们可以在调用input()输入一行,接着调用split函数把该行切分成多个元素后,看这一行是否少于5个元素。如果少于5个,就得出非法输入的结论。

如何检查第二种非法输入呢?我们要在把每个字符串类型的元素转换成整数类型的元素之前,检查这个字符串类型的元素是否构成合法的整数写法。比如,“30”, “-30”是合法的写法,而“5.8”则不是合法的写法。我们的判断方法是,
  if (字符串是否以负号打头) {
    if (负号之后的字符都是数字) {
       是合法的整数写法
    } else {
      不是合法的整数写法
    }
  } else {
    if (所有字符都是数字) {
       是合法的整数写法
    } else {
      不是合法的整数写法
    }
  }

最后的代码版本如下。

s是一个十进制整数吗

def is_decimal_num(s):
s = s.strip()
if s[0] == '-':
return s[1:].isdigit() #isdigit(): 判断字符串是否都由数字0~9组成
else:
return s.isdigit() #1a5

1. 输入矩阵

imtx = [] #定义矩阵
for r in range(3): #循环3次,每次读入一行
#输入第r+1行row
row = [] #准备row列表,用来存储一行
line = input() #读入一行
n_strs = line.split() #['1', '2', '3', '4', '5']
print(n_strs)
if len(n_strs) < 5:
print("illegal input")
exit(0) #退出程序
for s in n_strs:
if not is_decimal_num(s):
print("illegal input")
exit(0) #退出程序
t = int(s)
row.append(t) #row = [1, 2, 3, 4, 5]
# print("row=", row)
imtx.append(row)

print(imtx)

2. 求各列最大值

zdz_list = []
for c in range(5):
#求第c+1列的最大值
zdz = imtx[0][c]
for r in range(1, 3):
if imtx[r][c] > zdz:
zdz = imtx[r][c]

zdz_list.append(zdz)

3. 输出各列最大值

for n in zdz_list:
print(n, end=' ')1234567891011121314151617181920212223242526272829303132333435363738394041424344

对上述代码,简要说明如下:

  1. 第18到20行,检查一行中的元素个数是否小于5。如果是,那么打印”inllegal input”,接着执行第20行的exit()函数,退出程序。退出程序意味着不会在执行其他代码。
  2. 第22到24行,检查输入的元素是否是合法的整数写法。我们定义了一个函数is_decimal_num来判别字符串s是否是合法的整数写法。该函数返回True,意味着是合法的写法。该函数返回False,意味着是非法的写法,此时not is_decimal_num(s)为真,执行第23,24行。第24行的exit()函数执行后,程序退出。
  3. 第1到7行定义了函数is_decimal_num。第2行,def是定义函数的开头,是固定的写法。关于函数的定义,暂不多做介绍。s.isdigit()的作用是判断字符串s内的所有字符是不是由数字组成,是则返回True,否则返回False。

小结

一小步一小步地编写程序是一个好办法。
典型的代码,可以多读多写,直至熟练。
Python有numpy工具包来支持矩阵的表示和运算,既简便又高效。

相关文章

网友评论

    本文标题:百道Python入门级练习题(新手友好)第四回合——求矩阵各列最

    本文链接:https://www.haomeiwen.com/subject/dxouzftx.html