closed

Pages: 12
closed
Last edited on
How to i sort the array in ascending order based on int a?
Create a comparison function and pass it to std::sort.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <algorithm>

struct S
{
    int a;
    int b;
    int c;
};

bool order_by_a(const S& lhs, const S& rhs)
{
    return lhs.a < rhs.a;   
}

std::ostream& operator<<(std::ostream& out, const S& s)
{
    return out << '(' << s.a << ", " << s.b << ", " << s.c << ')';
}

int main()
{
    S array[3] = {{1, 0, 5}, {5, 2, 3}, {2, 1, 4},};
    
    for(const auto& s: array)
        std::cout << s << '\n';
    std::cout << '\n'; 
    
    using std::begin;
    using std::end;
    //http://en.cppreference.com/w/cpp/algorithm/sort
    //Sort by a using comparison function
    std::sort(begin(array), end(array), order_by_a);
    for(const auto& s: array)
        std::cout << s << '\n';
    std::cout << '\n'; 
    
    //Sort by c using lambda function
    std::sort(begin(array), end(array), 
              [](auto& lhs, auto& rhs) { return lhs.c < rhs.c; });
    for(const auto& s: array)
        std::cout << s << '\n';
    std::cout << '\n'; 
}
(1, 0, 5)
(5, 2, 3)
(2, 1, 4)

(1, 0, 5)
(2, 1, 4)
(5, 2, 3)

(5, 2, 3)
(2, 1, 4)
(1, 0, 5)
http://coliru.stacked-crooked.com/a/9f8581c9ac79e85e

How to i return a particular element based on row and col?
row is and index of array (off-by-one), column is either a, b or c for 1, 2, and 3 correspondingly
http://coliru.stacked-crooked.com/a/854384390384d939
Hi,

Thank you.

I did not manually create the array.
My array is generated like this.

for (int i = 1; i <= size; i++)
{
s.a = rand ();
s.b = rand ();
s.c = rand ();
}

in this case how should sort the array in ascending or get the particular element?
Last edited on
Exactly same way. Only thing which changes is declaration of array and filling of it.

If you have dynamic array (size of which is not known in compile time), then use vectors instead. It would be better: http://coliru.stacked-crooked.com/a/bad9d0359392ec14

As you can see, nothing really changed when I switched from array to vector and added dynamic size to it.

thank you,

instead of print(std::cout, array) << '\n';
in c++, how do you print out the array? cause cout << array[i] , no match for operator "<<"
Did you define operator<< for your type like I did earlier?
1
2
3
4
5
6
std::ostream& operator<<(std::ostream& out, const S& s)
{
    return out << '(' << std::setw(2) << s.a <<
    			 ", " << std::setw(2) << s.b <<
				 ", " << std::setw(2) << s.c << ')';
}
Remember, it is your type, so standard library does not know how to output it.

Of course you can do this manually instead of defining an operator:
1
2
3
std::cout << '(' << std::setw(2) << array[i].a <<
            ", " << std::setw(2) << array[i].b <<
            ", " << std::setw(2) << array[i].c << ')';
for my type?
ostream& operator<< is something new i come across today

I got my program compiled, but i didnt use this function - generate(array.begin(), array.end(), generate_s);

I use for (int i = 1; i <= size; i++)
{
s.a = rand ();
s.b = rand ();
s.c = rand ();
}
to generate.

cin >> size is 4.

However result after sort(array.begin(), array.end(), order_by_a);
(0,0,0)(0,0,0)(0,0,0)(0,0,0)(-1595947309,47228,8464048)
this is my result


1
2
3
4
5
6
for (int i = 1; i <= size; i++)
{
s.a = rand ();
s.b = rand ();
s.c = rand ();
} 
This will change s object size times.

You need to change elements of your array. Like array[i].a = ...
(or modify object and push them into vector)
You can read more on vectors here:
https://cal-linux.com/tutorials//vectors.html
Hello,

I been trying over the night. Thank you.
I have manage to construct, how do I use your sort function to make it acsending ?

S* array;
array= new S[size];

S *s = &array[0];

for (int i = 1; i <= size; i++)
{
s->a = rand ();
s->b = rand ();
s->c = rand ();
++s;
}
Last edited on
Ok, so you decide to use arrays. In this case it would be slightly harder.
Instead of requesting container about its begin and end, we need to do it ourselves (because arrays are dumb).

Luckily pointers can be used as iterators. We just need to create a pointer to the beginning of the array (we can use array name for that, it will decay to pointer) and pointer past-the-end (we need to advance begin pointes size times).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Create array of size size
S* array = new S[size]; 

//Fill array
for (int i = 0; i < size; ++i) { // Canonical form of loop
    s[i].a = rand ();
    s[i].b = rand ();
    s[i].c = rand ();
}
// Sort array
std::sort( array, // Beginning of array
           array + size, // Past-the-end of array
           order_by_a); // Sorting function

// You can write it in one line. This was just for exposition
// std::sort(array. array + size, order_by_a); 


You can read more on standard library uiniform approach to algorithms, iterator concept and more here: https://cal-linux.com/tutorials/STL.html
it works! Thank you

For finding an element, it compiled but i am unsure why the program crashes

S* array;
cin >> row >> col;

switch(col) {
case 1: cout << "The value is " << array[row-1].a;
case 2: cout << "The value is " << array[row-1].b;
case 3: cout << "The value is " << array[row-1].c;
default: cout << "not valid" << endl;
}
1
2
S* array;
cin >> row >> col; 
DId you fill the array? Right now in your code array is a garbage pointer. You need to allocate memory and initialize members, like in sorting example.
Hmm, it could execute now but it return me garbage value.

S* array = new S[size];
cin >> row >> col;

switch(col) {
case 1: cout << "The value is " << array [row-1].a;
break;
}
What do you expect? What did you set that value to before?
first i generate a array of structure
then sort and printed out the sorted order

now for finding a particular element

S* array = new S[size];
cin >> row >> col;

switch(col) {
case 1: cout << "The value is " << array[row-1].a;
break;
case 2: cout << "The value is " << array[row-1].b;
break;
case 3: cout << "The value is " << array[row-1].c;
break;
default: cout << "not valid" << endl;
}

so i type in 2 3,
the return value is 7939760
S* array = new S[size]; Creates a new array. Completely new without relation to any previous arrays. So values here would be completely different.

You need to use old one. For example like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
S* array = new S[size]; 
for (int i = 0; i < size; ++i) { // Canonical form of loop
    s[i].a = rand ();
    s[i].b = rand ();
    s[i].c = rand ();
}
std::sort( array, array + size, order_by_a);
for(int i = 0; i < size; ++i)
    std::cout << '(' << std::setw(2) << array[i].a <<
                ", " << std::setw(2) << array[i].b <<
                ", " << std::setw(2) << array[i].c << ')';

int row, col;
std::cin >> row >> col;
std::cout << "The value is ";
switch(col) {
    case 1: std::cout << array[row-1].a; break;
    case 2: std::cout << array[row-1].b; break;
    case 3: std::cout << array[row-1].c; break;
    default: std::cout << "not valid\n";
}
sorry, i didnt make it clear.

without declaring the new S[size], program crashes as previously.

I cant use back the old one as "array" is in different function(function1) and i cant pass the "array" variable over to function2) as main function first call function 1 -> call main function -> call function 2.

s* array;
switch(col) {
case 1: cout << "The value is " << array[row-1].i;
}

program crashes.
what is the best way for this?
Last edited on
To declare your array in main and pass it to both functions.
Or make first function return pointer to array and size and second one to thake it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::pair<Element*, int> create_array();
void display(const std::pair<Element*, int>&);

int main()
{
    auto arr = create array();
    display(arr);
}

void display(const std::pair<Element*, int>& arr_pair)
{
    Element* array = arr_pair.first;
    int size = arr_pair.second;
    //...
}
Or
1
2
3
4
5
6
7
8
9
10
11
//Passed by reference, so chnges to argumnts would be reflected on originals
void create_array(Element*&, int&);
void display(Element*, int);

int main()
{
    Element* array;
    int size;
    create array(array, size);
    display(array, size);
}

Thank you for aiding in my understanding on c++

I am able to find a specific element, is it possible if i delete based on row and col?

(1,2,3)
(4,5,6)
(7,8,9)
(10,11,12)

i type in 2 ,3
(7,8,9) is remove, left

(1,2,3)
(4,5,6)
(10,11,12)
Yes, it is possible. In your case we are only interested in row.

For arrays you will need to move all further elements back (rewriting old ones) and update size accordingly. So if we want to delete third element of array, you would have (before and after)
size = 6---\
1 2 3 4 5 6
1 2 4 5 6 ?
size = 5-/

Either do it manually throug loop or look for standard library algorithm which can help you (there are two which can be used here).

If you would use vectors (which are superior to arrays), you would have to just ask it to delete that element:
1
2
3
std::vector<Element> array;
//...
array.erase(array.begin() + row);
Pages: 12