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

  • ·         Test Report
  • ·         测试报告
 

2

  • ·         Size Measurement
  • ·         计算工作量
 

2

  • ·         Postmortem & Process Improvement Plan
  • ·         事后总结, 并提出过程改进计划
 

10

总结

由于进入大学之后没有搞过ACM,在解决这个问题的时候非常得吃力,对于群里大家提出的想法也只能是不明觉厉,希望能够在接下来的课程中多多提高吧。

posted @ 2013-09-30 16:21  比企鹅  阅读(160)  评论(1编辑  收藏  举报