C - Sort float array while keeping track of indices
Use a structure to store the value as well as index and then sort according to value.
struct str
{
float value;
int index;
};
int cmp(const void *a, const void *b)
{
struct str *a1 = (struct str *)a;
struct str *a2 = (struct str *)b;
if ((*a1).value > (*a2).value)
return -1;
else if ((*a1).value < (*a2).value)
return 1;
else
return 0;
}
int main()
{
float arr[3] = {0.4, 3.12, 1.7};
struct str objects[3];
for (int i = 0; i < 3; i++)
{
objects[i].value = arr[i];
objects[i].index = i;
}
//sort objects array according to value maybe using qsort
qsort(objects, 3, sizeof(objects[0]), cmp);
for (int i = 0; i < 3; i++)
printf("%d ", objects[i].index); //will give 1 2 0
// your code goes here
return 0;
}
keep track of previous indexes after sorting
I solved your problem by creating a struct
which contains the actual value and the index of a given number given by the user:
typedef struct num {
int index;
int value;
} num_t;
void swap(num_t *xp, num_t *yp){
num_t temp= *xp;
*xp = *yp;
*yp = temp;
}
void sort(num_t arr[], int n)
{
int i, j;
for(i = 0; i < n-1; i++)
{
for(j = 0; j < n - i - 1; j++)
if(arr[j].value>arr[j+1].value)
swap(&arr[j], &arr[j+1]);
}
}
void print(num_t arr[],int size)
{
int i;
for (i = 0; i < size; i++)
{
printf("%d[%d] ", arr[i].value, arr[i].index);
}
printf("\n\n");
}
int main()
{
int i, n;
printf("Total number: ");
scanf("%d", &n);
num_t number[n];
printf("\nInput numbers:\n");
for(i = 0; i < n; i++)
{
scanf("%d", &number[i].value);
number[i].index = i;
}
for(i = 0; i < n; i++)
{
printf("%d[%d] ", number[i].value, number[i].index);
}
n = sizeof(number) / sizeof(number[0]);
sort(number, n);
printf("\nSorted array: ");
print(number, n);
return 0;
}
Sorting and keeping track of indexes in struct
There are one of a number of sorts you can choose from. The simple sorts like bubble-sort being the worst efficient, and then various selection sorts, until you get to the longer partitioning sort where efficiency finally improves.
Here a simple selection-sort example sorting your example struct ascending will do. The selection so is as easy as any other:
void insertion_sort (struct Casa *arr, size_t size)
{
int i, j;
for (i = 0; i < (int)size; i++) {
for (j = i - 1; j >= 0; j--) {
if (arr[j].membri > arr[j + 1].membri) {
struct Casa tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
} else
break;
}
}
}
For a descending sort based on membri
you would just change the >
to a <
in:
if (arr[j].membri < arr[j + 1].membri) {
Putting it altogether in a short example using your sample data, you would have:
#include <iostream>
#include <iomanip>
struct Casa {
int id;
int membri;
};
void insertion_sort (struct Casa *arr, size_t size)
{
int i, j;
for (i = 0; i < (int)size; i++) {
for (j = i - 1; j >= 0; j--) {
if (arr[j].membri > arr[j + 1].membri) {
struct Casa tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
} else
break;
}
}
}
int main (void) {
struct Casa houses[] = { {1,2}, {5,4}, {3,6}, {2,8}, {4,10} };
size_t n = sizeof houses / sizeof *houses;
insertion_sort (houses, n);
std::cout << n << " houses sorted by membri\n\n";
for (size_t i = 0; i < n; i++)
std::cout << "id: " << houses[i].id <<
" mdmbri: " << std::setw(2) << houses[i].membri << '\n';
}
Example Use/Output
$ ./bin/struct_casa
5 houses sorted by membri
id: 1 mdmbri: 2
id: 5 mdmbri: 4
id: 3 mdmbri: 6
id: 2 mdmbri: 8
id: 4 mdmbri: 10
Or with the change made for a descending-sort:
$ ./bin/struct_casa
5 houses sorted by membri
id: 4 mdmbri: 10
id: 2 mdmbri: 8
id: 3 mdmbri: 6
id: 5 mdmbri: 4
id: 1 mdmbri: 2
Look things over and let me know if you have any additional questions.
c++ sort keeping track of indices [duplicate]
Using C++11, the following should work just fine:
template <typename T>
std::vector<size_t> ordered(std::vector<T> const& values) {
std::vector<size_t> indices(values.size());
std::iota(begin(indices), end(indices), static_cast<size_t>(0));
std::sort(
begin(indices), end(indices),
[&](size_t a, size_t b) { return values[a] < values[b]; }
);
return indices;
}
keeping track of the original indices of an array after sorting in C
There is also a method as follows under limited conditions.
#include <stdio.h>
int main(void){
int data[] ={ 5,4,1,2,3 }; //Without duplication, The number of limited range.
int size = sizeof(data)/sizeof(*data);
int keys[size];
int i;
printf("data :\n");
for(i=0;i<size;i++){
printf("%d ",data[i]);
}
for(i=0;i<size;i++){
keys[data[i]-1]=i;
}
printf("\n\ndata\tindex\n");
for(i=0;i<size;i++){
printf("%d\t%d\n", data[keys[i]], keys[i]);
}
return 0;
}
/* result sample
data :
5 4 1 2 3
data index
1 2
2 3
3 4
4 1
5 0
*/
How to sort an array of index @Kerrek is as proposed.
#include <stdio.h>
#include <stdlib.h>
int *array;
int cmp(const void *a, const void *b){
int ia = *(int *)a;
int ib = *(int *)b;
return array[ia] < array[ib] ? -1 : array[ia] > array[ib];
}
int main(void){
int data[] ={ 5,4,1,2,3 };
int size = sizeof(data)/sizeof(*data);
int index[size];//use malloc to large size array
int i;
for(i=0;i<size;i++){
index[i] = i;
}
array = data;
qsort(index, size, sizeof(*index), cmp);
printf("\n\ndata\tindex\n");
for(i=0;i<size;i++){
printf("%d\t%d\n", data[index[i]], index[i]);
}
return 0;
}
sort array in C, return sorted indices
The problem I see is that within main function - you are allocating pointer b some memory -
int * b = malloc(sizeof(int) * sizeof(a) / sizeof (*a));
The next line calls order_int(...) that returns a pointer to already allocated memory -
b = order_int(a, sizeof(a) / sizeof(*a));
Looking at the order_int function -
int * order_int (const int * ARRAY, const size_t SIZE) {
int * idx = malloc(SIZE * sizeof(int));
base_arr = malloc(sizeof(int) * SIZE);
for (size_t i = 0; i < SIZE; i++) {
base_arr[i] = ARRAY[i];
idx[i] = i;
}
qsort(idx, SIZE, sizeof(int), compar_increase);
free(base_arr); base_arr = NULL;
return idx;
}
.. you see that idx has been already been allocated the correct memory.
I would suggest removing the malloc from b - see below.
int * b = NULL;
Sort and keep track of elements
There's no off-the-shelf functionality to achieve this, but there are work-arounds. You can, for example, keep an array of user-defined structs that also contain the original position:
A = { {4,0}, {1,1}, {5,2}, {2,3}, {3,4}}
And then sort this using a custom comparator function that sorts by the value and not the original index.
A_sorted = {{1,1}, {2,3}, {3,4}, {4,0}, {5,2}}
C++ Sort vector by index
You don't want std::sort
, you want std::rotate
.
std::vector<int> v = {20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31};
auto b = std::next(std::begin(v), 3); // skip first three elements
auto const re = std::end(v); // keep track of the actual end
auto e = std::next(b, 6); // the end of our current block
while(e < re) {
auto mid = std::next(b, 3);
std::rotate(b, mid, e);
b = e;
std::advance(e, 6);
}
// print the results
std::copy(std::begin(v), std::end(v), std::ostream_iterator<int>(std::cout, " "));
This code assumes you always do two groups of 3 for each rotation, but you could obviously work with whichever arbitrary ranges you wanted.
The output looks like what you'd want:
20 21 22 26 27 28 23 24 25 29 30 31
Update: @Blastfurnace pointed out that std::swap_ranges
would work as well. The rotate
call can be replaced with the following line:
std::swap_ranges(b, mid, mid); // passing mid twice on purpose
Related Topics
How to Call a Constructor from Another Constructor (Do Constructor Chaining) in C++
How to Serialize and Deserialize a Class in C++
Infinite Loop With Cin When Typing String While a Number Is Expected
Pass by Reference/Value in C++
Why Can't the Switch Statement Be Applied on Strings
Why Do I Get the Same Sequence For Every Run With Std::Random_Device With Mingw Gcc4.8.1
Why Are Preprocessor Macros Evil and What Are the Alternatives
Raii and Smart Pointers in C++
The Static Keyword and Its Various Uses in C++
Why Is Unsigned Integer Overflow Defined Behavior But Signed Integer Overflow Isn'T
What Xml Parser Should I Use in C++
Escape Sequence \F - Form Feed - What Exactly Is It
Undefined Behavior and Sequence Points
How to Read N Bytes from a File and Put Them into a Vector<Uint8_T> Using Iterators
Why Isn't Sizeof For a Struct Equal to the Sum of Sizeof of Each Member
What Are the Barriers to Understanding Pointers and What Can Be Done to Overcome Them