如何在C中对没有string. h库的字符串进行排序[duplicate]

qvk1mo1f  于 2023-01-12  发布在  其他
关注(0)|答案(2)|浏览(141)
    • 此问题在此处已有答案**:

How to sort array of strings in ascending order in C(6个答案)
20天前关闭。

#include <stdio.h>
int main()
{
    char * str[ ]={"C  program", "Basic", "Foxbase+", "Fortran", "Pascal"};
    int i,j;
    char * temp;        
    int k;                  
    for(i=0;i<4;i++)  
    {
        k=i;          
        for(j=i+1;j<5;j++)  
            if(str[i] < str[j]) k=j;
        temp=str[i]; str[i] = str[k]; str[k] = temp;  
    }
    for(i=0;i<5;i++)
        printf("%s\n",str[i]);
    return 0;
}

我想按字母顺序(ASCII)对上面给出的字符串进行排序,但我做不到,我已经知道这段代码的错误部分是

if(str[i] < str[j]) k=j;

我试过很多次了,都没用。我已经试过了:* str [i]〈* str [j](不起作用,我认为这是合理的?)
顺便说一句,使用string. h是不允许的,我怎么才能把这里的一切都做好呢?
一些话:对不起我发布了这个问题,这是愚蠢的,我不知道,即使我不能使用字符串. h,我也可以使用stdlib. h使用strcmp函数,我当时感到困惑,但现在一切都清楚了。感谢大家花时间在这里,我很感激,并再次抱歉问这个愚蠢的问题。

yr9zkbsy

yr9zkbsy1#

从这个问题的注解中可以看出,你不被允许使用任何库函数--因此你需要手动比较这些字符串(注意,你不能只比较指针,这些可能是任意地址,你需要比较字符串指向什么!)--而且你甚至不被允许编写一个单独的函数,你也需要内联这段代码。
一般来说,字符串比较可能如下所示(这里仍然是一个函数):

int cmp(char const* x, char const* y)
{
    for(; *x && *y; ++x, ++y)
    {
         if(*x != *y)
             // first position where the strings differ:
             // x < y lexicographically if *x < *y, thus *x - *y < 0
             // x > y analogously, so:
             return *x - *y;
             // this gives you the equivalence: x # y <=> cmp(x, y) # 0
             // with # being any comparison operator
    }
#if 0
    if(*x)
        return 1; // x is longer, thus x > y
    if(*y)
        return -1; // y is longer, thus x < y
    return 0; // both equal
#else
    // actually, as the null terminator is smaller than any other character
    // anyway, we still can simply:
    return *x - *y;
#endif
}

编辑:还有一个更简单的解决方案(感谢@Lundin的提示),只要字符串仍然 * 可以 * 相等,就进行迭代:

while(*x && *x == *y) // covers *y being 0, too!
{
    ++x; ++y;
}
return *x - *y;

旁注:如果字符串包含字符范围(从128到255,包括128和255;在您的示例中没有问题):未指定原始char是有符号的还是无符号的-这会在比较不位于char范围的相同一半(200 - 100 = 100 > 0<->-56 - 100 = -156 < 0)中的字符时产生差异。如果在任何差异或比较(以上和以下)时强制转换为unsigned char,则可以在不同平台上实现更一致的行为:

return static_cast<unsigned char>(*x) - static_cast<unsigned char>(*y);

一般来说,使用这样的函数是更好的解决方案。也许你会再问一次,你是否被允许写一个新函数!
否则,在您的情况下,您可以减少测试代码,使其更小,因此:

char const* cur = str[j];
char const* min = str[k];
while(*cur && *cur == *min)
{
    ++cur; ++min;
}
if(*cur < *min)
{
    // cur is lexicographically smaller or shorter than min!
    // -> found a new minimum
    k = j;
}
omhiaaxx

omhiaaxx2#

而不是将指针与

if(str[i] < str[j])  // Compare pointers

代码需要比较这些指针引用的 * 字符串 *。

if (strcmp(str[i], str[j]))  // Compare strings

由于OP有义务不使用strcmp(),通过比较字符串,一次一个字符(如unsigned char)相等(而不是一个 * 空字符 *),使自己的。报告零时,相同或负或正对应的符号的差异。

// Use const to allow for pointers to const strings. 
int my_strcmp(const char *x, const char *y) {
  // Convert to unsigned char * as `strcmp()` compares "as if"
  // the characters were all unsigned.
  const unsigned char *ux = (const unsigned char*) x;
  const unsigned char *uy = (const unsigned char*) y;

  // Test for equality and null character.
  // I like to place the more likely to fail one first.
  while ((*ux == *uy) && *ux) {
    ux++;
    uy++;
  }

  // On rare machines, using `return *ux - *uy` may overflow. 
  // To avoid overflow, use 2 tests.
  // Good compilers see this idiom and emit efferent code.
  return (*ux > *uy) - (*ux < *uy);
}

相关问题