If you want to use your single array sorting algorithm (bubble sort) to sort the two dimensional array then you have to add the another for loop: An outer for loop which will take care of each row. Let's say m is number of row and n is number of column.
for(k=0; k< m; k++) {
for (i = 0; i < n; i++) {
for (j = i +1; j < n; ++j) {
if (array2[k][i] > array2[k][j]) {
int swap = array2[k][i];
array2[k][i] = array2[k][j];
array2[k][j] = swap;
}
}
}
}
But this is not an efficient approach to sort the array, it's time complexity will be O(mn^2)
If you want to use your single array sorting algorithm (bubble sort) to sort the two dimensional array then you have to add the another for loop: An outer for loop which will take care of each row. Let's say m is number of row and n is number of column.
for(k=0; k< m; k++) {
for (i = 0; i < n; i++) {
for (j = i +1; j < n; ++j) {
if (array2[k][i] > array2[k][j]) {
int swap = array2[k][i];
array2[k][i] = array2[k][j];
array2[k][j] = swap;
}
}
}
}
But this is not an efficient approach to sort the array, it's time complexity will be O(mn^2)
copy all the elements of the 2d array into an 1d array then apply any sorting algorithm on 1d array & then copy back the sorted 1d array to the 2d array. please don't mind if you have a better solution then post it that will be helpfull for me.
sorting - How to sort strings in an 2D array in C - Stack Overflow
sorting of 2d arrays in C - Stack Overflow
Sort 2D array in C - Stack Overflow
Sorting a 2D array using insertion sort (C++)
Limited to stdio.h
If you are limited to using what is provided in stdio.h, then you simply have to write similar string handling functionality to what you would require from string.h. For sorting, unless you want to use a partitioning sort like quicksort or mergesort, you would be limited to a nested loop sort -- which are simpler to write -- but much much slower. (but for a 1000 or so strings, it doesn't matter, 100,000 - then there will be a perceivable difference)
To compare strings, you can write a simple strcmp() like function that requires no additional header, e.g.
/** string compare without string.h */
int strcmp_nohdr (const char *a, const char *b)
{
if (!a && !b) return 0;
if ( a && !b) return 1;
if (!a && b) return -1;
for (; *a && *a == *b; a++, b++) {}
return (*a > *b) - (*a < *b);
}
If you are not declaring an additional set of pointers to sort, then you will need to copy strings between the rows (1D arrays) in your 2D array. You can write a simple strcpy() like function that needs no header as:
/** string copy wihout string.h */
char *strcpy_nohdr (char *dest, const char *src)
{
char *p = dest;
do {
*p++ = *src;
} while (*src++);
return dest;
}
Finally, the only other thing you need is a sort function. (you will not be able to write a quick qsort() replacement) The meager Bubblesort will do. You can write a function to sort your 2D array of strings as:
#define NCHR 50
/** bubble sort of strings in 'a' (highly inefficient) */
void bubblesort2D (char (*a)[NCHR], size_t n)
{
size_t i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < (n-1); j++) {
if (strcmp_nohdr(a[j], a[j + 1]) > 0) {
char temp[NCHR];
strcpy_nohdr (temp, a[j + 1]);
strcpy_nohdr (a[j + 1], a[j]);
strcpy_nohdr (a[j], temp);
}
}
}
}
If you put those altogether in a short example (the same used before with qsort(), you would have:
#include <stdio.h>
#define NCHR 50
/** string compare without string.h */
int strcmp_nohdr (const char *a, const char *b)
{
if (!a && !b) return 0;
if ( a && !b) return 1;
if (!a && b) return -1;
for (; *a && *a == *b; a++, b++) {}
return (*a > *b) - (*a < *b);
}
/** string copy wihout string.h */
char *strcpy_nohdr (char *dest, const char *src)
{
char *p = dest;
do {
*p++ = *src;
} while (*src++);
return dest;
}
/** bubble sort of strings in 'a' (highly inefficient) */
void bubblesort2D (char (*a)[NCHR], size_t n)
{
size_t i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < (n-1); j++) {
if (strcmp_nohdr(a[j], a[j + 1]) > 0) {
char temp[NCHR];
strcpy_nohdr (temp, a[j + 1]);
strcpy_nohdr (a[j + 1], a[j]);
strcpy_nohdr (a[j], temp);
}
}
}
}
int main (void) {
char strings[][NCHR] = { "zebra", "alligators", "frogs", "racoons", "opossums" };
size_t n = sizeof strings / sizeof *strings;
bubblesort2D (strings, n);
for (size_t i = 0; i < n; i++)
puts (strings[i]);
}
Example Use/Output
The results are the same as before:
$ ./bin/sort_2d_strings_stdio
alligators
frogs
opossums
racoons
zebra
Since I originally wrote the qsort() answer, I'll leave it below as the way you would want to handle sorting (whatever array you are sorting) in practice.
In Practice Use qsort()
C provides qsort() that will sort arrays of any object based on the compare function you write to tell qsort() how elements of the array are to be compares. With strings, you just want to return the result of strcmp(). Each argument to the compare function ia a Pointers to an element of your array. Since it is a void* pointer, you must cast the pointer back to the correct type.
Recall in C that a 2D array is simply an array of 1D arrays. In your case it is a array of 50-character arrays. A pointer to an array of 50-chars has the type char (*)[50], so your qsort() compare function can be written as follows:
int cmpstr50 (const void *a, const void *b)
{
const char *pa = *(char (*)[50])a,
*pb = *(char (*)[50])b;
return strcmp (pa, pb);
}
Where each of the parameters is a pointer to an array of char [50]. Nothing could be easier. Moreover the algorithm used by qsort() will be orders of magnitude faster than what you write with nested loops.
A complete example for your case would be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmpstr50 (const void *a, const void *b)
{
const char *pa = *(char (*)[50])a,
*pb = *(char (*)[50])b;
return strcmp (pa, pb);
}
int main (void) {
char strings[][50] = { "zebra", "alligators", "frogs", "racoons", "opossums" };
size_t n = sizeof strings / sizeof *strings;
qsort (strings, n, sizeof *strings, cmpstr50);
for (size_t i = 0; i < n; i++)
puts (strings[i]);
}
Where after writing your compare function, all it takes to sort the array of strings (or array of anything) is a single call to qsort():
qsort (strings, n, sizeof *strings, cmpstr50);
Much simpler than trying to reinvent the wheel.
Example Use/Output
$ ./bin/qsort_2d_strings
alligators
frogs
opossums
racoons
zebra
Let me know if you have further questions.
This comparison is incorrect:
while((dict[j][1]<dict[k-1][1]) && (k>0))
First, if you want to compare the first character of each word, use [0] instead of [1]. This is because array indexes are zero-based in C. Second, put the k>0 comparison first, before you use k-1 as an index to the array. This will take advantage of "short circuiting" to make sure you're not using an invalid index to the array. Result:
while(k > 0 && dict[j][0] < dict[k-1][0])
Another issue is that you are not making sure your strings are null terminated when you copy them. I believe this is the reason your "SEALION" is coming out "SEALI". For example, this loop:
x=0;
while(dict[k][x]!= '\0')
{
dict[k][x]=tmp[x];
x=x+1;
}
You're checking for null on the destination instead of the source. Also, you stop copying at the null character, but you actually need to copy that too, or at least tack a null at the end:
x=0;
while(tmp[x]!= '\0')
{
dict[k][x]=tmp[x];
x=x+1;
}
dict[k][x] = '\0';
Take a close look at each of your string copy loops for such errors.
So i am trying to sort an entire 2D array using insertion sort but i always encounter an error where the program only sort each row of the array. i've tried some algorithm that i made myself but it just make the program crash. can anyone tell me what's going on here? Below is my code
#include <iostream>
#include <conio.h>
using namespace std;
int main(){
int temp, k, v, h, l = 0;
int data[3][4], sorted[3][4];
int a[9] = {1,4,6,3,9,8,5,7,2};
for(int i = 0; i < 3; i++){
for(int j = 0; j < 4; j++){
if(l < 9){
data[i][j]=a[l];
l++;
}
else{
data[i][j]=0;
}
}
}
for(int i = 0; i < 3; i++){
for(int j = 0; j < 4; j++){
cout<<data[i][j]<<" ";
}
cout<<endl;
}
cout<<endl<<endl;
//sorting
for(int i = 0; i < 3; i++){
for(int j = 0; j < 4; j++){
temp = data[i][j];
k = j-1;
while(k >= 1 && temp <= data[i][k]){
data[i][k+1] = data[i][k];
k = k-1;
}
if(temp >= data[i][k])
data[i][k+1] = temp;
else{
data[i][k+1] = data[i][k];
data[i][k] = temp;
}
}
}
//sorting baru
for(int i = 0; i < 3; i++){
for(int j = 0; j < 4; j++){
cout<<data[i][j]<<" ";
}
cout<<endl;
}
}Try declaring the function as
sort_double_array(double A[][2], int n);
Multidimensional array must have bounds for all dimensions except the first.
Try prototyping your sorting function as void sort_double_array(double *A[], int n). For extra bonus points, use size_t rather than int.
I'm offering this up only because it was one of the few things std::qsort does well that std::sort simply does not, namely sort multi-column fixed arrays: The comparator is a string of ternary statements, but should be clear enough if you stare at it long enough:
#include <iostream>
#include <random>
#include <algorithm>
int main()
{
int ar[10][2];
// populate with random data
std::random_device rd;
std::default_random_engine rng(rd());
std::uniform_int_distribution<> dist(1,20);
std::for_each(std::begin(ar), std::end(ar),
&[2]){ ar[0] = dist(rng); ar[1] = dist(rng); });
std::cout << "Before Sort..." << '\n';
std::for_each(std::begin(ar), std::end(ar),
[2]) { std::cout << ar[0] << ',' << ar[1] << '\n';});
std::qsort(ar, 10, sizeof(*ar),
->int
{
int const *lhs = static_cast<int const*>(arg1);
int const *rhs = static_cast<int const*>(arg2);
return (lhs[0] < rhs[0]) ? -1
: ((rhs[0] < lhs[0]) ? 1
: (lhs[1] < rhs[1] ? -1
: ((rhs[1] < lhs[1] ? 1 : 0))));
});
std::cout << "After Sort..." << '\n';
std::for_each(std::begin(ar), std::end(ar),
[2]) { std::cout << ar[0] << ',' << ar[1] << '\n';});
return 0;
}
Sample Run (yours will vary, obviously)
Before Sort...
2,11
18,4
20,20
14,6
8,10
17,8
14,14
3,10
20,14
19,19
After Sort...
2,11
3,10
8,10
14,6
14,14
17,8
18,4
19,19
20,14
20,20
Notes: this specifically uses strict-value comparison rather than subtraction short-cuts in the comparator so as to avoid potential underflow issues. If that is not a problem in your restricted data-space, you could easily make that comparator significantly simpler.
The built-in arrays of C and C++ are very inflexible, among other things they cannot be assigned.
Your best option would be the 'array' class from the C++ standard library, at least for the inner dimension:
array<int, 2> a[5] = { { 20, 11 },
{ 10, 20 },
{ 39, 14 },
{ 29, 15 },
{ 22, 23 } };
sort( a, a + 5 );
Edit: Some more explanations.
Here we use the property of std::array that '<' by default compares them lexicographically, i.e. starts with the first element. In order to sort things differently we have to come up with an comparator object, so if you want to use the second column as sort key you have to do this:
auto comp =
{ return u[1] < v[1]; };
sort( a, a + 5, comp );
And as mentioned in the first comment, sort(a, a+5 ... is just an ugly short form for the cleaner sort(std::begin(a), std::end(a) ...