我想问一下,如何通过它的Character来对一些字符串进行排序。 例如:“Baba”,“Cece”,“Caca”,“Zaza”,“Lala”
我想把它变成这样的 巴巴 擦擦 测测 拉拉 扎扎
如何对这些单词进行排序? 我们比较每个单词的ASCII数字吗? 如果它是一个数字我们可以交换它(使用插入排序等) 我们也可以使用相同的方法吗?
答案 0 :(得分:1)
您是否在询问如何对字符串集合进行排序?或者如何在一个字符串中对字符进行排序?
在一个ASCII字符串中,它很容易。字符串只是一个字节数组,因此您可以使用任何用于对整数数组进行排序的算法对其进行排序。 C的char
类型是一个单字节整数类型,可以进行比较,加法,减法等。(它可以是有符号或无符号的:依赖于实现。)
使用utf8,单个字符可以占用多个字节(char
s)进行编码,因此对字节进行排序会破坏事物。
多年前,我为anagram-dictionary生成器的字符串写了这个简单的就地选择排序函数:
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;
}
}
给定单词的所有字谜具有相同的字符,逐字符是这些字符的规范表示。因此,您可以创建一个anagram-dictionary,存储/usr/share/dict/words
中每个单词的逐个字符表示形式以及原始单词。
您可以轻松地修改此函数以从头到尾进行排序,并查找尾随'\0'
(NUL)字节,而不需要显式长度。
答案 1 :(得分:1)
对字符串中的字符进行排序(对字符串进行排序)
在评论之后,您可以按照与C中任何其他type
排序相同的方式对字符串进行排序。您可以使用标准库提供的qsort
函数,也可以使用自己的函数功能(例如冒泡排序,堆排序等)。
使用qsort
时,您唯一的任务就是编写compare
函数以传递给qsort
函数,该函数告诉qsort
如何对数据进行排序。 qsort
的基本声明是:
void qsort (void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
qsort
有4个参数:(1)指向要排序的列表/数组的指针,(2)要排序的元素数,(3)类型大小每个元素(例如sizeof int
),以及(4)最后一个指向比较函数的指针。注意:您的compare
函数需要2个通用指针(void
类型)作为输入。
对于字符排序,您可以正确识别出您将按ascii值排序。因此,你所有的比较函数需要做的是返回两个字符中的一个:(a)一个大于另一个,或者(b)它们是相等的。
这里compare
函数的一个例子是:
int compare_char (const void *a, const void *b) {
if (*(char *)a != *(char *)b)
return *(char *)a - *(char *)b;
return 0;
}
通常,新C程序员唯一困难的部分是弄清楚如何将参数的void类型转换为您需要的类型进行比较。
在compare
函数中,由于您传递了指向void
类型的指针,因此您需要将其强制转换为类型,然后才能取消引用它以获取值在指针地址。在这里,只需将void *
转换为char *
即可。然后,在进行比较之前,需要使用'*'
取消引用它。 (例如*(char *)a
的最终演员/解除引用)。简单介绍一下:
#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;
}
<强>编译强>
$ gcc -Wall -Wextra -Ofast -o bin/str_sort_char str_sort_char.c
使用/输出强>
$ ./bin/str_sort_char
Enter a string: aghibw
word : aghibw
sorted : abghiw
排序字符串数组
上面关于按char
排序的所有解释,也适用于排序字符串数组。这也可以很好地了解您使用qsort
的方法。上面,在第一个示例中,当我们使用qsort
接近时,我们必须回答以下问题:&#34;我在排序type
是什么?&#34; 以上我们在一个以空值终止的字符数组(或char
)中对每个string
进行排序。
如何引用字符串?通过指向字符串中起始字符的指针。所以在这里,我们不是在字符数组中对每个char
进行排序,而是在字符串数组中对strings
进行排序(或正确< em>一个指向char *
类型的指针数组。就qsort
而言,唯一的区别是compare
函数(和输入...)。我们需要对字符串进行排序,因此compare
函数必须提供一种比较字符串的方法。在C中,标准字符串比较函数是strcmp
(或strncmp
来限制比较的字符数)。
例如,使用strcmp
对字符串数组进行排序,您可以使用类似的内容:
/* string compare function */
int compare_strings (const void *a, const void *b) {
return strcmp(*(char **)a, *(char **)b);
}
如果您查看compare_strings
中的比较,您只需返回strcmp
函数的结果。基本上,只更改比较函数(和输入),然后可以使用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;
}
<强>输出强>
$ ./bin/qsort_strings_static
strings[ 0] : Baba
strings[ 1] : Caca
strings[ 2] : Cece
strings[ 3] : Lala
strings[ 4] : Zaza
答案 2 :(得分:0)
你可以从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;
}