the error is:
/usr/include/c++/4.8/bits/stl_algo.h:2159:29: error: invalid conversion from 'int' to 'const char*' [-fpermissive]
if (__comp(*__i, *__first))
I am passing 2 strings X and Y. Now the sort should compare XY and YX and then return the X if XY>YX or return Y. X and Y will have values like - 33 or 9999.
string Solution::largestNumber(const vector<int> &A) {
int i,n;
vector<string> B;
string str;
for(i=0; i<A.size(); i++)
{
B[i]=to_string(A[i]);
}
sort(A.begin(), A.end(),[](const string lhs, const string rhs){
return rhs+lhs < lhs+rhs;
});
for(i=0; i<A.size(); i++)
{
str+= to_string(A[i]);
}
return str;}
You are calling std::sort on a range from A which is a std::vector<int>, so the compare function should compare int-s.
You could fill B initially with 0,1, .... A.size()-1 then, given two indexes i1 and i2 to compare, construct the strings and compare them.
the error is: /usr/include/c++/4.8/bits/stl_algo.h:2159:29: error: invalid conversion from 'int' to 'const char*' [-fpermissive] if (__comp(*__i, *__first))
sort(A.begin(), A.end(),[](const string lhs, const string rhs){...});
Your sort comparator is expecting to compare two std::strings. The element type of A is int. You created B to be a conversion of A's elements to B's element type of std::string. Use B.
Other notes:
string Solution::largestNumber(const vector<int> &A) {
int i,n; // n???
// vector<string> B; // B is empty. Calling B[i] will cause a
// segfault for attempting to access memory
// out of bounds.
vector<string> B(A.size()); // Fix: pass in the size. Now creates B
// with size elements that can be accessed.
string str;
// Consider using algorithms like std::transform
for(i=0; i<A.size(); i++)
{
B[i]=to_string(A[i]); // You won't segfault here now.
}
// Corrected your sort.
sort(B.begin(), B.end(),[](const string lhs, const string rhs){
return rhs+lhs < lhs+rhs;
});
// Appending should be done on the sorted string vector. Consider using
// a ranged-based for loop here.
for(i=0; i<B.size(); i++)
{
str+= B[i];
}
return str;
}
Related
This question already has answers here:
What is a segmentation fault?
(17 answers)
Closed 2 years ago.
Problem:
A student signed up for workshops and wants to attend the maximum
number of workshops where no two workshops overlap. You must do the
following: Implement structures:
struct Workshop having the following members: The workshop's start time. The workshop's duration. The workshop's end time.
struct Available_Workshops having the following members: An integer, (the number of workshops the student signed up for). An
array of type Workshop array having size . Implement functions:
Available_Workshops* initialize (int start_time[], int duration[], int n) Creates an Available_Workshops object and
initializes its elements using the elements in the and parameters
(both are of size ). Here, and are the respective start time and
duration for the workshop. This function must return a pointer to
an Available_Workshops object.
int CalculateMaxWorkshops(Available_Workshops* ptr) Returns the maximum number of workshops the student can attend—without overlap.
The next workshop cannot be attended until the previous workshop
ends. Note: An array of unkown size ( ) should be declared as
follows: DataType* arrayName = new DataType[n];
Your initialize function must return a pointer to an
Available_Workshops object. Your CalculateMaxWorkshops function
must return maximum number of non-overlapping workshops the student
can attend.
Sample Input
6
1 3 0 5 5 8
1 1 6 2 4 1
Sample Output
4
Explanation The first line denotes , the number of workshops. The next line contains space-separated integers where the integer
is the workshop's start time. The next line contains
space-separated integers where the integer is the workshop's
duration. The student can attend the workshops and without
overlap, so CalculateMaxWorkshops returns to main (which then
prints to stdout).
MY CODE:
#include <iostream>
using namespace std;
class Workshop{
public:
int start_time{},duration{},end_time{};};
class Available_Workshops
{
public:
int n{};
struct Workshop*arr=new struct Workshop[n];
~Available_Workshops()
{
delete [] arr;
}
void arr_sort();
void arr_delete(int i);
};
////////////////////////////////////////////////////////////////////////////////////////////
Available_Workshops * initialize(int start_time[],int duration[],int n)
{
Available_Workshops * x=new Available_Workshops{};
x->n=n;
for(int i=0;i<n;i++)
{
x->arr[i].start_time=start_time[i];
x->arr[i].duration=duration[i];
x->arr[i].end_time=start_time[i]+duration[i];
}
return x;
}
///////////////////////////////////////////////////////////////////////////////////////////
void Available_Workshops:: arr_delete(int i)
{
n-=1;
for(int j=i;j<n;j++)
{
arr[j]=arr[j+1];
}
}
///////////////////////////////////////////////////////////////////////////////////////////
void Available_Workshops:: arr_sort()
{
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(arr[i].start_time>arr[j].start_time)
{
struct Workshop temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int CalculateMaxWorkshops(Available_Workshops * x)
{
x->arr_sort();
for(int i=0;i<x->n-1;i++)
{
for(int j=i+1;j<x->n;j++)
{
if(x->arr[i].end_time>x->arr[j].start_time)
{
if(x->arr[i].duration>=x->arr[j].duration)
x->arr_delete(i);
else x->arr_delete(j);
j--;
}
}
}
int y=x->n;
delete x;
return y;
}
int main(int argc, char *argv[]) {
int n; // number of workshops
cin >> n;
// create arrays of unknown size n
int* start_time = new int[n];
int* duration = new int[n];
for(int i=0; i < n; i++){
cin >> start_time[i];
}
for(int i = 0; i < n; i++){
cin >> duration[i];
}
Available_Workshops * ptr;
ptr = initialize(start_time,duration, n);
cout << CalculateMaxWorkshops(ptr) << endl;
return 0;
}
My code is not running. It has segmentation fault. Please help me find this error
You bug can be seen from the class declaration:
class Available_Workshops
{
public:
int n{};
struct Workshop* arr = new struct Workshop[n];
~Available_Workshops()
{
delete[] arr;
}
void arr_sort();
void arr_delete(int i);
};
Member n gets explicitly initialized to 0. Yet, your initialize function will happily fill in more elements into arr (an array of zero elements) and cause all kinds of undefined behavior.
You really, really want a proper constructor for your class instead of trying to inline initialize the members.
Available_Workshops(int size) :
n(size)
{
arr = new Workshop[n];
}
Another issue, although not related to your crash is inside your arr_delete function.
for (int j = i; j < n; j++)
{
arr[j] = arr[j + 1];
}
When j == n-1 on the last iteration of the loop, it will execute arr[n-1] = arr[n]. Accesing arr[n] is undefined behavior since the only valid indices in the array are from [0..n-1]
I'm trying to find an optimized way to this problem-
https://www.codechef.com/KJCS2019/problems/TSHACK
int findanswer(int k,const multiset<pair<int,int> >&a2)
{
int freq=0;
while(k>0)
{
multiset<pair<int,int> >::iterator itt=a2.end();
k-=itt.second;
a2.erase(itt);
++freq;
}
return freq;
}
int main()
{
cin>>n>>q;
map<int,int>a;
multiset<pair<int,int> > a2;
for(int i=0;i<n;i++)
{
int b;
cin>>b;
++a[b];
}
for(auto it:a)
a2.insert(make_pair(it.second,it.first));
while(q--)
{
int k;
cin>>k;
int ans=findanswer(k,a2);
cout<<ans<<endl;
}
}
the error message :
prog.cpp: In function 'int findanswer(int, const std::multiset<std::pair<int, int> >&)':
prog.cpp:18:16: error: 'std::multiset<std::pair<int, int> >::iterator {aka struct std::_Rb_tree_const_iterator<std::pair<int, int> >}' has no member named 'second'
k-=itt.second;
^
prog.cpp:19:21: error: passing 'const std::multiset<std::pair<int, int> >' as 'this' argument discards qualifiers [-fpermissive]
a2.erase(itt);
^
As I said earlier, I want to know the reason why the iterator in the called function not identifying the datatype of the multiset.
First problem:
You want to access the data which the iterator is pointing to and not the iterator itself. So you simply have to replace:
k-=itt->second;
Next problem:
int findanswer(int k,const multiset<pair<int,int> >&a2)
This defines your ref a2 as const. As const you can't modify your multiset. So you have to remove const here.
I am finding connected components of a graph.
Condition : Those components should not be printed in same function, but they should be printed in calling function ( i.e. int main() )
I have gone through the link but got some error.
Returning multiple values from a C++ function
tuple <vector<int>&, int > connected( vector<int>& store, ...)
{
int component_size = 0;
// code
return make_tuple ( store, component_size);
}
int main()
{
// code
for( int i = 0 ; i < V; i++ )
{
if( !visited[i])
{
tie( ans, compo_size ) = connected(edges,
visited, myQ, store, V, i);
for(int i = 0 ; i < compo_size; i++ )
{
cout<< ans[i] <<" ";
}
}
}
}
There are few errors :
error: could not convert 'std::make_tuple(_Elements&& ...) [with _Elements = {std::vector >&, int&}](component_size)' from 'std::tuple >, int>' to 'std::tuple >&, int>'
return make_tuple ( store, component_size);
^
error: invalid initialization of reference of type 'std::vector&' from expression of type 'std::vector'
tie( ans, compo_size ) = connected(edges, visited, myQ, store, V, i);
How to return multiple values (vector and one int value) through function
A function can have at most one return value.
Returning more objects can be emulated by either
modifying one or more objects that are global or are referenced by arguments through indirection or by
returning an object of class type that has multiple sub objects.
You've attempted the latter approach through the use of tuple class template. The reason it doesn't work is explained in the documentation:
template< class... Types >
tuple<VTypes...> make_tuple( Types&&... args );
For each Ti in Types..., the corresponding type Vi in VTypes... is std::decay<Ti>::type unless application of std::decay results in std::reference_wrapper<X> for some type X, in which case the deduced type is X&.
As such, your invocation of make_tuple is deduced to return tuple <vector<int>, int > which is wrong because the function is supposed to return tuple <vector<int>&, int > instead. This can be fixed using std::ref so that the correct type is deduced:
std::make_tuple(std::ref(store), component_size);
As eerorika mentioned, you could use std::ref() as follow:
std::tuple <std::vector<int>&, int > connected( std::vector<int>& store, ...)
{
int component_size = 0;
// code
return std::make_tuple ( std::ref(store), component_size);
}
However, there is really no point in returning a reference to the input vector since it is already a non-const reference on input. So changing the vector in place is going to be enough. On return you get a modified version. However, that's probably not what you are looking to do (i.e. you probably wanted to make a copy of store and return the copy with the other arrays appended...)
That also means you're going to have yet another copy when you create the tuple:
std::tuple <std::vector<int>, int > connected( std::vector<int>& store, ...)
{
int component_size = 0;
std::vector<int> result;
// or maybe a straight copy, depends on your needs in "code"
//std::vector<int> result(store);
// code
return std::make_tuple ( result, component_size);
}
As mentioned by others, having a result in the list of arguments is probably your best bet:
int connected( std::vector<int> & result, std::vector<int> const & store, ...)
{
int component_size = 0;
// code
return component_size;
}
Also, wouldn't component_size == result.size() be true? If so, you should not return anything because it's going to be more confusing.
That simplifies the function to this point:
void connected( std::vector<int> & result, std::vector<int> const & store, ...)
{
// code
}
I created a class "config" that contains 12 bool values, organized in a std::array. The class has an "icing" function that returns a double value.
Trying to order a vector of 2^12 (4096) configs through a std:: sort (contained in #include ) using a predicate i have written, i get a segmentation fault error.
Shrinking the vector to 205 (not 1 more) eliminates the error, but I don't know why.
If i make the vector 4096 long, and try to sort only a little part, it works until the part is long 175+.
Shrinking the vector to for example around 1000, limits the partial sorting to around 20, before it gives the segmentation error.
#include <array>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
class config {
public:
config (){ //constructor, default
array<bool,12> t;
for (bool& b: t){
b=false;
}
val=t;
g=1;
}
config (const config& fro): val(fro.val){}; //copy constructor
array<bool,12> get_val(){ return val; } //returns the array
void set_tf(int n, bool tf){ val[n]=tf; } //sets a certain boolean in the array to false/true
void set_g(double d){ g=d; } //this sets the constant for calculation to a number
void print(){
cout<<"values: ";
for (auto b: val){ cout<<b<<" "; }
cout<<endl;
}
config & incr(int n=1){ //this increases the vector by 1 following the rules for binary numbers, but has the digits reversed
for(int j=0; j<n; j++){
int i=0;
bool out=false;
while(val[i]==true){
val[i]=false;
i++;
}
val[i]=true;
}
return *this;
}
double energy(){
int ct=0;
int cf=0;
for(auto b:val){ if(b==true){ ct++; } else { cf++; } }
return (abs(ct-cf));
}
double icing(){ //here is the "value" for ordering purposes
int n=0;
for(int i=0; i<11; i++){
if(val[i]!=val[i+1]){ n++; }
}
double temp=-g*n+this->energy();
return temp;
}
private:
array<bool,12> val;
double g;
};
bool pred (config c1, config c2){ return c1.icing()>c2.icing(); } //this sets the ordering predicate
template <typename T> //this orders the vector
void csort (vector <T>& in){
sort(in.begin(), in.end(), pred);
}
int main(){
vector<config> v;
for (int i=0; i<4096; i++){ //cicle that creates a vector of successive binaries
for(auto& c:v){
c.incr();
}
config t;
v.push_back(t);
}
sort(v.begin(), v.begin()+174, pred); //this gives seg.fault when 175+
csort(v); //this gives segmentation fault when the vec is 206 long or longer
}
I expected the code to order the vector, but it goes into segmentation fault.
Your program has undefined behaviour in sort function because your predicate takes config by value, so copies are made and in this place copy constructor is called which copies only array val, but not g.
bool pred (config c1, config c2){ return c1.icing()>c2.icing(); }
// takes by value, copy ctor is called
config (const config& fro): val(fro.val){}; // only val is copied, g HAS GARBAGE VALUE
// icing in pred uses g !! - stric weak ordering is violated because g has GARBAGE VALUE
Fix 1:
pass config by const config&:
bool pred (const config& c1, const config& c2){ return c1.icing()>c2.icing(); }
or fix 2:
g is initialized in copy constructor:
config (const config& fro): val(fro.val), g(fro.g){};
I think the argument types are wrong. Also can you check whether the sort function will work properly or not?? I have written this code to make the largest no possible by combining the integers in vector A.
string Solution::largestNumber(const vector<int> &A) {
int i,n;
vector<string> B;
string str;
for(i=0; i<A.size(); i++)
{
n=sprintf(B[i],"%d",A[i]);
}
sort(A.begin(), A.end(),[](string lhs, string rhs){
//[](const string &lhs, const string &rhs) {
// reverse the order of comparison to sort in descending order,
// otherwise we'll get the "big" numbers at the end of the vector
return rhs+lhs < lhs+rhs;
});
for(i=0; i<A.size(); i++)
{
str+= to_string(A[i]);
}
return str;
}
B is a vector of std::string.
B[I] is then a std::string
sprintf expects an array of char, not a std::string.