Files
house/house_service最终版.py
T
2026-06-30 19:55:10 +08:00

466 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from house_operation import *
from datetime import datetime
# v1
def get_next_house_id():
houses = read_houses()
if not houses:
return 1
max_id = max(house["id"] for house in houses)
return max_id + 1
def add_house(address, price, area, house_type):
if not address or not house_type:
print("错误:地址和户型不能为空!")
return False
if not isinstance(price, (int, float)) or price <= 0:
print("错误:租金必须是正数!")
return False
if not isinstance(area, (int, float)) or area <= 0:
print("错误:面积必须是正数!")
return False
new_house = {
"id": get_next_house_id(),
"address": address,
"price": price,
"area": area,
"house_type": house_type
}
houses = read_houses()
houses.append(new_house)
write_houses(houses)
print(f"房源新增成功!房源ID{new_house['id']}")
return True
def delete_house(house_id):
houses = read_houses()
for index, house in enumerate(houses):
if house["id"] == house_id:
del houses[index]
write_houses(houses)
print(f"房源ID {house_id} 删除成功!")
return True
print(f"错误:未找到房源ID {house_id}")
return False
def update_house(house_id, new_info):
houses = read_houses()
for house in houses:
if house["id"] == house_id:
for key, value in new_info.items():
if key in ["address", "price", "area", "house_type"]:
if key in ["price", "area"]:
if not isinstance(value, (int, float)) or value <= 0:
print(f"错误:{key}必须是正数!")
return False
house[key] = value
write_houses(houses)
print(f"房源ID {house_id} 修改成功!")
return True
print(f"错误:未找到房源ID {house_id}")
return False
def query_house(condition_type, condition_value):
houses = read_houses()
result = []
for house in houses:
if condition_type == "id":
if house["id"] == int(condition_value):
result.append(house)
elif condition_type == "address":
if condition_value in house["address"]:
result.append(house)
elif condition_type == "house_type":
if house["house_type"] == condition_value:
result.append(house)
elif condition_type == "price":
if house["price"] == float(condition_value):
result.append(house)
else:
print("错误:不支持的查询条件类型!")
return []
return result
# v2
MAX_STACK_LENGTH = 100
def push_operation_stack(operation_info):
time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
full_info = f"[{time_str}] {operation_info}"
stack = read_stack("operation")
stack.append(full_info)
if len(stack) > MAX_STACK_LENGTH:
stack.pop(0)
write_stack("operation", stack)
def push_browse_stack(house_id):
stack = read_stack("browse")
if stack and stack[-1] == house_id:
return
stack.append(house_id)
if len(stack) > MAX_STACK_LENGTH:
stack.pop(0)
write_stack("browse", stack)
def pop_operation_stack():
stack = read_stack("operation")
if not stack:
return None
latest_op = stack.pop()
write_stack("operation", stack)
return latest_op
def pop_browse_stack():
stack = read_stack("browse")
if not stack:
return None
latest_hid = stack.pop()
write_stack("browse", stack)
return latest_hid
def get_recent_records(stack_type, limit=10):
stack = read_stack(stack_type)
return stack[-limit:][::-1]
def clear_stack(stack_type):
write_stack(stack_type, [])
print(f"{stack_type}记录已清空!")
#v3
def parse_address_string(full_address):
"""解析完整地址字符串:拆分省、市、区、小区"""
parts = full_address.split("市")
province_city = parts[0] + "市" if "市" in full_address else parts[0]
if "省" in province_city:
province, city = province_city.split("省")
province += "省"
city += "市"
else:
province = "未知省份"
city = province_city
if len(parts) > 1:
district_part = parts[1]
if "区" in district_part or "县" in district_part:
district, community = district_part.split("区") if "区" in district_part else district_part.split("县")
district += "区" if "区" in district_part else "县"
else:
district = "未知区县"
community = district_part
else:
district = "未知区县"
community = "未知小区"
return {
"province": province,
"city": city,
"district": district,
"community": community
}
def fuzzy_query_by_district(keyword):
"""根据区域关键词模糊匹配所有房源"""
houses = read_houses()
result = []
for house in houses:
addr_info = parse_address_string(house["address"])
if keyword in addr_info["district"] or keyword in addr_info["community"]:
result.append(house)
return result
def init_community_matrix(community_name_list):
"""初始化小区距离邻接矩阵"""
INF = float("inf")
n = len(community_name_list)
distance_matrix = [[INF] * n for _ in range(n)]
for i in range(n):
distance_matrix[i][i] = 0
matrix_data = {
"community_list": community_name_list,
"distance_matrix": distance_matrix
}
write_matrix_data(matrix_data)
print("邻接矩阵初始化完成!")
def update_matrix_distance(community_a, community_b, distance):
"""更新两个小区之间的距离"""
matrix_data = read_matrix_data()
community_list = matrix_data["community_list"]
distance_matrix = matrix_data["distance_matrix"]
try:
idx_a = community_list.index(community_a)
idx_b = community_list.index(community_b)
distance_matrix[idx_a][idx_b] = distance
distance_matrix[idx_b][idx_a] = distance
write_matrix_data(matrix_data)
print(f"{community_a} <-> {community_b} 距离更新成功!")
except ValueError:
print("小区名称不存在!")
#v4
class HouseBSTNode:
"""
二叉查找树节点:按指定字段(租金/面积)作为键值
"""
def __init__(self, house_data, key_field="price"):
self.key = house_data[key_field] # 排序键(租金/面积)
self.house = house_data # 房源完整数据
self.left = None # 左子节点(键值更小)
self.right = None # 右子节点(键值更大)
# V4.0 新增:二叉查找树核心操作
def build_house_bst(houses, key_field="price"):
"""
构建房源二叉查找树(按租金/面积)
时间复杂度:O(n log n)(最优/平均),O(n²)(最坏,有序数据)
"""
if not houses:
return None
# 选第一个元素作为根节点
root = HouseBSTNode(houses[0], key_field)
# 逐个插入剩余节点
for house in houses[1:]:
insert_bst_node(root, house, key_field)
return root
def insert_bst_node(root, house_data, key_field="price"):
"""
向二叉查找树插入节点
时间复杂度:O(log n)(平均),O(n)(最坏)
"""
current = root
while True:
# 键值小于当前节点,走左子树
if house_data[key_field] < current.key:
if current.left is None:
current.left = HouseBSTNode(house_data, key_field)
break
else:
current = current.left
# 键值大于等于当前节点,走右子树
else:
if current.right is None:
current.right = HouseBSTNode(house_data, key_field)
break
else:
current = current.right
def inorder_bst_traversal(root, result_list):
"""
二叉查找树中序遍历(输出有序列表)
时间复杂度:O(n)(遍历所有节点)
"""
if root is not None:
inorder_bst_traversal(root.left, result_list)
result_list.append(root.house)
inorder_bst_traversal(root.right, result_list)
def search_bst_range(root, min_val, max_val, key_field="price", result_list=None):
"""
二叉查找树范围查询(如:租金5000-8000)
时间复杂度:O(log n + k)(k为符合条件的节点数)
"""
if result_list is None:
result_list = []
if root is None:
return result_list
# 若当前键值大于最小值,遍历左子树
if root.key > min_val:
search_bst_range(root.left, min_val, max_val, key_field, result_list)
# 若当前键值在范围内,加入结果
if min_val <= root.key <= max_val:
result_list.append(root.house)
# 若当前键值小于最大值,遍历右子树
if root.key < max_val:
search_bst_range(root.right, min_val, max_val, key_field, result_list)
return result_list
def bubble_sort_houses(houses, sort_field="price", reverse=False):
"""
V4.0新增 排序知识点
冒泡排序:按指定字段(租金/面积)排序
时间复杂度:O(n²)(稳定排序)
"""
n = len(houses)
# 深拷贝避免修改原列表
sorted_houses = [h.copy() for h in houses]
for i in range(n):
swapped = False
for j in range(0, n - i - 1):
if sorted_houses[j][sort_field] > sorted_houses[j + 1][sort_field]:
# 交换元素
sorted_houses[j], sorted_houses[j + 1] = sorted_houses[j + 1], sorted_houses[j]
swapped = True
# 无交换则提前退出
if not swapped:
break
# 降序反转
if reverse:
sorted_houses = sorted_houses[::-1]
return sorted_houses
def quick_sort_houses(houses, sort_field="price", reverse=False):
"""
V4新增 排序知识点
快速排序:按指定字段(租金/面积)排序
时间复杂度:O(n log n)(平均),O(n²)(最坏)
"""
if len(houses) <= 1:
return houses
# 深拷贝避免修改原列表
sorted_houses = [h.copy() for h in houses]
# 选第一个元素作为基准
pivot = sorted_houses[0][sort_field]
left = [h for h in sorted_houses[1:] if h[sort_field] <= pivot]
right = [h for h in sorted_houses[1:] if h[sort_field] > pivot]
# 递归排序
result = quick_sort_houses(left, sort_field) + [sorted_houses[0]] + quick_sort_houses(right, sort_field)
# 降序反转
if reverse:
result = result[::-1]
return result
#V5
def print_community_graph():
"""
文本形式可视化小区图(邻接矩阵)
时间复杂度:O(n²),n为小区数量
"""
matrix_data = read_matrix_data()
community_list = matrix_data["community_list"]
distance_matrix = matrix_data["distance_matrix"]
if not community_list:
print("暂无小区图数据!请先初始化邻接矩阵。")
return
# 打印表头
print("\n===== 小区距离图(邻接矩阵) =====")
print(" " + " ".join([c[:4].ljust(4) for c in community_list]))
# 打印每行数据
for i, community in enumerate(community_list):
row_str = community[:4].ljust(4)
for j in range(len(community_list)):
val = distance_matrix[i][j]
if val == float("inf"):
row_str += " ∞ "
else:
row_str += f"{val:5.1f}"
print(row_str)
def dijkstra_shortest_path(start_community, end_community):
"""
Dijkstra算法:计算两个小区间的最短路径
时间复杂度:O(n²)(邻接矩阵实现),n为小区数量
return: (最短距离, 路径列表)
"""
matrix_data = read_matrix_data()
community_list = matrix_data["community_list"]
distance_matrix = matrix_data["distance_matrix"]
# 校验小区是否存在
if start_community not in community_list or end_community not in community_list:
print("起始/目标小区不存在!")
return (None, None)
n = len(community_list)
start_idx = community_list.index(start_community)
end_idx = community_list.index(end_community)
# 初始化距离数组和前驱节点数组
INF = float("inf")
dist = [INF] * n # 各节点到起点的距离
visited = [False] * n # 节点是否已访问
prev = [-1] * n # 前驱节点索引
dist[start_idx] = 0 # 起点到自己的距离为0
# 核心Dijkstra循环
for _ in range(n):
# 找到未访问的距离最小节点
min_dist = INF
u = -1
for i in range(n):
if not visited[i] and dist[i] < min_dist:
min_dist = dist[i]
u = i
if u == -1 or dist[u] == INF:
break # 无可达路径
visited[u] = True
# 松弛操作:更新邻接节点的距离
for v in range(n):
if not visited[v] and distance_matrix[u][v] != INF:
if dist[v] > dist[u] + distance_matrix[u][v]:
dist[v] = dist[u] + distance_matrix[u][v]
prev[v] = u
# 回溯路径
if dist[end_idx] == INF:
print(f"{start_community}{end_community} 无可达路径!")
return (None, None)
# 从终点回溯到起点
path = []
current = end_idx
while current != -1:
path.append(community_list[current])
current = prev[current]
path.reverse() # 反转得到正序路径
return (dist[end_idx], path)
def recommend_houses_by_path(target_community, max_distance):
"""
推荐目标小区最短距离≤max_distance的周边房源
"""
matrix_data = read_matrix_data()
community_list = matrix_data["community_list"]
if target_community not in community_list:
print("目标小区不存在!")
return []
# 计算目标小区到所有小区的最短路径
recommend_communities = []
for comm in community_list:
dist, _ = dijkstra_shortest_path(target_community, comm)
if dist is not None and dist <= max_distance:
recommend_communities.append(comm)
# 查询这些小区的房源
all_houses = read_houses()
recommend_houses = []
for house in all_houses:
addr_info = parse_address_string(house["address"])
if addr_info["community"] in recommend_communities:
recommend_houses.append(house)
return recommend_houses