三维排序(将书以Name、Year、Price进行排序

本文介绍了一个三维排序问题的解决方案,通过定义不同的比较函数实现了根据书名、出版年份和价格的不同排序需求。采用泛型编程的方法,使得排序更加灵活。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  Jim很喜欢读书,他有很多数,有时候他很难管理它们。因此,他请求你的帮助来解决这个问题。
  Jim想以书名、出版年份和价格为关键字,按照排序标准把书进行排序。一本书由书名Name、出版年份Year和单价Price组成。Name是第一排序标准,Year是第二排序标准,Price是第三排序标准。如果排序标准是Year,且两本书的Year相同,那么,你就应该给它们按Name排序。如果Name还是相同,那么,就应该安Price排序。不存在两本书的三个参数都相同的情况。
  解题思路:本题是三维排序问题。Name、Year和Price分别是默认是第一、第二和第三排序。但本例又很特殊,第一排序是由输入指定的,是Name、Year和Price三者之一。
  当Name是排序标准,那么,三个排序顺序是Name、Year和Price;
  当Year是排序标准时,三个排序顺序是Year、Name和Price;
  当Price是排序标准时,三个排序顺序是Price、Name和Year。
  对于这三种排序标准,我们编写三个比较函数,这样就显得比较灵活,程序实现起来也比较容易。
  而书的信息,则写到一个结果体变量中,而结果体变量又作为向量的元素,最后,只要根据排序标准,在排序算法中选择相应的比较函数,就完成了书的排序了。这里选用“泛型编程”来实现。
  //BookSort.cpp  

#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

//Book的结构体
struct Book{
    string Name;
    int Year;
    int Price;
};

//比较函数,Name主序
bool CompName(const Book &b1,const Book &b2){
    if(b1.Name != b2.Name)
        return b1.Name < b2.Name;
    else if(b1.Year != b2.Year)
        return b1.Year < b2.Year;
    else
        return b1.Price < b2.Price;
}

//比较函数,Year主序
bool CompYear(const Book &b1,const Book &b2){
    if(b1.Year != b2.Year)
        return b1.Year < b2.Year;
    else if(b1.Name != b2.Name)
        return b1.Name < b2.Name;
    else
        return b1.Year < b2.Year;
}

//比较函数,Price主序
bool CompPrice(const Book &b1,const Book &b2){
    if(b1.Price != b2.Price)
        return b1.Price < b2.Price;
    else if(b1.Name != b2.Name)
        return b1.Name < b2.Name;
    else
        return b1.Year < b2.Year;
}

int main(int argc, char* argv[])
{
    //ifstream cin("aaa.txt");
    vector<Book> v;
    Book book;
    string sorting; //第一排序
    int n;
    int i;
    int line=0;
    while(cin>>n){
        if(n==0) break;
        line++; //案例号
        v.clear(); //清空向量
        //读入一个案例数据到向量中
        for (i=0;i<n;i++)
        {
            cin>>book.Name>>book.Year>>book.Price;
            v.push_back(book);
        }
        //读入排序标准
        cin>>sorting;
        //给向量排序,要根据主序来确定比较函数
        if(sorting == "Name")
            sort(v.begin(),v.end(),CompName);
        else if(sorting == "Year")
            sort(v.begin(),v.end(),CompYear);
        else if(sorting == "Price")
            sort(v.begin(),v.end(),CompPrice);
        //输出结果
        if(line != 1) cout<<endl; //不是第一行,先输出一个空行
        for (i=0;i<v.size();i++)
        {
            cout<<v[i].Name<<" "<<v[i].Year<<" "<<v[i].Price<<endl;
        }

    }

    return 0;
}

效果如下:

这里写图片描述

<think>我们正在处理用户关于数据库应用的学习资料求,特别是关系型数据库、单表结构设计、多表复杂查询、索引优化以及JavaWeb数据库操作。用户希望包含示例和教程。根据引用内容,我们可以组织以下内容:1.关系型数据库基础概念(引用[1]和[2])2.单表结构设计(DDL操作,引用[1]和[2])3.多表设计(引用[2]中的多表设计案例)4.多表复杂查询(引用[3]中的多表查询和子查询)5.索引优化(引用[1]中提到的数据库优化-索引)6. JavaWeb数据库操作(结合引用[1]中的DML和DQL,以及引用[2]和[3]中的案例)我们将按照这些主题组织回答,并尽量提供示例代码和讲解。注意:用户要求使用中文回答,数学公式使用$...$或$$...$$,并生成相关问题。</think>### 数据库应用技术学习指南 #### 一、关系型数据库基础 关系型数据库基于**二维表结构**存储数据,通过**主键-外键关联**实现多表连接。核心特点包括: - 数据以行/列格式存储,支持ACID事务特性 - 使用**SQL语言**统一操作,语法示例: ```sql SELECT * FROM employees WHERE salary > 5000; -- 单表查询 ``` - 常见系统:MySQL、PostgreSQL、Oracle[^1] #### 二、单表结构设计 设计要点包含**字段定义**、**约束设置**和**数据类型选择**: ```sql CREATE TABLE dish ( id INT PRIMARY KEY AUTO_INCREMENT, -- 主键自增 name VARCHAR(50) NOT NULL UNIQUE, -- 非空唯一约束 price DECIMAL(8,2) CHECK(price > 0), -- 正数检查 category_id INT, -- 外键预备字段 create_time DATETIME DEFAULT CURRENT_TIME -- 默认时间 ); ``` **设计规范**: 1. 主键用`INT/BIGINT`自增类型 2. 字符串字段明确长度(如`VARCHAR(255)`) 3. 金额使用`DECIMAL`避免精度丢失[^2] #### 、多表复杂查询 通过**JOIN操作**实现多表关联,常用技巧: 1. **表连接查询**(引用[3]案例): ```sql SELECT e.*, d.name FROM (SELECT * FROM tb_emp WHERE entrydate > '2006-01-01') e JOIN tb_dept d ON e.dept_id = d.id; ``` 2. **子查询类型**: - 行子查询:`WHERE (col1, col2) = (SELECT ...)` - 表子查询:`FROM (SELECT ...) AS temp` 3. **UNION操作**:合并多个查询结果集 #### 四、索引优化策略 索引加速查询的**B+树数据结构**,优化方案: ```sql CREATE INDEX idx_price ON dish(price); -- 创建普通索引 ``` **优化原则**: 1. 高频查询条件列建索引 2. 避免在索引列使用函数(如`WHERE YEAR(create_time)=2023`) 3. 联合索引遵循**最左匹配原则** 4. 文本字段用**前缀索引**:`INDEX idx_name(name(20))` #### 五、JavaWeb数据库操作 通过**JDBC**实现Java程序与数据库交互: ```java // 查询示例 try (Connection conn = DriverManager.getConnection(url, user, pwd)) { String sql = "SELECT name, price FROM dish WHERE category_id=?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setInt(1, 3); // 防SQL注入 ResultSet rs = stmt.executeQuery(); while (rs.next()) { System.out.println(rs.getString("name") + ": " + rs.getDouble("price")); } } ``` **最佳实践**: 1. 使用`PreparedStatement`防止SQL注入 2. 连接池管理(如HikariCP) 3. ORM框架简化操作(如MyBatis) --- ### 示例应用:餐饮管理系统表结构 ```mermaid erDiagram category ||--o{ dish : "1:N" category { BIGINT id PK VARCHAR(50) name } dish { BIGINT id PK VARCHAR(100) name DECIMAL price BIGINT category_id FK } set_meal ||--|{ set_meal_dish : "1:N" set_meal { BIGINT id PK VARCHAR(100) name } set_meal_dish { BIGINT set_meal_id FK BIGINT dish_id FK } ``` 表关系说明: - 分类表 → 菜品表:一对多 - 套餐表 → 套餐菜品表:一对多(关联菜品)[^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sanqima

一键三连,多多益善

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值