-
Hey Guy's
I am trying to sort names in alphabetical order without using string.h library function. This is not the assignment I am solving this problem just for learning. I don't understand how to sort because each name has different length
#include<stdio.h>
int main()
{
char Name[5][10] = {"bob", "stev", "devid", "ratch", "king"};
return 0;
}
Please give some ideas to solve the problem
-
Based on this question and your other question (https://www.eevblog.com/forum/microcontrollers/rules-for-standard-uart-format/msg4607647/#msg4607647), you will benefit from understanding a general techinque:
- decide on some terminology that encapsulates your problem
- use a search engine to find some answers, (probably ignoring stackexchange results since they are only useful for "which button do I press to floggle the thingumyjig" questions)
- if that doesn't help, read this (https://entertaininghacks.wordpress.com/library-2/good-questions-pique-our-interest-and-dont-waste-our-time-2/) and then post a question on this forum or elsewhere.
That will enable us to give you the best answers.
-
Try googling: strcmp() implementation in C
You'll find lots of examples of how to write your own strcmp function.
You may also need to write a toupper() or tolower() function so you can do a case independent alphabetic comparison.
The NUL character at the end of the shorter string will always compare lower than the next character of the longer string so as long as your strcmp() terminates after comparing the NUL, not before, its easy to get the usual alphabetic sort order with the root string sorting ahead of strings extended from that root.
You will also need write a sort function to reorder of the strings - the easiest solution there is to leave them where they are and build an array of pointers to them in the correct order. In fact, for consistency and ease of manipulation, its probably preferable to define the original string array as an array of pointers to strings. see: https://overiq.com/c-programming-101/array-of-pointers-to-strings-in-c/
Then you have the choice as to whether to sort in-situ or by building a new array of pointers.
-
ChatGPT answer to the question : "sorting the names in alphabetical order without using string.h library"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_NAMES 100
char Name[5][10] = {"bob", "stev", "devid", "ratch", "king"};
void sort_names(char *names[], int n) {
for (int i = 0; i < n; i++) {
int min_index = i;
for (int j = i + 1; j < n; j++) {
if (strcmp(names[j], names[min_index]) < 0) {
min_index = j;
}
}
if (min_index != i) {
char *temp = names;
names = names[min_index];
names[min_index] = temp;
}
}
}
int main(int argc, char **argv) {
char *names[MAX_NAMES];
int n = 5;
// Store the names in the names array
for (int i = 0; i < n; i++) {
names = Name;
}
// Sort the names
sort_names(names, n);
// Print the sorted list of names
printf("\nSorted list of names:\n");
for (int i = 0; i < n; i++) {
printf("%s\n", names);
}
return 0;
}
-
And where's the learning in that?
-
And where's the learning in that?
Learns about the existance of another tool, how to use it, and hopefully why it is necessary to critically evaluate answers :)
-
And where's the learning in that?
Learns about the existance of another tool, how to use it, and hopefully why it is necessary to critically evaluate answers :)
Indeed. ;D
-
I am trying to sort names in alphabetical order without using string.h library function. This is not the assignment I am solving this problem just for learning. I don't understand how to sort because each name has different length
You need two things: a string compare function (like strcmp()), and a sort function (like qsort()).
The string compare function compares two input strings character by character. If the first string sorts before the second one, the function returns negative. If the first string sorts after the second one, the function returns positive. If the strings are equal, the function returns 0.
The function does this using a single loop, first iteration comparing first characters, and so on, until either the characters differ, or one or both strings end.
If you use qsort() (https://man7.org/linux/man-pages/man3/qsort.3.html) from <stdlib.h>, the man page includes an example.
-
ChatGPT answer to the question : "sorting the names in alphabetical order without using string.h library"
Code: [/size]
for (int j = i + 1; j < n; j++) {
if (strcmp(names[j], names[min_index]) < 0) {
min_index = j;
}
ChatGPT gets an F. strcmp() is part of string.h
To handle strings of non-matching length, you have to decide whether "bob" comes before or after "bobby." After that, it's easy:
if (endOfString(s1))
if (!endOfString(s2))
return S1ISLESS; // or S1ISGREATER
-
...
To handle strings of non-matching length, you have to decide whether "bob" comes before or after "bobby."
...
if you decide the shorter string to be the lexicographic "smaller" one (which is kind of obvious), you can simplify your program by considering the trailing '\0' as part of the string.
-
A common way to implement it on systems with ASCII-compatible character sets (including UTF-8) is to loop until the characters differ, or they are nuls. Then, the return value is ((unsigned char)(character_in_s1) - (unsigned char)(character_in_s2)).
Aw crap, here you go:
// For qsort() on arrays of strings (arrays of pointers to char or unsigned char)
int compare(const void **p1, const void **p2)
{
const unsigned char *const s1 = *(const unsigned char **)p1;
const unsigned char *const s2 = *(const unsigned char **)p2;
size_t i = 0;
while (s1[i] == s2[i] && s1[i] != '\0') {
i++;
}
return (s1[i]) - (s2[i]);
}
or, for a case-insensitive comparison that considers all whitespace equal and considers decimal numbers by value, using tolower() (https://man7.org/linux/man-pages/man3/tolower.3.html) and isspace() (https://man7.org/linux/man-pages/man3/isspace.3.html) and isdigit() (https://man7.org/linux/man-pages/man3/isdigit.3.html) from <ctype.h> (use <locale.h> and setlocale(LC_ALL, "") to make it use your locale at run time):
// For qsort() on arrays of strings (arrays of pointers to char or unsigned char)
int humancompare(const void **p1, const void **p2)
{
const unsigned char *s1 = *(const unsigned char **)p1;
const unsigned char *s2 = *(const unsigned char **)p2;
while (1) {
unsigned char c1 = *(s1++);
unsigned char c2 = *(s2++);
if (isdigit(c1) && isdigit(c2)) {
const unsigned char *end1 = s1;
const unsigned char *end2 = s2;
// Skip to end of decimal number in s1
while (isdigit(*end1))
end1++;
// Skip to end of decimal number in s2
while (isdigit(*end2))
end2++;
// Digit offset
size_t i = 0;
// Maximum number of digits to examine
const size_t n1 = (size_t)(end1 - s1);
const size_t n2 = (size_t)(end2 - s2);
// is the smaller of the two
const size_t n = (n1 < n2) ? n1 : n2;
// Compare decimal numbers from right to left
while (i < n) {
const int d = end1[-i] - end2[-i];
if (d)
return d; // Digits differ
else
i++;
}
if (i < n1) {
// First string was shorter
return -1;
} else
if (i < n2) {
// Second string was shorter
return +1;
} else {
// Decimal numbers match, continue after them
s1 = end1;
s2 = end2;
continue;
}
}
if (isspace(c1)) {
// Consider all consecutive whitespace equivalent to a single space
while (isspace(*s1))
s1++;
c1 = ' ';
} else {
// Convert to lower case
c1 = tolower(c1);
}
if (isspace(c2)) {
// Consider all consecutive whitespace equivalent to a single space
while (isspace(*s2))
s2++;
c2 = ' ';
} else {
// Convert to lower case
c2 = tolower(c2);
}
// We have a result if the characters differ or both strings end.
if (c1 != c2 || c1 == '\0')
return c1 - c2;
}
}
For human text, you'd need to use wide character strings and iswspace() (https://www.man7.org/linux/man-pages/man3/iswspace.3.html), iswdigit() (https://www.man7.org/linux/man-pages/man3/iswdigit.3.html), and towctrans() (https://www.man7.org/linux/man-pages/man3/towctrans.3.html) (with desc=wctrans("tolower") (https://www.man7.org/linux/man-pages/man3/wctrans.3.html) and desc=wctrans("toupper), since not all letters in all languages have both lower- and uppercase versions).
The conversion between "normal" multibyte strings and wide strings is done using for example mbstowcs() (https://www.man7.org/linux/man-pages/man3/mbstowcs.3.html) and wcstombs() (https://www.man7.org/linux/man-pages/man3/wcstombs.3.html).
This way, if you localize your program properly using setlocale(LC_ALL, "") (https://www.man7.org/linux/man-pages/man3/setlocale.3.html) (or for character set and types only using setlocale(LC_CTYPE, "") (https://www.man7.org/linux/man-pages/man3/setlocale.3.html)), you can sort in human-preferred order in whatever locale the user has set.
-
Did the original poster ever bother to return and read people's answers?