- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我需要一个c语言代码来对一些字符串进行排序,它应该区分大小写并且对于大小写相同的字母,小写必须在前。例如以下字符串的排序结果:
eggs
bacon
cheese
Milk
spinach
potatoes
milk
spaghetti
应该是:
bacon
cheese
eggs
milk
Milk
potatoes
spaghetti
spinach
我写了一段代码,但得到的结果是:
Milk
bacon
cheese
eggs
milk
potatoes
spaghetti
spinach
我不知道如何改进这个,我已经搜索了很多。谁能帮我解决这个问题?
#include <stdio.h>
#include <string.h>
int main(){
char c;
char name[20][10], temp[10];
int count_name = 0;
int name_index = 0;
int i, j;
while ((c = getchar()) != EOF){
if (c == 10){
name[count_name][name_index] = '\0';
count_name++;
name_index = 0;
} else {
name[count_name][name_index] = c;
name_index++;
}
}
for(i=0; i < count_name-1 ; i++){
for(j=i+1; j< count_name; j++)
{
if(strcmp(name[i],name[j]) > 0)
{
strcpy(temp,name[i]);
strcpy(name[i],name[j]);
strcpy(name[j],temp);
}
}
}
for (i = 0; i < count_name; i++){
printf("%s\n", name[i]);
}
}
最佳答案
对于单词列表,将“相同”单词组合在一起通常更有用(即使它们的大小写不同)。例如:
Keeping things together: Simple "M after m":
------------------------ -------------------
mars mars
mars bar mars bar
Mars bar milk
milk milk-duds
Milk milky-way
milk-duds Mars bar
milky-way Milk
Milky-way Milky-way
如果你想像第一列那样排列单词,我提供了三种方法:
strcasecmp()
结合strcmp()
.isalpha()
跟踪字符类型的单 channel 实现, tolower()
, 和 isupper()
.最后我讨论了两种选择:
如果可能的话,避免重新发明轮子。在这种情况下,我们可以使用 POSIX 函数 strcasecmp()
来实现。通过不区分大小写的比较查看它们是否相等,然后返回 strcmp()
什么时候。
int alphaBetize (const char *a, const char *b) {
int r = strcasecmp(a, b);
if (r) return r;
/* if equal ignoring case, use opposite of strcmp() result to get
* lower before upper */
return -strcmp(a, b); /* aka: return strcmp(b, a); */
}
(在某些系统上,不区分大小写的比较函数称为 stricmp()
或 _stricmp()
。如果您无法使用,下面提供了实现。)
#ifdef I_DONT_HAVE_STRCASECMP
int strcasecmp (const char *a, const char *b) {
while (*a && *b) {
if (tolower(*a) != tolower(*b)) {
break;
}
++a;
++b;
}
return tolower(*a) - tolower(*b);
}
#endif
有时,现有功能的性能不够好,您必须采取其他措施来加快速度。以下函数在一次传递中以大致相同的方式进行比较,并且不使用 strcasecmp()
中的任何一个。或 strcmp()
.但是,它将所有非字母字符视为小于字母。
int alphaBetize (const char *a, const char *b) {
int weight = 0;
do {
if (*a != *b) {
if (!(isalpha(*a) && isalpha(*b))) {
if (isalpha(*a) || isalpha(*b)) {
return isalpha(*a) - isalpha(*b);
}
return *a - *b;
}
if (tolower(*a) != tolower(*b)) {
return tolower(*a) - tolower(*b);
}
/* treat as equal, but mark the weight if not set */
if (weight == 0) {
weight = isupper(*a) - isupper(*b);
}
}
++a;
++b;
} while (*a && *b);
/* if the words compared equal, use the weight as tie breaker */
if (*a == *b) {
return weight;
}
return !*b - !*a;
}
使用此比较进行排序将保留milk
和 Milk
彼此相邻,即使列表包含 milk-duds
.
这是一种从“配置”动态创建整理表的方法。它用于说明改变字符串比较方式的对比技术。
您可以将字母表中的字母与一种简单的表格进行比较,该表格描述了您希望字母(或除 NUL 字节以外的任何字符)具有的相对顺序:
const char * alphaBetical =
"aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
根据这个顺序,我们可以创建一个查找表来查看两个字母应该如何相互比较。如果尚未首先完成,则以下函数初始化表,否则执行表查找。
int alphaBeta_lookup (int c) {
static int initialized;
static char table[CHAR_MAX+1];
if (!initialized) {
/* leave all non-alphaBeticals in their relative order, but below
alphaBeticals */
int i, j;
for (i = j = 1; i < CHAR_MAX+1; ++i) {
if (strchr(alphaBetical, i)) continue;
table[i] = j++;
}
/* now run through the alphaBeticals */
for (i = 0; alphaBetical[i]; ++i) {
table[(int)alphaBetical[i]] = j++;
}
initialized = 1;
}
/* return the computed ordinal of the provided character */
if (c < 0 || c > CHAR_MAX) return c;
return table[c];
}
有了这个查找表,我们现在可以简化 alphaBetize()
的循环体比较功能:
int alphaBetize (const char *a, const char *b) {
int ax = alphaBeta_lookup(*a);
int bx = alphaBeta_lookup(*b);
int weight = 0;
do {
char al = tolower(*a);
char bl = tolower(*b);
if (ax != bx) {
if (al != bl) {
return alphaBeta_lookup(al) - alphaBeta_lookup(bl);
}
if (weight == 0) {
weight = ax - bx;
}
}
ax = alphaBeta_lookup(*++a);
bx = alphaBeta_lookup(*++b);
} while (ax && bx);
/* if the words compared equal, use the weight as tie breaker */
return (ax != bx) ? !bx - !ax : weight;
}
使用整理表,您可以使用简化的比较功能创建许多不同的排序,例如:
int simple_collating (const char *a, const char *b) {
while (alphaBeta_lookup(*a) == alphaBeta_lookup(*b)) {
if (*a == '\0') break;
++a, ++b;
}
return alphaBeta_lookup(*a) - alphaBeta_lookup(*b);
}
使用相同的函数并通过修改 alphaBetical
字符串,您几乎可以实现任何您想要的排序(字母顺序、反向字母顺序、元音在辅音之前等)。然而,将相似的单词放在一起的安排需要将大写单词与小写单词穿插在一起,而这只能通过忽略大小写的比较来实现。
请注意 simple_collating()
上面的函数和alphaBetical
我提供的字符串,Bacon
会在milk
之前来,但是Mars
会去 milk
和之前 Milk
.
如果您想使用已经为您的语言环境定义的整理序列,您可以设置语言环境并调用整理比较函数:
/*
* To change the collating locale, use (for example):
setlocale(LC_COLLATE, "en.US");
*/
int iso_collating (const char *a, const char *b) {
return strcoll(a, b);
}
现在,通过更改语言环境,排序顺序将基于标准化的整理顺序。
关于c - 如何按字母顺序对字符串数组进行排序(区分大小写,非标准排序规则),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12646734/
我正在编写一个程序,它必须规范化音频 *.wav 文件。有一个“显示头部数据”的任务:ChunkId、ChunkSize 等等。 我想创建一个名为display_hdr 的函数(为了减少main.c
我有一个带有缩放类的 css 文件:1。 我在浏览器控制台上收到以下错误。 此页面使用非标准的“缩放”属性。相反,您可以将 calc() 或“transform”与“transform-origin:
我想模拟来自非标准密度函数的数据。我已经找到以下链接( How do I best simulate an arbitrary univariate random variate using its
使用已安装的 JDK 版本时,默认系统语言环境报告正确,但当我使用 adoptopenjdk-11 时tar.gz ,总是报告为en_US import java.util.Locale; publi
我如何强制 automake 为非标准 C++ 后缀文件生成依赖项跟踪?特别是我的意思是生成 .deps 目录文件内容。我也在使用 libtool。 谢谢 最佳答案 看看this section in
我有一个快速解决方法的问题,以享受非标准 gnu 的好处 case ranges .例如,非标准: case 1 ... 5: 可以替换为: case 1: case 2: case 3: case
我有两个“日期”字段需要加入。 第一个是格式为 yyyy-mm-dd hh:mm:ss 的普通日期时间 第二个是红头步骤子格式的 varchar(8) mmddyyyy 现在这变得很痛苦,因为没有简单
我有一个符合以下约定的 CSV val1,val2,outerStruct1{valA,valB,innerStruct2{valX, valY},valC},... 问题是当我尝试正则表达式oute
我有数据列: id name type number 1 n1 t1 num1 2 n2 t1 num2 3 n3 t1 num3 4
我正在为 Shelly 系列设备开发 openHAB2 绑定(bind)。 http接口(interface)运行良好,但无法注册获取COAP事件。 有人有使用 Californium 框架的经验吗?
我在 UILabel 上显示商标“TM”字符时遇到了一些问题。 出现问题的“TM”字符是\U0099 而不是通常的\U2122 稍微深挖一下,发现“TM”字\U0099属于极少数的汉字。 所以我猜 i
请原谅我的无知,我是 c++ 的新手。 完整错误信息: coog.cpp(74): error C3867: 'Manager::start_foo': 非标准语法;使用“&”创建指向成员的指针 我正
我有一个可以生成如下 JSON 的 API: )]}', { //JSON DATA } //JSON DATA 是有效的 JSON,但顶部的 )]}', 不是。 当我尝试通过逻辑应用获取此数
我尝试使用 Apache Ant Get task获取我们公司另一个团队生成的 WSDL 列表。他们将它们托管在 http://....com:7925/services/ 上的 weblogic 9
我在 Google App Engine 上有一个 servlet,它从页面获取文本,将其存储为实体,然后将其发送回客户端。当我存储“You're”一词时,它会像平常一样在 GAE 本地存储中显示为“
这个问题在这里已经有了答案: Is there a way to access the underlying container of STL container adaptors? (10 个答案
我在编译这段代码时遇到了问题: void MyClass::MyMethod(Type * new_ptr) { myInternalUniquePtr_->swap(std::unique_
我有两个 Eigen::VectorXd 对象,A 和 B,具有相同的维度 n。 我想创建一个新的 vector C,这样: 如果 B[i] 是 NaN,则 C[i] = A[i] 否则:C[i] =
在 C++ 中,以这种格式向日期添加一天的最简单方法是什么: “20090629-05:57:43” 可能使用 Boost 1.36 - Boost::date、Boost::posix_date 或
我正在使用 Apache HTTPComponents 4.3 的 HttpCore 库编写一个 HTTP 服务器( java )。我的服务器必须能够接收具有非标准 HTTP 方法(GET、POST、
我是一名优秀的程序员,十分优秀!