上传文件至「/」

This commit is contained in:
2026-05-22 16:09:14 +08:00
parent e28face0b6
commit cf648f6bf9
3 changed files with 470 additions and 223 deletions
+39 -45
View File
@@ -1,83 +1,77 @@
import json import json
import os import os
# 以下为 V1.0 原有代码,完全未修改
# 定义数据文件路径
HOUSE_FILE = "./data/houses.json" HOUSE_FILE = "./data/houses.json"
def init_db(): def init_db():
""" """初始化房源数据文件"""
初始化数据文件:如果houses.json不存在,创建并写入空列表
空间复杂度:O(1)(仅创建空文件)
"""
# 确保data文件夹存在
os.makedirs("./data", exist_ok=True) os.makedirs("./data", exist_ok=True)
# 如果文件不存在,创建并写入空列表
if not os.path.exists(HOUSE_FILE): if not os.path.exists(HOUSE_FILE):
with open(HOUSE_FILE, 'w', encoding='utf-8') as f: with open(HOUSE_FILE, 'w', encoding='utf-8') as f:
json.dump([], f, ensure_ascii=False, indent=4) json.dump([], f, ensure_ascii=False, indent=4)
def read_houses(): def read_houses():
""" """读取所有房源"""
读取所有房源数据 init_db()
时间复杂度:O(n)(n为房源数,JSON解析耗时与数据量正相关)
空间复杂度:O(n)(存储所有房源数据)
return: 房源列表(每个元素是字典)
"""
init_db() # 先确保文件存在
with open(HOUSE_FILE, 'r', encoding='utf-8') as f: with open(HOUSE_FILE, 'r', encoding='utf-8') as f:
return json.load(f) return json.load(f)
def write_houses(houses): def write_houses(houses):
""" """写入房源"""
写入房源数据到JSON文件
时间复杂度:O(n)(n为房源数,JSON序列化耗时与数据量正相关)
空间复杂度:O(1)(仅写入操作,无额外存储)
param houses: 要写入的房源列表
"""
with open(HOUSE_FILE, 'w', encoding='utf-8') as f: with open(HOUSE_FILE, 'w', encoding='utf-8') as f:
json.dump(houses, f, ensure_ascii=False, indent=4) json.dump(houses, f, ensure_ascii=False, indent=4)
# V2.0 新增代码:栈数据读写
# V2.0 新增:栈数据文件配置
STACK_FILE = "./data/stack_data.json" STACK_FILE = "./data/stack_data.json"
# V2.0 新增:栈数据初始化与读写
def init_stack_db(): def init_stack_db():
""" """初始化栈文件"""
初始化栈数据文件:若不存在则创建,区分操作记录栈/浏览历史栈
"""
os.makedirs("./data", exist_ok=True) os.makedirs("./data", exist_ok=True)
if not os.path.exists(STACK_FILE): if not os.path.exists(STACK_FILE):
init_data = { init_data = {"operation_stack": [], "browse_stack": []}
"operation_stack": [],
"browse_stack": []
}
with open(STACK_FILE, 'w', encoding='utf-8') as f: with open(STACK_FILE, 'w', encoding='utf-8') as f:
json.dump(init_data, f, ensure_ascii=False, indent=4) json.dump(init_data, f, ensure_ascii=False, indent=4)
def read_stack(stack_type): def read_stack(stack_type):
""" """读取指定栈"""
读取指定类型的栈数据
:param stack_type: operation(操作记录)/ browse(浏览历史)
"""
init_stack_db() init_stack_db()
with open(STACK_FILE, 'r', encoding='utf-8') as f: with open(STACK_FILE, 'r', encoding='utf-8') as f:
data = json.load(f) data = json.load(f)
stack_key = f"{stack_type}_stack" return data.get(f"{stack_type}_stack", [])
return data.get(stack_key, [])
def write_stack(stack_type, new_stack): def write_stack(stack_type, new_stack):
""" """写入指定栈"""
写入指定类型的栈数据到文件
"""
init_stack_db() init_stack_db()
# 读取原有数据,避免覆盖另一个栈
with open(STACK_FILE, 'r', encoding='utf-8') as f: with open(STACK_FILE, 'r', encoding='utf-8') as f:
data = json.load(f) data = json.load(f)
stack_key = f"{stack_type}_stack" data[f"{stack_type}_stack"] = new_stack
data[stack_key] = new_stack
with open(STACK_FILE, 'w', encoding='utf-8') as f: with open(STACK_FILE, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4) json.dump(data, f, ensure_ascii=False, indent=4)
# V3.0 字符串+数组:邻接矩阵数据读写
MATRIX_FILE = "./data/matrix.json"
def init_matrix_db():
"""
新增:初始化小区邻接矩阵文件
存储所有小区名称列表 和 二维距离数组(邻接矩阵)
"""
os.makedirs("./data", exist_ok=True)
if not os.path.exists(MATRIX_FILE):
init_data = {
"community_list": [], # 小区名称列表(一维数组)
"distance_matrix": [] # 小区距离二维数组(邻接矩阵)
}
with open(MATRIX_FILE, 'w', encoding='utf-8') as f:
json.dump(init_data, f, ensure_ascii=False, indent=4)
def read_matrix_data():
"""V3.0新增读取小区列表和距离邻接矩阵"""
init_matrix_db()
with open(MATRIX_FILE, 'r', encoding='utf-8') as f:
return json.load(f)
def write_matrix_data(matrix_dict):
"""V3.0新增保存小区列表和距离邻接矩阵"""
init_matrix_db()
with open(MATRIX_FILE, 'w', encoding='utf-8') as f:
json.dump(matrix_dict, f, ensure_ascii=False, indent=4)
+131 -63
View File
@@ -1,32 +1,14 @@
from house.db_operation import read_houses, write_houses from house_operation import *
from datetime import datetime
def get_next_house_id(): def get_next_house_id():
"""
生成下一个房源ID(保证ID唯一)
时间复杂度:O(n)(遍历所有房源找最大ID)
return: 下一个可用的ID(整数)
"""
houses = read_houses() houses = read_houses()
if not houses: if not houses:
return 1 # 无房源时,第一个ID为1 return 1
# 找到最大ID,加1作为新ID
max_id = max(house["id"] for house in houses) max_id = max(house["id"] for house in houses)
return max_id + 1 return max_id + 1
def add_house(address, price, area, house_type): def add_house(address, price, area, house_type):
"""
新增房源(线性表的尾部插入操作)
时间复杂度:O(n)read/write各O(n),整体O(n)
空间复杂度:O(n)(存储所有房源数据)
param address: 房源地址(字符串)
param price: 租金(整数/浮点数)
param area: 面积(整数/浮点数)
param house_type: 户型(字符串,如"一居室"
return: 新增成功返回True,失败返回False
"""
# 基础数据校验(非空+数值合法性)
if not address or not house_type: if not address or not house_type:
print("错误:地址和户型不能为空!") print("错误:地址和户型不能为空!")
return False return False
@@ -37,7 +19,6 @@ def add_house(address, price, area, house_type):
print("错误:面积必须是正数!") print("错误:面积必须是正数!")
return False return False
# 构建新房源字典(线性表的元素)
new_house = { new_house = {
"id": get_next_house_id(), "id": get_next_house_id(),
"address": address, "address": address,
@@ -45,54 +26,29 @@ def add_house(address, price, area, house_type):
"area": area, "area": area,
"house_type": house_type "house_type": house_type
} }
# 读取现有房源(线性表),新增元素(尾部插入)
houses = read_houses() houses = read_houses()
houses.append(new_house) # 线性表append操作,时间复杂度O(1) houses.append(new_house)
# 写入文件
write_houses(houses) write_houses(houses)
print(f"房源新增成功!房源ID{new_house['id']}") print(f"房源新增成功!房源ID{new_house['id']}")
return True return True
def delete_house(house_id): def delete_house(house_id):
"""
删除房源(线性表的指定位置删除操作)
时间复杂度:O(n)(遍历找ID+写入文件,整体O(n))
空间复杂度:O(n)(存储所有房源数据)
param house_id: 要删除的房源ID(整数)
return: 删除成功返回True,失败返回False
"""
houses = read_houses() houses = read_houses()
# 遍历线性表,找到对应ID的房源
for index, house in enumerate(houses): for index, house in enumerate(houses):
if house["id"] == house_id: if house["id"] == house_id:
del houses[index] # 线性表删除操作,时间复杂度O(n)(后续元素前移) del houses[index]
write_houses(houses) write_houses(houses)
print(f"房源ID {house_id} 删除成功!") print(f"房源ID {house_id} 删除成功!")
return True return True
print(f"错误:未找到房源ID {house_id}") print(f"错误:未找到房源ID {house_id}")
return False return False
def update_house(house_id, new_info): def update_house(house_id, new_info):
"""
修改房源信息(线性表的指定元素更新操作)
时间复杂度:O(n)(遍历找ID+写入文件,整体O(n))
空间复杂度:O(n)(存储所有房源数据)
param house_id: 要修改的房源ID(整数)
param new_info: 要修改的字段字典(如{"price": 5500, "area": 85}
return: 修改成功返回True,失败返回False
"""
houses = read_houses() houses = read_houses()
# 遍历线性表,找到对应ID的房源
for house in houses: for house in houses:
if house["id"] == house_id: if house["id"] == house_id:
# 仅更新传入的有效字段
for key, value in new_info.items(): for key, value in new_info.items():
if key in ["address", "price", "area", "house_type"]: if key in ["address", "price", "area", "house_type"]:
# 校验数值字段合法性
if key in ["price", "area"]: if key in ["price", "area"]:
if not isinstance(value, (int, float)) or value <= 0: if not isinstance(value, (int, float)) or value <= 0:
print(f"错误:{key}必须是正数!") print(f"错误:{key}必须是正数!")
@@ -104,33 +60,19 @@ def update_house(house_id, new_info):
print(f"错误:未找到房源ID {house_id}") print(f"错误:未找到房源ID {house_id}")
return False return False
def query_house(condition_type, condition_value): def query_house(condition_type, condition_value):
"""
查询房源(线性表的遍历筛选操作)
时间复杂度:O(n)(遍历所有房源,n为房源数)
空间复杂度:O(k)(k为符合条件的房源数,最坏O(n))
param condition_type: 查询条件类型("id"/"address"/"price"/"house_type"
param condition_value: 查询条件值
return: 符合条件的房源列表
"""
houses = read_houses() houses = read_houses()
result = [] result = []
# 按条件遍历筛选
for house in houses: for house in houses:
# 处理ID查询(整数匹配)
if condition_type == "id": if condition_type == "id":
if house["id"] == int(condition_value): if house["id"] == int(condition_value):
result.append(house) result.append(house)
# 处理地址查询(模糊匹配)
elif condition_type == "address": elif condition_type == "address":
if condition_value in house["address"]: if condition_value in house["address"]:
result.append(house) result.append(house)
# 处理户型查询(精确匹配)
elif condition_type == "house_type": elif condition_type == "house_type":
if house["house_type"] == condition_value: if house["house_type"] == condition_value:
result.append(house) result.append(house)
# 处理租金查询(数值匹配,示例:查询等于该价格的房源)
elif condition_type == "price": elif condition_type == "price":
if house["price"] == float(condition_value): if house["price"] == float(condition_value):
result.append(house) result.append(house)
@@ -138,3 +80,129 @@ def query_house(condition_type, condition_value):
print("错误:不支持的查询条件类型!") print("错误:不支持的查询条件类型!")
return [] return []
return result return result
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}记录已清空!")
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):
"""
【V3.0新增 二维数组知识点:邻接矩阵初始化】
根据小区列表生成距离邻接矩阵,初始化距离为无穷大,自己到自己为0
时间复杂度:O(N²),N为小区数量
空间复杂度:O(N²)
"""
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 # 自己到自己距离为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("小区名称不存在!")
+185
View File
@@ -0,0 +1,185 @@
from house_service import *
def print_menu():
print("\n===== 房屋出租系统 V3.0 =====")
print("1. 新增房源")
print("2. 删除房源")
print("3. 修改房源")
print("4. 查询房源")
print("5. 查看/管理操作记录")
print("6. 查看/管理浏览历史")
# V3.0 新增菜单
print("7. 地址字符串解析测试")
print("8. 按区域关键词模糊查询")
print("9. 初始化小区邻接矩阵")
print("10. 更新小区间距离")
print("11. 退出系统")
print("============================")
def op_record_menu():
while True:
print("\n----- 操作记录管理 -----")
print("1. 查看最近10条")
print("2. 取出最新一条")
print("3. 清空记录")
print("4. 返回")
c = input("请选择:")
if c == "1":
lst = get_recent_records("operation",10)
print(lst if lst else "暂无记录")
elif c == "2":
print(pop_operation_stack() or "暂无记录")
elif c == "3":
clear_stack("operation")
elif c == "4":
break
else:
print("输入有误")
def browse_history_menu():
while True:
print("\n----- 浏览历史管理 -----")
print("1. 查看最近10条")
print("2. 取出最新一条")
print("3. 清空历史")
print("4. 返回")
c = input("请选择:")
if c == "1":
id_list = get_recent_records("browse",10)
if not id_list:
print("暂无浏览历史")
continue
for idx,hid in enumerate(id_list,1):
info = query_house("id", hid)
if info:
h = info[0]
print(f"{idx}. ID:{hid} 地址:{h['address']}")
else:
print(f"{idx}. ID:{hid} 房源已不存在")
elif c == "2":
hid = pop_browse_stack()
if not hid:
print("暂无浏览历史")
continue
info = query_house("id", hid)
print(f"最近浏览ID:{hid}")
elif c == "3":
clear_stack("browse")
elif c == "4":
break
else:
print("输入有误")
def main():
while True:
print_menu()
choice = input("请输入功能编号:")
if choice == "1":
addr = input("输入房源地址:")
try:
price = float(input("输入月租金:"))
area = float(input("输入面积:"))
except:
print("租金面积必须是数字!")
continue
htype = input("输入户型:")
if add_house(addr,price,area,htype):
new_id = get_next_house_id() - 1
push_operation_stack(f"新增房源ID:{new_id} 地址:{addr}")
elif choice == "2":
try:
hid = int(input("输入要删除房源ID"))
res = query_house("id",hid)
addr = res[0]["address"] if res else "未知地址"
if delete_house(hid):
push_operation_stack(f"删除房源ID:{hid} 地址:{addr}")
except:
print("ID必须是整数")
elif choice == "3":
try:
hid = int(input("输入要修改房源ID"))
edit = {}
a = input("新地址(回车不修改)")
if a: edit["address"] = a
p = input("新租金(回车不修改)")
if p: edit["price"] = float(p)
ar = input("新面积(回车不修改)")
if ar: edit["area"] = float(ar)
t = input("新户型(回车不修改)")
if t: edit["house_type"] = t
if edit:
if update_house(hid, edit):
push_operation_stack(f"修改房源ID:{hid} 变更:{edit}")
else:
print("未填写任何修改内容")
except:
print("输入格式错误")
elif choice == "4":
print("1-ID 2-地址 3-租金 4-户型")
sel = input("选择查询类型:")
map_dic = {"1":"id","2":"address","3":"price","4":"house_type"}
if sel not in map_dic:
print("选择无效")
continue
val = input("输入查询值:")
res_list = query_house(map_dic[sel], val)
if not res_list:
print("未找到房源")
continue
for h in res_list:
print(f"ID:{h['id']} 地址:{h['address']} 租金:{h['price']}")
if map_dic[sel] == "id":
push_browse_stack(h["id"])
elif choice == "5":
op_record_menu()
elif choice == "6":
browse_history_menu()
#3.0
elif choice == "7":
# 测试地址字符串解析
full_addr = input("输入完整地址(如:四川省德阳市什邡市XX小区):")
res = parse_address_string(full_addr)
print("解析结果:", res)
elif choice == "8":
# 按区域关键词模糊查询
keyword = input("输入区域关键词(如:什邡、德阳):")
res_list = fuzzy_query_by_district(keyword)
if not res_list:
print("未找到该区域房源")
else:
for h in res_list:
print(f"ID:{h['id']} 地址:{h['address']}")
elif choice == "9":
# 初始化小区邻接矩阵
community_input = input("输入所有小区名称,用英文逗号分隔:")
community_list = community_input.split(",")
init_community_matrix(community_list)
elif choice == "10":
# 更新两个小区距离
c1 = input("输入小区A名称:")
c2 = input("输入小区B名称:")
try:
dis = float(input("输入两小区距离:"))
update_matrix_distance(c1, c2, dis)
except:
print("距离必须是数字")
elif choice == "11":
print("系统退出成功!")
break
else:
print("请输入有效编号")
if __name__ == "__main__":
main()