homework-02 "最大子数组之和"的问题进阶
代码编写
这次的作业瞬间难了好多,无论是问题本身的难度或者是单元测试这一原来没接触过的概念或者是命令行参数的处理这些琐碎的问题,都使得这次作业的完成说不上轻松。
最大子数组之和垂直水平相连的拓展问题解决关键在于循环语句的适度改写,连通问题则是用递归搜索的方法来解决(效率没有实测),在15*15的情况下还是能较快得出结果的。
非常庆幸使用的是Python,Pyhton中很多语法能够保证我在编写代码时不用分太多的时间去处理数据输入,在处理问题上一些数组相关灵活的语法也很大程度上方便了代码的编写。
1 # coding:utf-8 2 ''' 3 2013-9-30 XTH 4 ''' 5 import sys 6 7 def setglobalvar(): 8 global max_sum,now_sum,min_x,min_y,num,visited,pointgroup 9 max_sum = 0 10 now_sum = 0 11 min_x = 0 12 min_y = 0 13 num = [] 14 visited = {} 15 pointgroup = [] 16 17 def maxsum_h(num,n1,n2):#水平上相连 18 line = [0]*n2 19 max_sum = 0 #最大和 20 now_sum = 0 #当前和 21 for l in range (0,n2): 22 for i in range(0,n1): 23 for j in range(i,n1): 24 for k in range(0+l,n2+l): 25 k = k % n2 26 line[k] += num[j][k] 27 if now_sum <0: 28 now_sum = 0 29 now_sum += line[k] 30 if now_sum > max_sum: 31 max_sum = now_sum 32 now_sum = 0 33 now_sum=0 34 line = [0]*n2 35 return max_sum 36 37 def maxsum_v(num,n1,n2): #垂直上相连 38 line = [0]*n2 39 max_sum = 0 #最大和 40 now_sum = 0 #当前和 41 for l in range (0,n1): 42 for i in range(0,n1): 43 for j in range(i+l,n1+l): 44 for k in range(0,n2): 45 j = j % n1 46 line[k] += num[j][k] 47 if now_sum <0: 48 now_sum = 0 49 now_sum += line[k] 50 if now_sum > max_sum: 51 max_sum = now_sum 52 now_sum = 0 53 now_sum=0 54 line = [0]*n2 55 return max_sum 56 57 58 def maxsum(num,n1,n2):#普通 59 line = [0]*n2 60 max_sum = 0 #最大和 61 now_sum = 0 #当前和 62 for i in range(0,n1): 63 for j in range(i,n1): 64 for k in range(0,n2): 65 line[k] += num[j][k] 66 if now_sum <0: 67 now_sum = 0 68 now_sum += line[k] 69 if now_sum > max_sum: 70 max_sum = now_sum 71 now_sum = 0 72 now_sum=0 73 line = [0]*n2 74 return max_sum 75 76 77 def maxsum_vh(num,n1,n2):#垂直水平相连 78 line = [0]*n2 79 max_sum = 0 #最大和 80 now_sum = 0 #当前和 81 for l1 in range (0,n1): 82 for l2 in range (0,n2): 83 for i in range(0,n1): 84 for j in range(i+l1,n1+l1): 85 for k in range(0+l2,n2+l2): 86 j = j % n1 87 k = k % n2 88 line[k] += num[j][k] 89 if now_sum <0: 90 now_sum = 0 91 now_sum += line[k] 92 if now_sum > max_sum: 93 max_sum = now_sum 94 now_sum = 0 95 now_sum=0 96 line = [0]*n2 97 return max_sum 98 99 def searchthrough(x,y,num,now_sum):#搜索函数 100 global max_sum,pointgroup,min_x,min_y,visited 101 max_sum = max(max_sum, now_sum) 102 for i in [[0,-1],[1,0],[0,1],[-1,0]]: 103 if x+i[0]>=min_x and x+i[0]<n1 and y+i[1]>=min_y and y+i[1]<n2 and visited[(x+i[0])%n1,(y+i[1])%n2]==0 and [(x+i[0])%n1,(y+i[1])%n2,num[(x+i[0])% n1][(y+i[1])%n2]] not in pointgroup: 104 pointgroup.append([(x + i[0]) % n1, (y + i[1]) % n2, num[(x + i[0]) % n1][(y + i[1]) % n2]]) 105 if pointgroup == []: 106 return 107 pointgroup = sorted(pointgroup, key=lambda x: x[2]) 108 nextpoint = pointgroup.pop() 109 if now_sum + nextpoint[2] > 0: 110 visited[nextpoint[0], nextpoint[1]] = 1 111 searchthrough(nextpoint[0],nextpoint[1],num,now_sum + nextpoint[2]) 112 visited[nextpoint[0], nextpoint[1]] = 0 113 else: 114 return 115 116 def maxsum_a(num,n1,n2): #连通 117 global min_x,min_y,max_sum,visited 118 min_x = 0 119 min_y = 0 120 max_sum = 0 121 now_sum = 0 122 startpointx = [] 123 startpointy = [] 124 pointgroup = [] 125 for i in range(0,n1): 126 for j in range(0,n2): 127 visited[i,j] = 0 128 for i in range(0,n1): 129 for j in range(0,n2): 130 if num[i][j] > 0: 131 startpointx.append(i) 132 startpointy.append(j) 133 for pointx in startpointx: 134 pointy = startpointy.pop() 135 visited[pointx, pointy] = 1 136 searchthrough(pointx,pointy,num,num[pointx][pointy]) 137 return max_sum 138 139 def maxsum_vha(num,n1,n2): #水平垂直上相连 连通 140 global min_x,min_y,max_sum,visited 141 min_x = -n1 142 min_y = -n2 143 max_sum = 0 144 now_sum = 0 145 startpointx = [] 146 startpointy = [] 147 pointgroup = [] 148 for i in range(0,n1): 149 for j in range(0,n2): 150 visited[i,j] = 0 151 for i in range(0,n1): 152 for j in range(0,n2): 153 if num[i][j] > 0: 154 startpointx.append(i) 155 startpointy.append(j) 156 for pointx in startpointx: 157 pointy = startpointy.pop() 158 visited[pointx, pointy] = 1 159 searchthrough(pointx,pointy,num,num[pointx][pointy]) 160 return max_sum 161 162 def main(): 163 setglobalvar() 164 global n1,n2 165 max_sum = 0 166 V = H = A = False 167 if "\\v" in sys.argv[1:]: 168 V = True; 169 if "\\h" in sys.argv[1:]: 170 H = True; 171 if "\\a" in sys.argv[1:]: 172 A = True; 173 filename = sys.argv[-1]; 174 try: 175 f = open(filename,"r") 176 except: 177 raise IOError("ERROR:can't open the file") 178 try: 179 line = f.readline() 180 line = line.strip('\n').strip(',') 181 n1 = int(line) 182 line = f.readline() 183 line = line.strip('\n').strip(',') 184 n2 = int(line) 185 num=[[]]*int(n1) 186 for i in range(0,int(n1)): 187 line = f.readline() 188 line = line.strip('\n') 189 if len(line.split(",")) != n2: 190 raise ValueError("ERROR:the format of file is wrong") 191 num[i] = line.split(",") 192 num=[[int(x) for x in inner] for inner in num] 193 except: 194 raise ValueError("ERROR:the format of file is wrong") 195 if V!=True and H!=True and A == True:#连通 196 max_sum = maxsum_a(num,n1,n2); 197 elif V==True and H!=True and A != True:#水平上相连 198 max_sum = maxsum_v(num,n1,n2); 199 elif V!=True and H==True and A != True:#垂直上相连 200 max_sum = maxsum_h(num,n1,n2); 201 elif V==True and H==True and A != True:#水平垂直上相连 202 max_sum = maxsum_vh(num,n1,n2); 203 elif V==True and H==True and A == True:#水平垂直上相连连通 204 max_sum = maxsum_vha(num,n1,n2); 205 else:#普通 206 max_sum = maxsum(num,n1,n2); 207 return max_sum 208 209 210 211 if __name__ == '__main__': 212 print main()
单元测试
我大概明白单元测试的概念,但是本次问题很难被看做是一个模块,写单元测试的时候也无从下手,只是简单地测试了一下命令行参数的处理、以及样例的结果验证。
项目时间
PSP2.1 |
Personal Software Process Stages |
Time (%) Senior Student |
Planning |
计划 |
6 |
· Estimate |
· 估计这个任务需要多少时间 |
6 |
Development |
开发 |
80 |
· Analysis |
· 需求分析 (包括学习新技术) |
10 |
· Design Spec |
· 生成设计文档 |
0 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
0 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
0 |
· Design |
· 具体设计 |
15 |
· Coding |
· 具体编码 |
40 |
· Code Review |
· 代码复审 |
5 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
10 |
Reporting |
报告 |
14 |
|
2 |
|
|
2 |
|
|
10 |
总结
由于进入大学之后没有搞过ACM,在解决这个问题的时候非常得吃力,对于群里大家提出的想法也只能是不明觉厉,希望能够在接下来的课程中多多提高吧。