[英]sort String by Character in C Programming
I'd like to ask, how to sort some group of string by it's Character. 我想问一下,如何通过“字符”对一组字符串进行排序。 For instance : "Baba", "Cece" , "Caca" , "Zaza" , "Lala"
例如:“ Baba”,“ Cece”,“ Caca”,“ Zaza”,“ Lala”
i'd like to sort it become like this Baba Caca Cece Lala Zaza 我想把它变成这样的Baba Caca Cece Lala Zaza
how to sort those words? 这些单词怎么排序? do we compare it's ASCII Number each word?
我们是否比较每个单词的ASCII码? if it's a number we can just swap it(using insertion sort and so on) do we can also use the same method?
如果它是一个数字,我们可以交换它(使用插入排序等),是否也可以使用相同的方法?
Are you asking how to sort a collection of strings? 您在问如何对字符串集合进行排序吗? Or how to sort the characters within one string?
或如何一个字符串中的字符排序?
Within a single ASCII string, it's dead easy. 在单个ASCII字符串中,这非常简单。 A string is just an array of bytes, so you sort it using any of the same algorithms you'd use to sort an array of integers.
字符串只是字节数组,因此您可以使用与对整数数组进行排序相同的算法对它进行排序。 C's
char
type is a one-byte integer type that can be compared, added, subtracted, etc. (It can be signed or unsigned: implementation-dependent.) C的
char
类型是一个一字节的整数类型,可以进行比较,加,减等。(可以带符号或无符号:与实现有关。)
With utf8, a single character can take multiple bytes ( char
s) to encode, so sorting the bytes will break things. 使用utf8,单个字符可以占用多个字节(
char
)进行编码,因此对这些字节进行排序会造成麻烦。
I wrote this trivial in-place selection-sort function for strings for an anagram-dictionary generator many years ago: 多年前,我为字谜字典生成器编写了这个琐碎的就地选择排序函数,用于字符串:
void sort_chars(char *string, int len) // selection sort because words are short
{
char *end_p, *search, *max_p; // *end_p == last char before '\0'
char max_val;
for(end_p = string + len - 1; end_p > string ; end_p--){
for(search = max_p = string, max_val = *max_p ; search <= end_p ; search++){
if(*search > max_val){ max_p = search; max_val = *max_p; }
}
// max_p now points to largest element, so swap
*max_p = *end_p;
*end_p = max_val;
}
}
All anagrams of a given word have the same characters, and sorted-by-character is a canonical representation of those characters. 给定单词的所有字谜都具有相同的字符,并且按字符排序是这些字符的规范表示。 So you can make an anagram-dictionary storing the sort-by-character representation of every word in
/usr/share/dict/words
, along with the original word. 因此,您可以制作一个字谜词典,将
/usr/share/dict/words
中每个单词的按字符排序表示形式与原始单词一起存储。
You could easily modify this function to sort from start to end, and look for a trailing '\\0'
(NUL) byte instead of needing an explicit length. 您可以轻松地修改此函数,使其从头到尾进行排序,并寻找尾随的
'\\0'
(NUL)字节,而不需要显式的长度。
Sorting chars in a String (sorting strings below) 对字符串中的字符进行排序(下面对字符串进行排序)
Following from the comment, you can sort a string the very same way you sort any other type
in C. You either use the qsort
function provided by the standard library, or you use your own function (eg bubble sort, heap sort, etc..) 从注释开始,您可以使用与在C中对任何其他
type
进行排序相同的方式对字符串进行排序。您可以使用标准库提供的qsort
函数,也可以使用自己的函数(例如冒泡排序,堆排序等)。 )
When using qsort
your only task is to write a compare
function to pass to the qsort
function that tells qsort
how to sort your data. 使用
qsort
您唯一的任务是编写一个compare
函数以传递给qsort
函数,该函数告诉qsort
如何对数据进行排序。 The basic declaration for qsort
is: qsort
的基本声明是:
void qsort (void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
qsort
takes 4 arguments: (1) a pointer to the list/array to be sorted, (2) the number of elements to sort, (3) the type size of each element (eg sizeof int
), and (4) lastly a pointer to your compare function. qsort
接受4个参数:(1)指向要排序的列表/数组的指针,(2)要排序的元素数,(3)每个元素的类型大小 (例如sizeof int
),以及(4)最后一个a指向您的比较函数的指针。 Note: your compare
function takes 2 generic pointers ( void
type) as its input. 注意:您的
compare
函数采用2个通用指针( void
类型)作为输入。
For sorting characters, you correctly recognize you will sort by the ascii values. 对于字符排序,您正确地认识到您将按ascii值进行排序。 Therefore, all your compare function needs to do is return whether of the two characters: (a) one is greater than the other, or (b) they are equal.
因此,您的比较功能要做的就是返回两个字符中的一个:(a)一个大于另一个,或者(b)相等。
An example of the compare
function here would be: compare
功能的示例如下:
int compare_char (const void *a, const void *b) {
if (*(char *)a != *(char *)b)
return *(char *)a - *(char *)b;
return 0;
}
Generally, the only difficult part for new C programers is figuring out how to cast the void type of the arguments to the type you need to compare. 通常,对于新C程序员而言,唯一困难的部分是弄清楚如何将参数的void类型转换为需要比较的类型 。
In the compare
function, since you are passed a pointer to type void
, you need to cast it to your type before you can dereference it to get the value at the pointer address. 在
compare
函数中,由于向您传递了一个指向void
类型的指针,因此您需要将其强制转换为您的类型,然后才能取消引用它以获取指针地址处的值。 Here casting the void *
to char *
is all you need. 您只需要在这里将
void *
为char *
。 Then you need to dereference it with '*'
before you making the comparison. 然后,在进行比较之前,需要用
'*'
对其进行取消引用。 (for a final cast/dereference of eg *(char *)a
). (例如
*(char *)a
的最终强制转换/取消引用)。 Putting it all together in a short example: 在一个简短的示例中将它们放在一起:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXS 32
/* simple compare function for qsort, returns
less than 0 if char 'b' is larger than char 'a',
a positiver number if 'a' is larger than 'b', and
zero if they are equal (note: you can return
'b' - 'a' to sort in reverse order.)
*/
int compare_char (const void *a, const void *b) {
if (*(char *)a != *(char *)b)
return *(char *)a - *(char *)b;
return 0;
}
int main (void) {
char word[MAXS] = {0};
char sorted[MAXS] = {0};
printf ("\n Enter a string: "); /* read word from stdin */
if (!scanf ("%31[^\n]%*c", word)) {
printf (" [ctrl+d] received\n\n");
return 1;
}
/* copy word to sorted before sort */
strncpy (sorted, word, sizeof word);
/* sort the chars in sorted[] */
qsort (sorted, strlen (word), sizeof *word, compare_char);
/* print results */
printf ("\n word : %s\n sorted : %s\n\n", word, sorted);
return 0;
}
Compile 编译
$ gcc -Wall -Wextra -Ofast -o bin/str_sort_char str_sort_char.c
Use/Output 使用/输出
$ ./bin/str_sort_char
Enter a string: aghibw
word : aghibw
sorted : abghiw
Sorting The Array of Strings 对字符串数组进行排序
All the explanation above originally regarding sorting by char
's, also applies to sorting an array of strings. 上面所有有关按
char
排序的说明,也适用于对字符串数组进行排序。 This also provides a good look at the way you approach using qsort
. 这也使您更好地了解使用
qsort
。 Above, in the first example, when we approached using qsort
, we had to answer the question: "What type
am I sorting?" 上面,在第一个示例中,当我们使用
qsort
,我们必须回答以下问题: “我要排序哪种type
?” Above we were sorting each char
in a null-terminated array of chars (or string
). 在上面,我们按照以null终止的chars (或
string
) 数组对每个char
进行排序。
How are strings referenced? 如何引用字符串? Through a pointer to the beginning character in the string.
通过指向字符串开头字符的指针。 So here, instead of sorting each
char
in an array of chars , we will be sorting strings
in an array of strings (or properly an array of pointers to type char *
) As far is qsort
is concerned, the only difference will be the compare
function (and the input...). 因此,在这里,我们将对
strings
数组中的字符串 (或适当地对char *
类型的指针 数组)中的字符串进行排序,而不是对chars数组中的每个char
进行排序。就qsort
而言,唯一的区别是compare
功能(以及输入...)。 We need to sort strings, so the compare
function must provide a way of comparing strings. 我们需要对字符串进行排序,因此
compare
函数必须提供一种比较字符串的方法。 In C, the standard string comparison function is strcmp
(or strncmp
to limit the number of characters compared). 在C语言中,标准的字符串比较功能是
strcmp
(或strncmp
以限制比较的字符数)。
For instance, using strcmp
to sort an array of strings, you would use something similar to: 例如,使用
strcmp
对字符串数组进行排序,将使用类似于以下内容的内容:
/* string compare function */
int compare_strings (const void *a, const void *b) {
return strcmp(*(char **)a, *(char **)b);
}
If you look at the comparison within compare_strings
, you are simply returning the result of the strcmp
function. 如果查看
compare_strings
中的比较,您只是在返回strcmp
函数的结果。 Basically, changing only the compare function (and the input), you can then use qsort
to sort your array of strings, as follows: 基本上,仅更改比较函数(和输入),然后可以使用
qsort
对字符串数组进行排序,如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* string compare function */
int compare_strings (const void *a, const void *b) {
return strcmp(*(char **)a, *(char **)b);
}
int main (void) {
char *strings[] = {"Baba", "Cece" , "Caca" , "Zaza" , "Lala"};
size_t i;
/* sort strings */
qsort (strings, sizeof strings/sizeof *strings,
sizeof *strings, compare_strings);
/* output sorted arrray of strings */
for (i = 0; i < sizeof strings/sizeof *strings; i++)
printf (" strings[%2zu] : %s\n", i, strings[i]);
return 0;
}
Output 输出量
$ ./bin/qsort_strings_static
strings[ 0] : Baba
strings[ 1] : Caca
strings[ 2] : Cece
strings[ 3] : Lala
strings[ 4] : Zaza
you can start off with 2 pointers and a loop,1 pointer pointing at string1 and the other pointing at string2 ,de-reference both and check to see whose character is greater,or if they are equal.and make the swap accordingly.Here is a code that implement this approach.This is a complete function that you can use. 您可以从2个指针和一个循环开始,1个指针指向string1,另一个指针指向string2,两者都取消引用,并检查其字符是否更大或它们是否相等。然后进行相应的交换。实现此方法的代码。这是您可以使用的完整功能。
#include <stdio.h>
int s_bubblesort(int argc,char **argv);
int main(void)
{
char *str[] = { "zzz","zhz","ydc","acb","zzb","zua","abc","zuaaa","xzz" };
s_bubblesort(9,str);
for( int n = 0 ; n < 9 ; n++ )
{
printf("%s\n",str[n]);
}
printf("\n\n");
char *words[] = {"Baba","Caca" , "Cece","Lala","Babaaaaaa", "L"};
s_bubblesort(6,words);
for( int n = 0 ; n < 6 ; n++ )
{
printf("%s\n",words[n]);
}
}
int s_bubblesort(int argc,char **argv)
{
int i , j = 0;
char *p_1 , *p_2 , *tmp;
while( j < argc )
{
for( i = 0 ; i < argc - j - 1 ; i++ )
{
p_1 = argv[i] , p_2 = argv[i+1];
while( *p_1 && *p_2 )
{
if( *p_1 > *p_2 || ( ! *(p_2 + 1) && ( *p_1 == *p_2 ) ) )
{
tmp = argv[i];
argv[i] = argv[i+1];
argv[i+1] = tmp;
break;
}
else if( *p_1 < *p_2 )
{
break;
}
p_1++;
p_2++;
}
}
j++;
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.