当前位置: 首页 > news >正文

C语言初学者必看:如何用冒泡排序实现英文单词长度排序(附完整代码)

C语言实战:用冒泡排序算法处理英文单词长度排序

在编程学习的早期阶段,掌握基础算法和字符串处理是每个C语言学习者的必经之路。今天我们要探讨的是一个既经典又实用的案例——如何用冒泡排序算法对一组英文单词按长度进行排序。这个案例不仅涵盖了基本的输入输出操作,还涉及字符串处理、数组应用和算法实现,是检验初学者C语言综合能力的绝佳练习。

1. 理解问题需求与准备工作

在开始编码之前,我们需要明确问题的具体要求。题目要求我们编写一个程序,能够接收用户输入的一系列英文单词(以#作为结束标志),然后对这些单词按照长度从小到大进行排序。如果两个单词长度相同,则保持它们原有的输入顺序不变。

为了完成这个任务,我们需要准备以下知识基础:

  • 字符串的存储与处理:C语言中字符串通常用字符数组表示
  • 基本的输入输出操作:特别是如何读取不定数量的输入
  • 冒泡排序算法:虽然效率不高,但实现简单,适合初学者
  • 字符串长度计算:使用strlen函数
  • 字符串复制操作:使用strcpy函数
#include <stdio.h> #include <string.h> // 提供strlen和strcpy函数

2. 数据存储与输入处理

2.1 设计数据结构

首先需要考虑如何存储输入的单词。根据题目要求,我们需要:

  • 存储最多20个单词
  • 每个单词长度不超过10个字符(加上终止符'\0'需要11个字符空间)

因此,我们可以定义一个二维字符数组:

char words[20][11]; // 20个单词,每个单词最多10个字符+'\0'

2.2 实现输入循环

我们需要一个循环来持续读取用户输入,直到遇到"#"为止。这里使用while循环配合break语句是常见做法:

int count = 0; // 记录已输入的单词数量 while (1) { scanf("%s", words[count]); if (words[count][0] == '#') { break; } count++; }

注意事项

  • 使用count变量跟踪实际输入的单词数量
  • 检查输入的第一个字符是否为'#'来判断是否结束
  • 题目保证输入不超过20个单词,所以不需要额外检查数组越界

3. 实现冒泡排序算法

3.1 标准冒泡排序回顾

冒泡排序的基本思想是通过多次遍历数组,每次比较相邻元素,如果顺序不对就交换它们。对于整数排序,典型的实现如下:

for (int i = 0; i < n-1; i++) { for (int j = 0; j < n-i-1; j++) { if (arr[j] > arr[j+1]) { // 交换arr[j]和arr[j+1] int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } }

3.2 适配字符串排序需求

我们需要对上述算法进行修改,以适应字符串长度排序的需求:

  1. 比较条件改为字符串长度比较
  2. 交换操作需要使用strcpy函数完成字符串复制
char temp[11]; // 临时存储空间用于交换字符串 for (int i = 0; i < count-1; i++) { for (int j = 0; j < count-i-1; j++) { if (strlen(words[j]) > strlen(words[j+1])) { // 交换words[j]和words[j+1] strcpy(temp, words[j]); strcpy(words[j], words[j+1]); strcpy(words[j+1], temp); } } }

关键点说明

  • temp数组大小必须足够存储最长的字符串
  • 使用strlen()获取字符串长度进行比较
  • strcpy()用于字符串的复制交换
  • 保持稳定排序(长度相同时不交换)

4. 完整代码实现与优化

4.1 基础版本实现

将上述各部分组合起来,我们得到完整的程序:

#include <stdio.h> #include <string.h> #define MAX_WORDS 20 #define MAX_LENGTH 11 int main() { char words[MAX_WORDS][MAX_LENGTH]; int count = 0; // 输入处理 while (count < MAX_WORDS) { scanf("%s", words[count]); if (words[count][0] == '#') { break; } count++; } // 冒泡排序 char temp[MAX_LENGTH]; for (int i = 0; i < count-1; i++) { for (int j = 0; j < count-i-1; j++) { if (strlen(words[j]) > strlen(words[j+1])) { strcpy(temp, words[j]); strcpy(words[j], words[j+1]); strcpy(words[j+1], temp); } } } // 输出结果 for (int i = 0; i < count; i++) { printf("%s ", words[i]); } return 0; }

4.2 代码优化建议

虽然上面的代码已经可以正确运行,但我们还可以做一些改进:

  1. 添加输入验证:虽然题目保证输入合法,但实际应用中应该检查
  2. 提高可读性:将排序逻辑封装成函数
  3. 优化性能:添加提前终止标志

优化后的排序函数可能如下:

void bubbleSortWords(char words[][MAX_LENGTH], int count) { char temp[MAX_LENGTH]; int swapped; for (int i = 0; i < count-1; i++) { swapped = 0; for (int j = 0; j < count-i-1; j++) { if (strlen(words[j]) > strlen(words[j+1])) { strcpy(temp, words[j]); strcpy(words[j], words[j+1]); strcpy(words[j+1], temp); swapped = 1; } } if (!swapped) break; // 如果没有发生交换,提前结束 } }

5. 常见问题与调试技巧

初学者在实现这个程序时经常会遇到一些问题,下面列举几个典型情况:

5.1 字符串存储空间不足

char word[10]; // 错误!只能存储9个字符+'\0',不符合题目要求

正确做法

char word[11]; // 可以存储10个字符+'\0'

5.2 字符串比较错误

直接使用比较运算符比较字符串是错误的:

if (words[j] > words[j+1]) // 错误!这比较的是地址而非内容

正确做法

if (strlen(words[j]) > strlen(words[j+1])) // 比较长度

5.3 输入处理问题

在读取输入时,需要注意:

  • 使用scanf("%s", ...)会自动跳过空白字符
  • 但无法处理包含空格的字符串(本题不要求)
  • 确保输入缓冲区不会溢出

5.4 排序稳定性问题

题目要求长度相同的单词保持输入顺序,因此:

// 只有当长度严格大于时才交换 if (strlen(words[j]) > strlen(words[j+1])) { // 交换操作 }

如果写成>=就会破坏稳定性。

6. 扩展思考与实际应用

掌握了这个基础版本后,我们可以考虑一些扩展方向:

6.1 支持更多排序方式

修改比较逻辑,可以实现不同的排序方式:

  • 按字典序排序:使用strcmp()函数
  • 不区分大小写排序:先统一转换为小写/大写
  • 多重条件排序:先按长度,长度相同再按字典序

6.2 性能优化方向

虽然冒泡排序简单易懂,但其时间复杂度为O(n²),对于大量数据效率低下。可以考虑:

  • 使用更高效的排序算法(如快速排序、归并排序)
  • 对于字符串排序,可以考虑基数排序等专用算法
  • 使用指针数组代替二维数组,减少数据移动开销

6.3 实际应用场景

这种字符串排序技术在现实中有很多应用:

  • 文本处理工具中的单词频率统计
  • 字典应用程序的单词列表展示
  • 搜索引擎的结果排序(简化版)
  • 数据分析中的分类处理

7. 测试用例与验证方法

为了确保程序的正确性,应该设计全面的测试用例:

测试用例描述输入样例预期输出测试要点
常规输入"hello world code #""code hello world "基本功能验证
空输入"#""" (无输出)边界条件
单单词"programming #""programming "最小输入
等长单词"cat dog pig #""cat dog pig "稳定性验证
最大数量20个单词+"#"按长度排序的20个单词容量测试
混合长度"a bc def ghij klmno #""a bc def ghij klmno "多种长度

在Linux环境下,可以使用shell脚本进行自动化测试:

#!/bin/bash # 编译程序 gcc -o word_sort word_sort.c # 测试1: 常规输入 echo "hello world code #" | ./word_sort | grep -q "code hello world " && echo "Test 1 PASSED" || echo "Test 1 FAILED" # 测试2: 空输入 echo "#" | ./word_sort | [ $(wc -c) -eq 0 ] && echo "Test 2 PASSED" || echo "Test 2 FAILED" # 更多测试...

8. 进阶学习路径

掌握了这个基础案例后,可以继续深入学习以下内容:

  1. 更高效的排序算法

    • 快速排序
    • 归并排序
    • 堆排序
  2. 字符串处理进阶

    • 正则表达式
    • Unicode字符串处理
    • 字符串匹配算法
  3. C语言高级特性

    • 函数指针(可用于实现通用排序)
    • 动态内存分配
    • 结构体和联合
  4. 实际项目应用

    • 开发简单的文本处理工具
    • 参与开源项目如grep、sed等的基础功能
    • 算法竞赛中的字符串处理题目
// 使用函数指针实现通用排序的示例 typedef int (*compare_func)(const char*, const char*); void sort_words(char words[][MAX_LENGTH], int count, compare_func cmp) { // 实现细节类似冒泡排序,但使用cmp函数进行比较 }

这个简单的单词排序程序虽然代码量不大,但涵盖了C语言学习的多个重要概念。通过不断练习和扩展这样的案例,可以逐步提升编程能力和算法思维。

http://www.jsqmd.com/news/650096/

相关文章:

  • 从Socket到RDMA:一个Java后端开发者的真实踩坑与性能对比实验(附代码)
  • 讲讲服务不错的GEO推广机构,如何选出适合自己的品牌 - 工业品网
  • eNSP静态路由配置全网可达入门练习
  • 告别反复烧录:用STM32F407 IAP打造你的产品远程固件更新方案
  • 保姆级教程:在Ubuntu 20.04上搞定OMNeT++ 4.6安装与环境配置(含依赖库完整清单)
  • 2025终极方案:八大网盘直链下载助手LinkSwift完全解析
  • Clear Temporary Files
  • 从复位到运行:深入解析STM32 Boot模式的选择与实战
  • 2026年性价比高的AI推广品牌企业盘点,为你揭秘优质之选 - myqiye
  • PowerISO:虚拟光驱软件解决映像文件打开与编辑难题
  • 如何快速掌握canvas-editor:开源富文本编辑器的完整指南
  • 别再傻傻分不清了!Linux exec函数族(execl/execv)保姆级选择指南与实战避坑
  • 避坑指南:用R做批量单因素Logistic回归时,你的分类变量处理对了吗?
  • Faster-Whisper-GUI:一键将音频视频转换为精准字幕的高效解决方案
  • HandheldCompanion:如何让Windows掌机获得完美控制器兼容性
  • 基于C++实现的简单的SMTP服务器
  • 用Python+OpenCV复现DWT-DCT-SVD图像水印:从原理到代码的保姆级教程
  • 一键解决米哈游游戏登录难题:MHY_Scanner完整使用教程
  • 别再浪费480MHz主频!手把手教你优化STM32H750的Keil工程内存布局
  • Portainer部署实战:一键配置默认管理员凭据
  • 如何轻松下载国家中小学智慧教育平台电子课本:3步搞定完整教材获取
  • 还在为3D模型查看而烦恼?3步解锁浏览器中的专业级3D查看体验
  • PS4存档管理终极指南:Apollo Save Tool完全使用教程
  • AI+地图:智能进化下的出行革命
  • 海康威视MV_CC_GetImageBuffer接口详解:如何正确释放缓存与避免内存泄漏
  • Python自动化抢票脚本:3步构建大麦网秒级响应系统
  • 死亡是万物的基石
  • 从游戏地图到城市设计:Voronoi算法在Unity和GIS中的实战应用对比
  • 终极解决方案:如何快速重置JetBrains IDE试用期的3种高效方法
  • Mac版百度网盘终极提速方案:5分钟解锁SVIP高速下载体验