This question already has answers here:
Storing C++ template function definitions in a .CPP file
(13 answers)
Closed 24 days ago.
I am creating a simple MergeSort algorithm with array type(array<int,N>).
The function mergeSortByMyself is written with templates.
I want to test it with CppUnit, but when I run the code, it shows:
My .h files is "mergeModel.h", which contains:
#pragma once
#include <bits/stdc++.h>
using namespace std;
template<typename Iterator>
void print(Iterator list);
template<size_t M, size_t P>
array<int,M+P> merge(array<int,M>& arr1, array<int,P>& arr2);
template<size_t N>
array<int,N> mergeSortByMyself(array<int,N>& list);
Then, I have include "mergeModel.h" in "MergeSortByMyself.cpp", this file contains:
#include "mergeSortModel.h"
template<typename Iterator>
void print(Iterator list){
for(auto item: list ){
cout << item << " ";
}
cout << endl;
}
template<size_t M, size_t P>
array<int,M+P> merge(array<int,M>& arr1, array<int,P>& arr2){
cout << "Merge starts here......."<<endl;
int i = 0, j = 0, k = 0;
array<int,arr1.size()+arr2.size()> joined;
cout << "a1: " << arr1.size() << " a2: "<< arr2.size() << " a3: "<<joined.size()<< endl;
for(k = 0; k < joined.size(); k++){
if(i < arr1.size() && j < arr2.size() && arr1[i] < arr2[j]){
joined[k] = arr1[i];
i++;
}else if( i < arr1.size() && j < arr2.size() && arr1[i] > arr2[j]){
joined[k] = arr2[j];
j++;
}else{
break;
}
}
if(i == arr1.size()){
for(; k < joined.size();k++ ){
// cout << "j= "<<j << " k= "<<k<< endl;
joined[k] = arr2[j];
j++;
}
}
if(j == arr2.size()){
for(; k < joined.size(); k++){
joined[k] = arr1[i];
i++;
}
}
cout << "joined ";
print(joined);
return joined;
}
//array<int,N>
template<size_t N>
array<int,N> mergeSortByMyself(array<int,N>& list){
if(list.size() <= 1){
return list;
}
const int firstPart = (const int)list.size()/2;
array<int, firstPart> leftArr;
int i;
for(i=0; i < firstPart; i++){
leftArr[i] = list[i];
}
array<int,list.size() - firstPart> rightArr;
for(i=firstPart; i < list.size(); i++){
rightArr[i-firstPart] = list[i];
}
print(list);
print(leftArr);
print(rightArr);
leftArr = mergeSortByMyself(leftArr);
rightArr = mergeSortByMyself(rightArr);
array<int,list.size()> joined;
if(leftArr[leftArr.size() -1] > rightArr[0]){
joined = merge(leftArr,rightArr);
}else{
int y = 0;
for(int g = 0; g < joined.size(); g++){
if(y < leftArr.size()){
joined[g] = leftArr[y];
}else{
joined[g] = rightArr[y-leftArr.size()];
}
y++;
}
}
return joined;
}
Apparently, the code works well in the main() function:
int main(){
array<int,3> arr = {3,2,1};
array<int,3> sorted = mergeSortByMyself(arr);
print(sorted);
}
But when I try to run "mergeSortByMyself()" function using CppUnit. it shows a that error:
The file "testing.cpp" use CppUnit and "mergeModel.h":
//testing.cpp
#include "mergeSortModel.h"
#include <cppunit/TestRunner.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
// #define N 100;
template<typename Iterator>
void print(Iterator list){
for(auto item: list){
cout << item << " ";
}
cout << endl;
}
template<typename Iterator>
string toStr(Iterator list){
string str="";
for(auto item: list){
str += to_string(item);
}
return str;
}
class Test : public CPPUNIT_NS::TestCase
{
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testMergeSort);
CPPUNIT_TEST_SUITE_END();
public:
void setUp(void) {}
void tearDown(void) {}
protected:
void testMergeSort(void){
const size_t n = 12;
array<int,n> tosort;
array<int,n> tosort_test;
for(int i = 0; i < n; i++){
tosort[i] = rand()%100;
tosort_test[i] = tosort[i];
}
// copy(tosort.begin(), tosort.end(), tosort_test);
sort(tosort.begin(),tosort.end());
array<int,n> sorted = mergeSortByMyself<tosort_test.size()>(tosort_test);
CPPUNIT_ASSERT(toStr(tosort)==toStr(tosort_test));
// print(tosort);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
int main( int ac, char **av )
{
srand(time(0));
CPPUNIT_NS::TestResult controller;
CPPUNIT_NS::TestResultCollector result;
controller.addListener( &result );
CPPUNIT_NS::BriefTestProgressListener progress;
controller.addListener( &progress );
CPPUNIT_NS::TestRunner runner;
runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());
runner.run( controller );
return result.wasSuccessful() ? 0 : 1;
}
Command to run the code that I used: g++ mergeSortByMyself.cpp testing.cpp -lcppunit -o test
At the end, you were right #sklott.
There are only two ways that a compiler knows about a specific template function:
First: Pass all your template definitions(your code implementation) in the ".h" file.
Second: Write a specific implementation in the ".cpp" file.
A useful link what helped to me is this
I think the second way is not feasible for my template function because the mergeSortByMySelf() function is constantly changing the template parameter "size_t N":
template<size_t N>
array<int,N> mergeSortByMyself(array<int,N>& list)
So I decided to do the first method, which is easier, but in isocpp.org, in the link presented before, it says:
The first solution is to physically move the definition of the
template functions into the .h file, even if they are not inline
functions. This solution may (or may not!) cause significant code
bloat, meaning your executable size may increase dramatically (or, if
your compiler is smart enough, may not; try it and see).
Nevertheless, I did it.
This is "mergeSortModel.h":
#pragma once
#include <bits/stdc++.h>
using namespace std;
template<typename Iterator>
void print(Iterator list);
template<size_t M, size_t P>
array<int,M+P> merge(array<int,M>& arr1, array<int,P>& arr2);
template<size_t N>
array<int,N> mergeSortByMyself(array<int,N>& list);
//-------------------------DEFINITIONS of TEMPLATES
template<typename Iterator>
void print(Iterator list){
for(auto item: list ){
cout << item << " ";
}
// cout << "\n**********"<<endl;
cout <<endl;
}
template<size_t M, size_t P>
array<int,M+P> merge(array<int,M>& arr1, array<int,P>& arr2){
// cout << "Merge starts here......."<<endl;
int i = 0, j = 0, k = 0;
array<int,arr1.size()+arr2.size()> joined;
// cout << "a1: " << arr1.size() << " a2: "<< arr2.size() << " a3: "<<joined.size()<< endl;
// cout << "partA: ";
// print(arr1);
// cout << "\n";
// cout << "partB: ";
// print(arr2);
// cout << "\n";
for(k = 0; k < joined.size(); k++){
if(i < arr1.size() && j < arr2.size() && arr1[i] < arr2[j]){
joined[k] = arr1[i];
i++;
}else if( i < arr1.size() && j < arr2.size() && arr1[i] >= arr2[j]){
//arr1[i] >= arr2[j] This is important,
//there was an error with "arr1[i] > arr2[j]"
joined[k] = arr2[j];
j++;
}else{
break;
}
}
if(i == arr1.size()){
for(; k < joined.size();k++ ){
// // cout << "j= "<<j << " k= "<<k<< endl;
joined[k] = arr2[j];
j++;
}
}
if(j == arr2.size()){
for(; k < joined.size(); k++){
joined[k] = arr1[i];
i++;
}
}
// cout << "joined ";
// print(joined);
return joined;
}
//array<int,N>
template<size_t N>
array<int,N> mergeSortByMyself(array<int,N>& list){
if(list.size() <= 1){
return list;
}
const int firstPart = (const int)list.size()/2;
array<int, firstPart> leftArr;
int i;
for(i=0; i < firstPart; i++){
leftArr[i] = list[i];
}
array<int,list.size() - firstPart> rightArr;
for(i=firstPart; i < list.size(); i++){
rightArr[i-firstPart] = list[i];
}
// cout << "\nCall starts here.....................\n";
// print(list);
// print(leftArr);
// print(rightArr);
// cout << "\nCall ends here.....................\n";
leftArr = mergeSortByMyself(leftArr);
rightArr = mergeSortByMyself(rightArr);
array<int,list.size()> joined;
if(leftArr[leftArr.size() -1] > rightArr[0]){
joined = merge(leftArr,rightArr);
}else{
int y = 0;
for(int g = 0; g < joined.size(); g++){
if(y < leftArr.size()){
joined[g] = leftArr[y];
}else{
joined[g] = rightArr[y-leftArr.size()];
}
y++;
}
}
return joined;
}
And this is the UnitTest with CppUnit:
//testing.cpp
#include "mergeSortModel.h"
#include <cppunit/TestRunner.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
// #define N 100;
// template<typename Iterator>
// void print(Iterator list){
// for(auto item: list){
// cout << item << " ";
// }
// cout << endl;
// }
template<typename Iterator>
string toStr(Iterator list){
string str="";
for(auto item: list){
str += to_string(item)+" ";
}
cout <<"\n|"<<str<<"|\n";
return str;
}
template<size_t M>
bool test_arrays(array<int,M> a, array<int,M> b){
if(a.size() != b.size())
return false;
for(int i = 0; i < a.size(); ++i){
if(!(a[i] == b[i]))
return false;
}
return true;
}
class Test : public CPPUNIT_NS::TestCase
{
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testMergeSort);
CPPUNIT_TEST_SUITE_END();
public:
void setUp(void) {}
void tearDown(void) {}
protected:
void testMergeSort(void){
const size_t n = 73;
array<int,n> tosort;
array<int,n> tosort_test;
for(int i = 0; i < n; i++){
tosort[i] = rand()%100;
tosort_test[i] = tosort[i];
}
toStr(tosort);
toStr(tosort_test);
// copy(tosort.begin(), tosort.end(), tosort_test);
sort(tosort.begin(),tosort.end());
array<int,n> sorted = mergeSortByMyself<tosort_test.size()>(tosort_test);
cout << "------------RESULTS--------------\n";
toStr(tosort);
toStr(sorted);
CPPUNIT_ASSERT(test_arrays<n>(tosort,sorted));
// print(tosort);
// print(sorted);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
int main( int ac, char **av )
{
srand(time(0));
CPPUNIT_NS::TestResult controller;
CPPUNIT_NS::TestResultCollector result;
controller.addListener( &result );
CPPUNIT_NS::BriefTestProgressListener progress;
controller.addListener( &progress );
CPPUNIT_NS::TestRunner runner;
runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());
runner.run( controller );
return result.wasSuccessful() ? 0 : 1;
}
Command to run it: g++ testing.cpp -lcppunit -o test
Size of "test" is:
122792 Jan 25 22:55 test
Help me please.
I have a 3d vector. I need to make a new vector from this using existing internal indices. I hope the input and output information will be clear.
Input:
a = {
{ {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}, {5,5,5,5}, {6,6,6,6} },
{ {10,10,10,10}, {20,20,20,20}, {30,30,30,30}, {40,40,40,40}, {50,50,50,50}, {60,60,60,60} },
{ {100,100,100,100}, {200,200,200,200}, {300,300,300,300}, {400,400,400,400}, {500,500,500,500}, {600,600,600,600} },
};
Output:
b = {
{{ 1,1,1,1}, {10,10,10,10}, {100,100,100,100}},
{{ 2,2,2,2}, {20,20,20,20}, {200,200,200,200}},
{{ 3,3,3,3}, {30,30,30,30}, {300,300,300,300}},
{{ 4,4,4,4}, {40,40,40,40}, {400,400,400,400}},
{{ 5,5,5,5}, {50,50,50,50}, {500,500,500,500}},
{{ 6,6,6,6}, {60,60,60,60}, {600,600,600,600}},
}
I don't know how to iterate over indices in a 3D array to create a new 3D array (Output). I want to create a 3D vector from the columns (n-indices) of an existing 3D vector. I have a 3D vector ('Input'). I need to make a 3D vector out of this ('Output').
#include <iostream>
#include <vector>
using namespace std;
void show3D_vector(std::vector<std::vector<std::vector<double>>>& a);
void show2D_vector(std::vector<std::vector<double>>& a);
template<typename T> std::vector<std::vector<T>> SplitVector(const std::vector<T>& vec, size_t n);
int main()
{
a = {
{ {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}, {5,5,5,5}, {6,6,6,6} },
{ {10,10,10,10}, {20,20,20,20}, {30,30,30,30}, {40,40,40,40}, {50,50,50,50}, {60,60,60,60} },
{ {100,100,100,100}, {200,200,200,200}, {300,300,300,300}, {400,400,400,400}, {500,500,500,500}, {600,600,600,600} },
};
}
void show3D_vector(std::vector<std::vector<std::vector<double>>>& a)
{
for (double i = 0; i < a.size(); ++i)
{
for (double j = 0; j < a[i].size(); ++j)
{
for (double k = 0; k < a[i][j].size(); ++k)
std::cout << a[i][j][k] << " ";
std::cout << endl;
}
std::cout << endl;
}
}
void show2D_vector(std::vector<std::vector<double>>& a)
{
for (int i = 0; i < a.size(); i++) {
for (auto it = a[i].begin(); it != a[i].end(); it++)
{
std::cout << *it << " ";
}
std::cout << endl << endl;
}
}
template<typename T>
std::vector<std::vector<T>> SplitVector(const std::vector<T>& vec, size_t n)
{
std::vector<std::vector<T>> outVec;
size_t length = vec.size() / n;
size_t remain = vec.size() % n;
size_t begin = 0;
size_t end = 0;
for (size_t i = 0; i < std::min(n, vec.size()); ++i)
{
end += (remain > 0) ? (length + !!(remain--)) : length;
outVec.push_back(std::vector<T>(vec.begin() + begin, vec.begin() + end));
begin = end;
}
return outVec;
}
Thank you.
You can solve this matrix transpose more succinctly.
for(const auto& a1 : a){
b.resize(a1.size());
auto b1 = b.begin();
for(const auto& a2 : a1){
b1->push_back(a2);
b1++;
}
}
output is
{{1,1,1,1,},{10,10,10,10,},{100,100,100,100,},},
{{2,2,2,2,},{20,20,20,20,},{200,200,200,200,},},
{{3,3,3,3,},{30,30,30,30,},{300,300,300,300,},},
{{4,4,4,4,},{40,40,40,40,},{400,400,400,400,},},
{{5,5,5,5,},{50,50,50,50,},{500,500,500,500,},},
{{6,6,6,6,},{60,60,60,60,},{600,600,600,600,},},
Given your input and output in the example you posted, it seems to be just a transpose of the data, where n would be irrelevant.
If this is the case, the following code does this:
#include <vector>
#include <iostream>
void show3D_vector(std::vector<std::vector<std::vector<double>>>& a)
{
for (size_t i = 0; i < a.size(); ++i)
{
for (size_t j = 0; j < a[i].size(); ++j)
{
std::cout << "{";
for (size_t k = 0; k < a[i][j].size(); ++k)
{
if (k > 0)
std::cout << ",";
std::cout << a[i][j][k];
}
std::cout << "} ";
}
std::cout << std::endl;
}
}
template<typename T>
std::vector<std::vector<std::vector<T>>> Transpose(const std::vector<std::vector<std::vector<T>>>& vec)
{
if (vec.empty())
return {};
// Construct the output vector
std::vector<std::vector<std::vector<T>>>
outVect(vec[0].size(),
std::vector<std::vector<T>>(vec.size()));
// transpose loop
for (size_t row = 0; row < vec.size(); ++row)
{
for (size_t col = 0; col < vec[0].size(); ++col)
outVect[col][row] = vec[row][col];
}
return outVect;
}
int main()
{
std::vector<std::vector<std::vector<double>>> a =
{
{ {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}, {5,5,5,5}, {6,6,6,6} },
{ {10,10,10,10}, {20,20,20,20}, {30,30,30,30}, {40,40,40,40}, {50,50,50,50}, {60,60,60,60} },
{ {100,100,100,100}, {200,200,200,200}, {300,300,300,300}, {400,400,400,400}, {500,500,500,500}, {600,600,600,600} },
};
auto b = Transpose(a);
show3D_vector(b);
}
Output:
{1,1,1,1} {10,10,10,10} {100,100,100,100}
{2,2,2,2} {20,20,20,20} {200,200,200,200}
{3,3,3,3} {30,30,30,30} {300,300,300,300}
{4,4,4,4} {40,40,40,40} {400,400,400,400}
{5,5,5,5} {50,50,50,50} {500,500,500,500}
{6,6,6,6} {60,60,60,60} {600,600,600,600}
The other issue is that your show3d_vector function uses an incorrect type for the for loop counter. It should be size_t, not double.
Hello I am looking for a way to write this C++ Code in a general way, so that if a want 20 columns I will not have to write 20 for loops:
for(int i=1; i<6; i++) {
for(int j=i; j<6; j++) {
for(int k=j; k<6; k++) {
for(int m=k; m<6; m++) {
std::cout << i << j << k << m << std::endl;
}
}
}
}
It is important that my numbers follow a >= Order.
I am very grateful for any help.
This recursive function should work:
#include <iostream>
bool inc( int *indexes, int limit, int n )
{
if( ++indexes[n] < limit )
return true;
if( n == 0 ) return false;
if( inc( indexes, limit, n-1 ) ) {
indexes[n] = indexes[n-1];
return true;
}
return false;
}
int main()
{
const size_t N=3;
int indexes[N];
for( size_t i = 0; i < N; ++i ) indexes[i] = 1;
do {
for( size_t i = 0; i < N; ++i ) std::cout << indexes[i] << ' ';
std::cout << std::endl;
} while( inc( indexes, 6, N-1 ) );
return 0;
}
live example
The design here is simple. We take a std::vector each containing a dimension count and a std::vector containing a current index at each dimension.
advance advances the current bundle of dimension indexes by amt (default 1).
void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
if (indexes.size() < counts.size())
indexes.resize(counts.size());
for (size_t i = 0; i < counts.size(); ++i ) {
indexes[i]+=amt;
if (indexes[i] < counts[i])
return;
assert(counts[i]!=0);
amt = indexes[i]/counts[i];
indexes[i] = indexes[i]%counts[i];
}
// past the end, don't advance:
indexes = counts;
}
which gives us an advance function for generic n dimensional coordinates.
Next, a filter that tests the restriction you want:
bool vector_ascending( std::vector<size_t> const& v ) {
for (size_t i = 1; (i < v.size()); ++i) {
if (v[i-1] < v[i]) {
return false;
}
}
return true;
}
then a for loop that uses the above:
void print_a_lot( std::vector<size_t> counts ) {
for( std::vector<size_t> v(counts.size()); v < counts; advance(v,counts)) {
// check validity
if (!vector_ascending(v))
continue;
for (size_t x : v)
std::cout << (x+1);
std::cout << std::endl;
}
}
live example.
No recursion needed.
The downside to the above is that it generates 6^20 elements, and then filters. We don't want to make that many elements.
void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
if (indexes.size() < counts.size())
indexes.resize(counts.size());
for (size_t i = 0; i < counts.size(); ++i ) {
indexes[i]+=amt;
if (indexes[i] < counts[i])
{
size_t min = indexes[i];
// enforce <= ordering:
for (size_t j = i+i; j < counts.size(); ++j) {
if (indexes[j]<min)
indexes[j]=min;
else
break; // other elements already follow <= transitively
}
assert(vector_ascending(indexes));
return;
}
assert(counts[i]!=0);
amt = indexes[i]/counts[i];
indexes[i] = indexes[i]%counts[i];
}
// past the end, don't advance:
indexes = counts;
}
which should do it without the vector_ascending check in the previous version. (I left the assert in to do testing).
This function works for me, but do not call it with 20 if you want it to finish.
#include <list>
#include <iostream>
std::list<std::list<int>> fun (std::list<std::list<int>> inputlist, int counter)
{
if(counter == 0)
{
return inputlist;
}
else
{
std::list<std::list<int>> outputlist;
for(std::list<int> oldlist : inputlist)
{
for(int i = 1; i<6; i++)
{
std::list<int> newlist = oldlist;
newlist.push_back(i);
outputlist.push_back(newlist);
}
}
return fun(outputlist, counter - 1);
}
}
int main()
{
std::list<int> somelist;
std::list<std::list<int>> listlist;
listlist.push_back(somelist);
std::list<std::list<int>> manynumbers = fun (listlist,5);
for (std::list<int> somenumbers : manynumbers)
{
for(int k : somenumbers)
{
std::cout<<k;
}
std::cout<<std::endl;
}
return 0;
}
Same with Processing (java) here :
void loopFunction(int targetLevel, int actualLevel, int min, int max, String prefix){
/*
targetLevel is the wanted level (20 in your case)
actualLevel starts from 1
min starts from 1
max is the max number displayed (6 in your case)
prefix starts from blank
see usage bellow (in setup function)
*/
for(int m=min; m<max; m++) {
if(targetLevel==actualLevel)
{
println(prefix+ " " + m);
}
else
{
loopFunction(targetLevel, actualLevel+1,m,max,prefix+ " " + m);
}
}
}
void setup(){
loopFunction(10,1,1,6,"");
}
Well, I am not the fastest in writing answer... when I started there was no other answer. Anyhow, here is my version:
#include <iostream>
#include <vector>
using namespace std;
class Multiindex {
public:
typedef std::vector<int> Index;
Multiindex(int dims,int size) :
dims(dims),size(size),index(Index(dims,0)){}
void next(){
int j=dims-1;
while (nextAt(j) && j >= 0){j--;}
}
Index index;
bool hasNext(){return !(index[0]==size-1);}
private:
bool nextAt(int j){
index[j] = index[j]+1;
bool overflow = (index[j]==size);
if (!overflow && j < dims-1){std::fill(index.begin() + j + 1,index.end(),index[j]);}
return overflow;
}
int dims;
int size;
};
int main() {
Multiindex m(4,6);
while (m.hasNext()){
cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
m.next();
}
cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
return 0;
}
How to use standard template library std::sort() to sort an array declared as
int v[2000];
Does C++ provide some function that can get the begin and end index of an array?
In C++0x/11 we get std::begin and std::end which are overloaded for arrays:
#include <algorithm>
int main(){
int v[2000];
std::sort(std::begin(v), std::end(v));
}
If you don't have access to C++0x, it isn't hard to write them yourself:
// for container with nested typedefs, non-const version
template<class Cont>
typename Cont::iterator begin(Cont& c){
return c.begin();
}
template<class Cont>
typename Cont::iterator end(Cont& c){
return c.end();
}
// const version
template<class Cont>
typename Cont::const_iterator begin(Cont const& c){
return c.begin();
}
template<class Cont>
typename Cont::const_iterator end(Cont const& c){
return c.end();
}
// overloads for C style arrays
template<class T, std::size_t N>
T* begin(T (&arr)[N]){
return &arr[0];
}
template<class T, std::size_t N>
T* end(T (&arr)[N]){
return arr + N;
}
#include <algorithm>
static const size_t v_size = 2000;
int v[v_size];
// Fill the array by values
std::sort(v, v + v_size);
In C++11:
#include <algorithm>
#include <array>
std::array<int, 2000> v;
// Fill the array by values
std::sort(v.begin(), v.end());
If you don't know the size, you can use:
std::sort(v, v + sizeof v / sizeof v[0]);
Even if you do know the size, it's a good idea to code it this way as it will reduce the possibility of a bug if the array size is changed later.
You can sort it std::sort(v, v + 2000)
#include<iostream>
using namespace std;
void main()
{
int a[5];
int temp = 0;
cout << "Enter Values: " << endl;
for(int i = 0; i < 5; i++)
cin >> a[i];
for(int i = 0; i < 5; i++)
for(int j = 0; j < 5; j++)
if(a[i] > a[j])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
cout << "Asending Series" << endl;
for(int i = 0; i < 5; i++)
{
cout << endl;
cout << a[i] << endl;
}
for(int i = 0; i < 5; i++)
for(int j = 0; j < 5; j++)
if(a[i] < a[j])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
cout << "Desending Series" << endl;
for(int i = 0;i < 5; i++)
{
cout << endl;
cout << a[i] << endl;
}
}
you can use sort() in C++ STL. sort() function Syntax :
sort(array_name, array_name+size)
So you use sort(v, v+2000);
It is as simple as that ... C++ is providing you a function in STL (Standard Template Library) called sort which runs 20% to 50% faster than the hand-coded quick-sort.
Here is the sample code for it's usage:
std::sort(arr, arr + size);
//sort by number
bool sortByStartNumber(Player &p1, Player &p2) {
return p1.getStartNumber() < p2.getStartNumber();
}
//sort by string
bool sortByName(Player &p1, Player &p2) {
string s1 = p1.getFullName();
string s2 = p2.getFullName();
return s1.compare(s2) == -1;
}
With the Ranges library that is coming in C++20, you can use
ranges::sort(arr);
directly, where arr is a builtin array.
sort() can be applied on both array and vector in C++ to sort or re-arrange elements .
1. C++ sort() in case of a vector:
// importing vector, algorithm & iostream
using namespace std;
int main()
{
vector v = {5,4,3,2,8}; // depending on your vector size
sort(v.begin(), v.end());
cout<<v[1]; //testing the sorted element positions by printing
return 0;
}
2. C++ sort() in case of an array:
// including algorithm & iostream
using namespace std;
int main() {
int array[] = {10, 35, 85}; // array size 2000 in your case
int n = sizeof(array)/sizeof(array[0]);
sort(array, array+3);
cout<<array[0];
return 0;
}
Note: Both the above snippets were tested with modern C++ versions (11,17 & 20) before posting here .
sorting method without std::sort:
// sorting myArray ascending
int iTemp = 0;
for (int i = 0; i < ARRAYSIZE; i++)
{
for (int j = i + 1; j <= ARRAYSIZE; j++)
{
// for descending sort change '<' with '>'
if (myArray[j] < myArray[i])
{
iTemp = myArray[i];
myArray[i] = myArray[j];
myArray[j] = iTemp;
}
}
}
Run complete example:
#include <iostream> // std::cout, std::endl /* http://en.cppreference.com/w/cpp/header/iostream */
#include <cstdlib> // srand(), rand() /* http://en.cppreference.com/w/cpp/header/cstdlib */
#include <ctime> // time() /* http://en.cppreference.com/w/cpp/header/ctime */
int main()
{
const int ARRAYSIZE = 10;
int myArray[ARRAYSIZE];
// populate myArray with random numbers from 1 to 1000
srand(time(0));
for (int i = 0; i < ARRAYSIZE; i++)
{
myArray[i] = rand()% 1000 + 1;
}
// print unsorted myArray
std::cout << "unsorted myArray: " << std::endl;
for (int i = 0; i < ARRAYSIZE; i++)
{
std::cout << "[" << i << "] -> " << myArray[i] << std::endl;
}
std::cout << std::endl;
// sorting myArray ascending
int iTemp = 0;
for (int i = 0; i < ARRAYSIZE; i++)
{
for (int j = i + 1; j <= ARRAYSIZE; j++)
{
// for descending sort change '<' with '>'
if (myArray[j] < myArray[i])
{
iTemp = myArray[i];
myArray[i] = myArray[j];
myArray[j] = iTemp;
}
}
}
// print sorted myArray
std::cout << "sorted myArray: " << std::endl;
for (int i = 0; i < ARRAYSIZE; i++)
{
std::cout << "[" << i << "] -> " << myArray[i] << std::endl;
}
std::cout << std::endl;
return 0;
}
Use the C++ std::sort function:
#include <algorithm>
using namespace std;
int main()
{
vector<int> v(2000);
sort(v.begin(), v.end());
}
C++ sorting using sort function
#include <bits/stdc++.h>
using namespace std;
vector <int> v[100];
int main()
{
sort(v.begin(), v.end());
}
you can use,
std::sort(v.begin(),v.end());