遍历3D数组添加容器ID时出现重复值问题求助
Ship[4] 3D数组重复值问题排查与修复
问题背景
需要将容器ID写入ship[4]三维数组的指定(i,j,k)位置,实现相关函数后,测试发现ship[4]中出现大量重复值,需定位并解决该问题。
实现代码
核心函数
def addContainerOnShip(ship,container): place = findPlace(ship,container) if place == False: return False ship[3].append(container) id = getIdContainer(container) deck = place[0][0] row = place[0][1] position1 = place[0][2] if len(place) == 2: position2 = place[1][2] ship[4][deck][row][position1] = id ship[4][deck][row][position2] = id elif len(place) == 1: ship[4][deck][row][position1] = id else: return False return True def findPlace(ship, container): #rowsene øker ikke. for i in range(getHeightShip(ship)-1): deck = ship[4][i] if getLengthContainer(container) == 20: for j in range(getWidthShip(ship)): row = deck[j] for k in range(getLengthShip(ship)-1): position = row[k] if position == 0 and isContainerBelow(ship, [i, j, k]): return [[i, j, k]] #doble lister fordi den kjører på to elementer k+=1 elif getLengthContainer(container) == 40: for j in range(getWidthShip(ship)): row = deck[j] for k in range(getLengthShip(ship)-2): position1 = row[k] position2 = row[k+1] if (position1 == 0 and position2 == 0 and isContainerBelow(ship, [i,j,k]) and isContainerBelow(ship, [i,j,k+1])): return [[i, j, k],[i, j, k+1]] k+=1 else: return False def isContainerBelow(ship, position): deck = position[0] row = position[1] place = position[2] positionBelow = ship[4][deck-1][row][place] if deck == 0: return True elif positionBelow == 0: #there is nothing under here return False else: return True
测试代码与输出
测试代码
randomContainers(containers) #随机生成10个容器 skip1 = NewShip(6,5,4) makeDeck(skip1) con = NewContainer(1111,40,3) sortContainersWeight(containers) for el in containers: print(el) print(addContainerOnShip(skip1,el)) print(findPlace(skip1,con)) print(skip1[4])
输出结果
[307813, 20, 2, 0, 2] True [[0, 0, 1], [0, 0, 2]] [3779799, 20, 2, 2, 4] True [[0, 0, 2], [0, 0, 3]] [9725995, 20, 2, 6, 8] True [[0, 0, 3], [0, 0, 4]] [7275339, 40, 4, 6, 10] True [[1, 0, 0], [1, 0, 1]] [4210939, 40, 4, 8, 12] True [[1, 0, 2], [1, 0, 3]] [2058645, 40, 4, 11, 15] True [[1, 1, 0], [1, 1, 1]] [4558888, 20, 2, 13, 15] True [[1, 1, 0], [1, 1, 1]] [9093612, 40, 4, 16, 20] True [[1, 1, 2], [1, 1, 3]] [2733982, 20, 2, 19, 21] True [[1, 1, 3], [1, 1, 4]] [6156045, 20, 2, 22, 24] True [[1, 2, 0], [1, 2, 1]] [[[307813, 3779799, 9725995, 7275339, 7275339], [307813, 3779799, 9725995, 7275339, 7275339], [307813, 3779799, 9725995, 7275339, 7275339], [307813, 3779799, 9725995, 7275339, 7275339], [307813, 3779799, 9725995, 7275339, 7275339], [307813, 3779799, 9725995, 7275339, 7275339]], [[4210939, 4210939, 2058645, 2058645, 4558888], [9093612, 9093612, 2733982, 6156045, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]], [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]], [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]
问题定位
- 数组初始化引用重复:输出显示ship[4]第一个甲板的所有行内容完全一致,原因是
makeDeck初始化时所有行复用了同一个列表对象,修改任意一行都会同步影响其他行。 - findPlace循环逻辑错误:遍历位置时手动执行
k +=1,叠加for循环的自动递增,导致k每次增加2,跳过大量位置,同时可能错误重复选择区域。 - 甲板遍历范围错误:
for i in range(getHeightShip(ship)-1)会跳过最后一个甲板,导致容器无法被放置到上层甲板。
修复方案
1. 修复makeDeck的数组初始化
确保每个行都是独立列表,避免引用复用:
def makeDeck(ship): height = getHeightShip(ship) width = getWidthShip(ship) length = getLengthShip(ship) ship[4] = [] for _ in range(height): deck = [] for _ in range(width): # 为每行创建独立的初始列表 deck.append([0]*length) ship[4].append(deck)
2. 修复findPlace的循环逻辑
移除手动k +=1,修正遍历范围:
def findPlace(ship, container): # 遍历所有甲板,从底层开始 for i in range(getHeightShip(ship)): deck = ship[4][i] if getLengthContainer(container) == 20: for j in range(getWidthShip(ship)): row = deck[j] # 遍历所有合法位置 for k in range(getLengthShip(ship)): position = row[k] if position == 0 and isContainerBelow(ship, [i, j, k]): return [[i, j, k]] elif getLengthContainer(container) == 40: for j in range(getWidthShip(ship)): row = deck[j] # 遍历到倒数第二个位置即可 for k in range(getLengthShip(ship)-1): position1 = row[k] position2 = row[k+1] if (position1 == 0 and position2 == 0 and isContainerBelow(ship, [i,j,k]) and isContainerBelow(ship, [i,j,k+1])): return [[i, j, k],[i, j, k+1]] else: return False
3. 完善isContainerBelow的边界处理
避免deck=0时访问非法索引,逻辑更严谨:
def isContainerBelow(ship, position): deck = position[0] row = position[1] place = position[2] if deck == 0: return True # 确保下层甲板索引合法 if deck-1 < 0 or deck-1 >= len(ship[4]): return False positionBelow = ship[4][deck-1][row][place] return positionBelow != 0
验证修复
重新运行测试代码,ship[4]的各行列应仅在对应位置出现容器ID,不再出现全行列重复的情况。
内容的提问来源于stack exchange,提问作者marfin
相关产品推荐
相关产品推荐

