探讨两种方法解决大小、数字字符排序问题
来源:互联网 发布:苹果刷机后数据恢复 编辑:程序博客网 时间:2024/06/06 23:57
一 问题描述
一个字符数组,里面的字符可能是a-z、A-Z、0-9.现在要求对数组进行排序,要求所有小写字符放在最前面,所有大写字符放在中间,所有数字放在最后,而且各部分内部分别有序。
二 解题思路
方法一 利用快排
如图所示,为了能够实现排序,首先将原始字符串进行一次二次划分,将所有小写字符移动到字符串的最开始,然后对此段子序列进行快速排序,然后依据同样的方法对大写字符和数字字符进行排序。
方法二:
如图所示,首先定义哈希表,然后根据原始字符串对哈希表进行初始化,那么在哈希表中,小写字符必然在大写字符前,大写字符必然在数字字符前,最后将哈希表里的内容拷贝回原始字符串中。
三 运行测试
方法一测试结果:
方法二测试结果
四 代码
方法一代码:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <ctype.h>#define SIZE 100int partition(char *array, int low, int high) {int i, j;char tmp;i = low;j = high;tmp = array[low];while(i < j) {while(i < j && array[j] > tmp) j--;if(i < j) array[i++] = array[j];while(i < j && array[i] < tmp) i++;if(i < j) array[j--] = array[i];}array[i] = tmp;return i;}void self_qsort(char *array, int low, int high) {if(low < high) {int mid = partition(array, low, high);self_qsort(array, low, mid - 1);self_qsort(array, mid + 1, high);}}void Arrange(char *str, int low, int high) {int lower_end; // the end pointer to lower char arrayint i, j;/* * to put all the lower char in the front of array*/i = low;j = high;char tmp = str[low];while(i < j) {while(i < j && !islower(str[j])) j--;if(i < j) str[i++] = str[j];while(i < j && islower(str[i])) i++;if(i < j) str[j--] = str[i];}/* * to locate the lower_end*/str[i] = tmp;if(islower(str[i])) lower_end = i;else lower_end = i - 1;/* * to sort the lower char in the array*/self_qsort(str, 0, lower_end);/* * to put the upper char in the front of digital char in the array*/int upper_end;i = lower_end + 1;j = high;tmp = str[i];while(i < j) {while(i < j && !isupper(str[j])) j--;if(i < j) str[i++] = str[j];while(i < j && isupper(str[i])) i++;if(i < j) str[j--] = str[i];}str[i] = tmp;/* * to locate the upper_end*/if(isupper(str[i])) upper_end = i;else upper_end = i - 1;self_qsort(str, lower_end + 1, upper_end); // to sort the upper charself_qsort(str, upper_end + 1, high); // to sort the digital char}int main() { char str[SIZE];printf("input a string(only contains 'a' - 'z', 'A' - 'Z', '0' - '9')");gets(str);int i;for(i = 0;str[i];i++) {if(!islower(str[i]) && !isupper(str[i]) && !isdigit(str[i])) {fprintf(stderr, "input error!\n");exit(EXIT_FAILURE);}}int len = strlen(str);Arrange(str, 0, len - 1);puts(str);return 0;}
方法二代码:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <ctype.h>#define SIZE 100#define HashTableLen 62int HashTable[HashTableLen]; // to define a Hash Table/* * Hash Function: Mapping a char to a interger position*/int Hash(char ch) {int pos;if(islower(ch)) pos = ch - 'a';else if(isupper(ch)) pos = ch - 'A' + 26;else if(isdigit(ch)) pos = ch - '0' + 52;else pos = -1;return pos;}/* * Reverse Hash Function: Mapping a position to a char*/char ReHash(int pos) {if(pos < 26 && pos >= 0) return 'a' + pos;if(pos < 52 && pos >= 26) return 'A' + pos - 26;if(pos < 62 && pos >= 52) return '0' + pos - 52; }/* * to initialize a Hash table*/void InitHash(char *str, int low, int high) {int i;int pos;for(i = low;i <= high;i++) {pos = Hash(str[i]);if(pos == -1) {perror("error position in the hash table!\n");exit(EXIT_FAILURE);}HashTable[pos]++;}}int main() { char str[SIZE];printf("input a string(only contains 'a' - 'z', 'A' - 'Z', '0' - '9')");gets(str);int i;/* * to check the validity*/for(i = 0;str[i];i++) {if(!islower(str[i]) && !isupper(str[i]) && !isdigit(str[i])) {fprintf(stderr, "input error!\n");exit(EXIT_FAILURE);}}int len = strlen(str);InitHash(str, 0, len - 1);int j = 0;/* * to regenerate the string */for(i = 0; i < HashTableLen;i++) {while(HashTable[i]-- > 0) {str[j++] = ReHash(i);}}puts(str);return 0;}
五 编程体会
这个问题本质还是排序问题,但是属于特殊排序,第一种方法利用快排,时间效率较高,而方法二要使用额外的空间,不过方法更加巧妙。
0 0
- 探讨两种方法解决大小、数字字符排序问题
- 数据库数字字符按数字大小排序
- 中英文数字字符等混合字符串精确测量字符大小并两种方式绘制比较
- 两种方法解决数字千分位问题(没考虑负数和小数),仅供参考
- 数组排序sort()方法--按数字大小
- 数字比较大小并排序问题
- 完美解决x2注册页面出现‘抱歉,你输入的用户名小于3个字符问题’的两种方法
- 完美解决x2注册页面出现‘抱歉,你输入的用户名小于3个字符问题’的两种方法
- 最简洁的比较两数字的大小编写方法
- C语言 判断字符是否是一个数字的两种方法
- 数字大小排序
- jquery 数字大小排序
- 数字大小排序
- 解决SQL数字排序的问题
- 字符大小排序
- lintcode --字符大小排序
- 两种方法解决jbuilder2005不能启动问题
- 解决URLDownloadToFile缓存问题的两种方法【转】
- C++解析json数据
- Jenkins的Slave的配置
- oracle用户密码密码的生成
- Python连接SQLServer2000
- DOM节点操作
- 探讨两种方法解决大小、数字字符排序问题
- jQuery数组处理详解(含实例演示)
- zigbee路由知识
- 局域网内,windows通过samba自动映射linux服务器的方法
- 16-4相同数字??
- Linux下 使用 中断唤醒 已经suspend的 系统
- linux shell编程指南第二十二章------创建屏幕输入
- 扩展方法
- 数据结构_链表实现无限循环的"环"结构/循环队列