1. 项目概述
"PTA 习题9-4 查找书籍"是一道典型的程序设计练习题,主要考察学生对数据结构中查找算法的理解和应用能力。这道题目通常出现在程序设计课程的作业或考试中,要求学生编写程序实现对书籍信息的存储和查找功能。
作为一道基础算法题,它融合了以下几个核心知识点:
-
结构体定义与使用
-
数组或链表的数据存储
-
基本查找算法实现
-
文件输入输出操作
这道题目特别适合正在学习C语言或VB等编程语言的初学者,通过实际编码练习可以加深对基础数据结构和算法的理解。我在教授编程课程时,经常使用这类题目作为学生的课后练习。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 题目需求分析
2.1 题目基本要求
根据常见的PTA题目设置,这道题的基本要求通常包括:
-
定义一个书籍结构体,包含书名、作者、价格等基本信息
-
从标准输入或文件读取多本书籍信息
-
实现按书名查找书籍的功能
-
输出查找结果
2.2 输入输出规范
典型的输入输出格式如下:
输入:
code复制3
C Programming
K.N. King
59.9
Data Structure
Mark Allen
69.8
Algorithm Design
Jon Kleinberg
89.0
Data Structure
输出:
code复制Data Structure Mark Allen 69.8
2.3 边界条件考虑
在实际编码中需要考虑以下特殊情况:
-
查找的书名不存在时的处理
-
输入书籍数量为0的情况
-
书名或作者名中包含空格的情况
-
价格的小数位数处理
3. 实现方案设计
3.1 数据结构选择
对于这类查找问题,常用的数据结构选择有:
-
数组存储:实现简单,适合数据量小的情况
-
链表存储:动态内存分配,适合数据量不确定的情况
-
二叉搜索树:提高查找效率,适合数据量大的情况
考虑到这是基础练习题,建议先使用数组实现,掌握基本思路后再尝试其他数据结构。
3.2 查找算法选择
常见的查找算法包括:
-
顺序查找:最简单直接的查找方式
-
二分查找:效率更高,但需要数据有序
-
哈希查找:最高效,但实现较复杂
对于初学者,建议先实现顺序查找,理解基本查找逻辑后,可以尝试优化为二分查找。
4. C语言实现详解
4.1 结构体定义
首先定义书籍的结构体:
c复制#define MAX_TITLE_LEN 50
#define MAX_AUTHOR_LEN 30
typedef struct {
char title[MAX_TITLE_LEN];
char author[MAX_AUTHOR_LEN];
double price;
} Book;
4.2 主函数框架
主函数的基本框架如下:
c复制#include <stdio.h>
#include <string.h>
int main() {
int n;
Book books[100]; // 假设最多100本书
// 读取书籍数量
scanf("%d", &n);
getchar(); // 消耗换行符
// 读取书籍信息
for (int i = 0; i < n; i++) {
read_book(&books[i]);
}
// 查找书籍
char search_title[MAX_TITLE_LEN];
fgets(search_title, MAX_TITLE_LEN, stdin);
search_title[strcspn(search_title, "\n")] = '\0'; // 去除换行符
// 执行查找并输出结果
search_and_print(books, n, search_title);
return 0;
}
4.3 书籍读取函数
实现读取单本书籍信息的函数:
c复制void read_book(Book *book) {
fgets(book->title, MAX_TITLE_LEN, stdin);
book->title[strcspn(book->title, "\n")] = '\0';
fgets(book->author, MAX_AUTHOR_LEN, stdin);
book->author[strcspn(book->author, "\n")] = '\0';
scanf("%lf", &book->price);
getchar(); // 消耗换行符
}
4.4 查找与输出函数
实现查找并输出结果的函数:
c复制void search_and_print(Book books[], int n, char *title) {
for (int i = 0; i < n; i++) {
if (strcmp(books[i].title, title) == 0) {
printf("%s %s %.1lf\n", books[i].title,
books[i].author, books[i].price);
return;
}
}
printf("Not found\n");
}
5. 常见问题与解决方案
5.1 输入缓冲区问题
初学者常见的问题是忘记处理输入缓冲区中的换行符,导致后续读取出错。解决方案:
-
在读取数字后使用
getchar()消耗换行符 -
使用
fgets读取字符串后再手动去除末尾的换行符
5.2 字符串比较问题
字符串比较必须使用strcmp函数,不能直接使用==运算符。常见错误:
c复制// 错误写法
if (books[i].title == title)
// 正确写法
if (strcmp(books[i].title, title) == 0)
5.3 价格输出格式
注意题目要求的输出格式,特别是价格的小数位数。可以使用%.1lf指定输出1位小数。
6. 算法优化思路
6.1 排序后二分查找
如果题目允许预处理数据,可以先对书籍按书名排序,然后使用二分查找提高效率:
c复制#include <stdlib.h>
// 比较函数用于qsort
int compare_books(const void *a, const void *b) {
Book *bookA = (Book *)a;
Book *bookB = (Book *)b;
return strcmp(bookA->title, bookB->title);
}
// 在主函数中添加排序
qsort(books, n, sizeof(Book), compare_books);
然后实现二分查找:
c复制int binary_search(Book books[], int n, char *title) {
int left = 0, right = n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int cmp = strcmp(books[mid].title, title);
if (cmp == 0) {
return mid;
} else if (cmp < 0) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
6.2 哈希表实现
对于更大规模的数据,可以考虑使用哈希表来存储书籍信息,实现O(1)时间复杂度的查找。
7. 测试用例设计
完善的测试用例应该包括:
-
正常情况测试
- 输入多本书,查找存在的书名
- 输入多本书,查找不存在的书名
-
边界情况测试
- 只输入一本书并查找
- 输入最大数量书籍并查找
-
异常情况测试
- 输入0本书
- 书名或作者名包含空格
- 价格输入为0或负数
8. VB实现方案
对于使用VB的学生,以下是基本实现思路:
8.1 结构体定义
vb复制Public Type Book
Title As String
Author As String
Price As Double
End Type
8.2 主程序逻辑
vb复制Sub Main()
Dim n As Integer
Dim books(100) As Book
Dim searchTitle As String
Dim found As Boolean
' 读取书籍数量
n = Val(InputBox("Enter number of books:"))
' 读取书籍信息
For i = 1 To n
books(i).Title = InputBox("Enter title for book " & i)
books(i).Author = InputBox("Enter author for book " & i)
books(i).Price = Val(InputBox("Enter price for book " & i))
Next i
' 输入要查找的书名
searchTitle = InputBox("Enter title to search:")
' 执行查找
found = False
For i = 1 To n
If books(i).Title = searchTitle Then
MsgBox books(i).Title & " " & books(i).Author & " " & books(i).Price
found = True
Exit For
End If
Next i
If Not found Then
MsgBox "Not found"
End If
End Sub
9. 实际应用扩展
这道基础题目可以扩展为更实用的图书管理系统,考虑以下功能增强:
-
从文件批量导入书籍信息
-
支持多种查找方式(按作者、按价格范围等)
-
添加书籍修改和删除功能
-
实现图形用户界面
-
增加数据持久化存储
在实际开发中,这类功能通常会使用数据库来存储和管理数据,但对于学习基础编程概念,这种简单的实现方式已经足够。
