no matching function for call to 'begin(int [n])' - c++

Getting the error
no matching function for call to 'begin(int [n])'
I am using vectors and array and set but can't find out the reason for the error.
P.S. - I googled it but also couldn't find out anything relevant.
I tried debugging it but couldn't do it.
Here's my code!
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n, flag = 0;
scanf("%d", &n);
int a[n];
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
int index1 = distance(begin(a), find(begin(a), end(a), 2));
std::set<int> sa(a, a + n);
std::vector<int> vec(sa.size());
std::copy(sa.begin(), sa.end(), vec.begin());
int arr[vec.size()];
copy(vec.begin(), vec.end(), arr);
for (int i = 0; i < vec.size(); i++) {
for (int j = 0; j < n; j++) {
if (arr[i] == a[j]) {
int index1 = distance(begin(a), find(begin(a), end(a), i));
int index2 = distance(begin(a), find(begin(a), end(a), j));
if (index1 < n && index2 < n) {
flag = 1;
break;
}
}
}
}
if (flag) { cout << "Truly Happy\n"; }
else if (!flag) {
cout << "Poor Chef\n";
}
}
return 0;
}

Your problem is variable sized arrays, which are not part of C++ standards, and you are using it in your code.
Use std::vector<> instead of them. That means, change this
int a[n]; // to ----------------------------> std::vector<int> a(n);
and this line
std::set<int> sa(a, a + n); // to ----------> std::set<int> sa(a.begin(), a.end());
also
int arr[vec.size()]; // to -----------------> std::vector<int> arr(vec.size());
copy(vec.begin(), vec.end(), arr); // to ---> copy(vec.begin(), vec.end(), arr.begin());
then your code will work.
However,
Here
for (int i = 0; i < n; i++) { scanf("%d", &a[i]); }
it looks like you are trying to have an array filling elements from
0, 1, 2,... , n-1. This could be easily done by
std::iota. That means, the following is equivalent to the for loop, which you wrote.
std::iota(a.begin(), a.end(), 0);
Secondly, you are doing so many copying, which does not look like a
good algorithm. Especially, coping with the set sa and again coping it back to another vector(vec). This is definitely, not you
want I guess.
You do not need to use std::find on vector/ array a. Since it is
in sorted order the relation between array index and array
element is of difference 1, make use of this information to find
the index.
PS: Do not use #include<bits/stdc++.h>, see this post for more info and
using namespace std; is not a good coding practices.

Related

what's wrong with this "maximum-minimum element in an array" Logic?

I am new to coding and I am unable to see what is wrong with this Logic.
I am unable to get the desired output for this program.
The Question is to find the minimum and maximum elements of an array.
The idea is to create two functions for minimum and maximum respectively and have a linear search to identify the maximum as well as a minimum number.
#include <iostream>
#include<climits>
using namespace std;
void maxElement(int a[], int b)
{
// int temp;
int maxNum = INT_MIN;
for (int i = 0; i < b; i++)
{
if (a[i] > a[i + 1])
{
maxNum = max(maxNum, a[i]);
}
else
{
maxNum = max(maxNum, a[i+1]);
}
// maxNum = max(maxNum, temp);
}
// return maxNum;
cout<<maxNum<<endl;
}
void minElement(int c[], int d)
{
// int temp;
int minNum = INT_MAX;
for (int i = 0; i < d; i++)
{
if (c[i] > c[i + 1])
{
minNum = min(minNum,c[i+1]);
}
else
{
minNum = min(minNum,c[i]);
}
// minNum = min(minNum, temp);
}
// return minNum;
cout<<minNum<<endl;
}
int main()
{
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
minElement(arr,n);
maxElement(arr,n);
return 0;
}
You are already comparing each element to the current max / min. It is not clear why in addition you compare to adjacent elements. Trying to access a[i+1] in the last iteration goes out of bounds of the array and causes undefined behavior. Just remove that part:
void maxElement(int a[], int b)
{
// int temp;
int maxNum = INT_MIN;
for (int i = 0; i < b; i++)
{
maxNum = max(maxNum, a[i]);
}
cout<<maxNum<<endl;
}
Similar for the other method.
Note that
int n;
cin >> n;
int arr[n];
is not standard C++. Variable length arrays are supported by some compilers as an extension, but you don't need them. You should be using std::vector, and if you want to use c-arrays for practice, dynamically allocate the array:
int n;
cin >> n;
int* arr = new int[n];
Also consider to take a look at std::minmax_element, which is the standard algorithm to be used when you want to find the min and max element of a container.
Last but not least you should seperate computation from output on the screen. Considering all this, your code could look like this:
#include <iostream>
#include <algorithm>
std::pair<int,int> minmaxElement(const std::vector<int>& v) {
auto iterators = std::minmax_element(v.begin(),v.end());
return {*iterators.first,*iterators.second};
}
int main()
{
int n;
std::cin >> n;
std::vector<int> input(n);
for (int i = 0; i < n; i++)
{
std::cin >> input[i];
}
auto minmax = minmaxElement(input);
std::cout << minmax.first << " " << minmax.second;
}
The method merely wraps the standard algorithm. It isnt really needed, but I tried to keep some of your codes structure. std::minmax_element returns a std::pair of iterators that need to be dereferenced to get the elements. The method assumes that input has at least one element, otherwise dereferencing the iterators is invalid.

Best way to remove non uniques values from an array, keep the order, and not use vectors?

I apologize if this has been asked, but I ran into a coding question, which was supposed to be simple but I struggled on. Please provide a link if already answered (I may just be bad at searching).
Question: Given the sample code fill in the function to return only unique values in the array. Values must keep order.
Example Input : 1, 2, 3, 10, 4, 3, 2, 10, 1, 11, 6
Example Output: 1 2 3 10 4 11 6
Below is my solution, but I can not seem to think of an easy solution that does not include the use of a vector to store unique values. The tester did not like the use of a vector so I can only assume additional headers / libraries were unacceptable. Any other solutions? I am guessing the tester was looking for the array to be filtered in place.
#include <iostream>
#include <vector> //I was not allowed to add this...
//Function to fill in...
int fxn(int *a, int size)
{
std::vector<int> temp;
for(int i(0); i < size; ++i)
{
bool found(false);
for(auto j : temp)
{
if( j == a[i])
{
found = true;
break;
}
}
if(!found)
{
temp.push_back(a[i]);
}
}
int *ptr_a = &a[0];
for(auto j : temp)
{
*ptr_a = j;
++ptr_a;
}
return size - temp.size();
}
//The rest untochable...
void print(int *a, int size)
{
for(int i(0); i < size; ++i)
{
std::cout << a[i] << " ";
}
std::cout << std::endl;
}
int main(void)
{
int a[] = { 1, 2, 3, 10, 4, 3, 2, 10, 1, 11, 6 };
int size = 11;
int count = fxn(a, size);
print(a, size - count);
return 0;
}
Admittedly, this problem would be easier if you could use external libraries, but if you are certain you cannot, it is still solvable.
I read the question incorrectly the first time. Here is a link to as similar question.
#include<iostream>
using namespace std;
int removeDuplicates(int arr[], int n)
{
int j = 0;
for (int i=0; i < n; i++){
for(int j=0;j<i;j++){
if(arr[i]==arr[j]){
n--;
for (int k=i; k<n; k++){
arr[k]=arr[k+1];
}
i--; // you forgot to decrement i
}
}
}
return n;
}

Logical error in a C++ selection sort algorithm?

I'm brand new to C++ and am trying to write this simple selection sort function. Apologies if the answer is simple to the more experienced coders, but I am beginner and have been staring at this for a long time to no avail. Here is my code:
#include <iostream>
#include <array>
using namespace std;
array<int, 10> unsorted {3, 4, 1, 5, 7, 2, 8, 9, 6, 0};
void printarray(array<int, 10> arr) {
int count = 0;
for (int i : arr) {
if (count < arr.size()-1) {
cout << i << ", ";
} else {
cout << i << endl;
}
count++;
};
}
int selection_sort(array<int, 10> arr) {
int test;
array<int, 10> newarr;
for(int j = 0; j < arr.size(); j++) {
test = arr[j];
for(int i = j; i < arr.size(); i++) {
if(arr[i+1] < test) {
test = arr[i];
}
}
newarr[j] = test;
}
printarray(newarr);
return 0;
}
int main() {
selection_sort(unsorted);
return 0;
}
When I run this function it prints an int array containing 10 zeros. Is there an error with the way I am assigning values to the array (in C++), or rather is there a problem with the logic itself?
Both of the implementations are wrong. I just corrected #Adrisui3's answer.
Correct solution:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> array(5);
int aux;
array[0] = 10;
array[1] = 2;
array[2] = 45;
array[3] = -5;
array[4] = 0;
for(int i = 0; i < array.size(); i++)
{
int min = i;
for(int j = i+1; j < array.size(); j++)
{
if(array[j] < array[min])
{
min = j;
}
}
if (i != min)
{
aux = array[i];
array[i] = array[min] ;
array[min] = aux;
}
}
for(int k = 0; k < array.size(); k++)
{
std::cout << array[k] << std::endl;
}
}
Reference : wikipidia
That's quite a strange way to implement Selection Sort. You've made several mistakes there, as far as I can see. First of all, you can't use arr.size() in the first for loop, as it would cause the second one to just go off the limits, which causes unexpected behaviour. If by chance those were regular arrays you'd get a nice segmentation fault. Even though you don't get a run-time error, that's something you need to be aware of.
On the other hand, the main problem here is caused by the way in which you are using indexes, as well as the fact that you don't really need a second array.
Here you have an example of this algorithm.
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> array(5);
int aux;
array[0]=10;
array[1]=2;
array[2]=45;
array[3]=-5;
array[4]=0;
for(int i=0; i<array.size()-1; i++)
{
for(int j=i+1; j<array.size(); j++)
{
if(array[j]<array[i])
{
aux=array[j];
array[j]=array[i];
array[i]=aux;
}
}
}
}
Aditionally, I'd recommend you to use vector instead of array, both are STL's containers, but vector is way more flexible and useful, although it consumes some extra memory.
I hope my answer was clarifying enough. I'm here if you need any extra help. Good luck!

Function returning the index of largest value, skipping previously returned values

I need to make a function in c++ that returns the index of the largest value. Whenever it is called it should skip the index it returned previously and return the index storing the next largest value.
for eg if : -
int a[8] = {2,6,4,12,5,7,12,8}
the function should return 3 then 6 then 7, 5,1,4,2,0
Edit :-
#include <iostream>
#include <vector>
using std::vector;
int return_max_index(vector<int> valuebyweight, int n)
{
int max_index = 0;
for(int i=0; i<n; i++)
{
if(valuebyweight[i] >= valuebyweight[max_index])
{
max_index = i;
}
}
return max_index;
}
double get_optimal_value(int capacity, vector<int> weights, vector<int> values,int n) {
double value = 0.0;
vector<int> valuebyweight(n);
for(int i=0; i<n; i++)
{
valuebyweight[i] = values[i] / weights[i];
}
while(capacity!=0)
{
int max_index = return_max_index(valuebyweight, n);
if(weights[max_index] <= capacity)
{
capacity -= weights[max_index];
value += values[max_index];
}
else
{
value += (valuebyweight[max_index] * capacity);
capacity = 0;
}
}
return value;
}
int main() {
int n;
int capacity;
std::cin >> n >> capacity;
vector<int> values(n);
vector<int> weights(n);
for (int i = 0; i < n; i++) {
std::cin >> values[i] >> weights[i];
}
double optimal_value = get_optimal_value(capacity, weights, values,n);
std::cout.precision(10);
std::cout << optimal_value << std::endl;
return 0;
}
Trying to implement Fractional Knapsack algorithm. If I run the code on input
3 50
60 20
100 50
120 30
it should give the answer 180 but it returns 200 instead because my 'return_max_index' function is returning the same index again (2) but I somehow want it to skip the index it returned previously (2) and return the index that has the next highest 'valuebyweight' i.e 0.
Try this code.I made some minor changes.
#include <iostream>
#include <vector>
using std::vector;
int return_max_index(vector<int> valuebyweight, int n)
{
int max_index = 0;
for(int i=0; i<n; i++)
{
if(valuebyweight[i] >= valuebyweight[max_index])
{
max_index = i;
}
}
//if all the values in valuebyweight are 0
if(valuebyweight[max_index]==0)
{
return -1;
}
else
return max_index;
}
double get_optimal_value(int capacity, vector<int> weights, vector<int> values,int n) {
double value = 0.0;
vector<int> valuebyweight(n);
for(int i=0; i<n; i++)
{
valuebyweight[i] = values[i] / weights[i];
}
while(capacity!=0)
{
int max_index = return_max_index(valuebyweight, n);
if(max_index==-1)
{
break;
}
if(weights[max_index] <= capacity)
{
capacity -= weights[max_index];
value += values[max_index];
// assign valuebyweight[max_index] to 0 as it already participated in optimal solution and need no longer to participate.
valuebyweight[max_index]=0;
}
else
{
value += (valuebyweight[max_index] * capacity);
capacity = 0;
}
}
return value;
}
int main() {
int n;
int capacity;
std::cin >> n >> capacity;
vector<int> values(n);
vector<int> weights(n);
for (int i = 0; i < n; i++) {
std::cin >> values[i] >> weights[i];
}
double optimal_value = get_optimal_value(capacity, weights, values,n);
std::cout.precision(10);
std::cout << optimal_value << std::endl;
return 0;
}
One way to do this is to just keep the list of found indices in a static local. But then, how do you know you haven't already seen this one before? So better to make it a class. Then you can also do some optimization: sort the array once, then just pop the next highest index from the result whenever it's called:
struct mysort{
const std::vector<int>& _tosort;
mysort(const std::vector<int> tosort) : _tosort(tosort) {}
bool operator()(int a, int b){ return _tosort[a] < _tosort[b]; }
}
class IndexFinder{
private:
std::vector<int> sorted_indices;
int invoked;
public:
IndexFinder(const std::vector<int>& tosort) :
sorted_indices(tosort.size()) {
invoked = 0;
for(size_t i=0; i<tosort.size(); ++i)
sorted_indices[i] = i;
std::stable_sort(sorted_indices.begin(), sorted_indices.end(),
mysort(tosort));
}
int IndexFinder::operator()(){
return sorted_indices[invoked++];
}
};
You should put in protections to IndexFinder::operator()() to handle what happens if the user calls it more times than there are indices in the vector. As a bonus you should be pretty easily able to change it into a template class to sort things other than ints.
This is not pretty (it modifies the array), but gives an idea:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int index_of_largest(int array[], size_t len) {
int r = INT_MIN;
int d = 0;
for (int i = 0; i < len; i++) {
if (array[i] > r) {
d = i;
r = array[i];
}
}
if (r != INT_MIN) {
array[d] = INT_MIN;
}
return d;
}
int main(){
int a[8] = {2, 6, 4, 12, 5, 7, 12, 8};
int len = (int)(sizeof(a) / sizeof(a[0]));
for (int i = 0; i < len; i++) {
printf("%d\n", index_of_largest(a, len));
}
}
OUTPUT
3
6
7
5
1
4
2
0
This is a little different than the previous answer #bloer gave, but shows somewhat of a shorter method (it still uses a class) by using C++ 11 (std::iota and usage if lambda in std::sort).
#include <algorithm>
#include <iostream>
#include <vector>
class MaxIndex
{
private:
std::vector<int> index;
public:
MaxIndex(const std::vector<int>& tosort) : index(tosort.size())
{
// initialize the indices
std::iota(index.begin(), index.end(), 0);
// sort the indices based on passed-in vector
std::sort(index.begin(), index.end(), [&](int n1, int n2)
{ return tosort[n1] > tosort[n2];});
}
// return the nth highest index
int getNthMaxIndex(int n) const { return index[n]; }
};
using namespace std;
int main()
{
std::vector<int> a = {2,6,4,12,5,7,12,8};
MaxIndex mi(a);
for (size_t i = 0; i < a.size(); ++i)
cout << mi.getNthMaxIndex(i) << endl;
}
Live Example
Second, is there a reason to consistently use n if you're going to use std::vector? A std::vector knows its own size, so passing (and using) extraneous variables denoting the number of elements in a vector is inviting a bug to be introduced somewhere. Just use the std::vector::size() function if you want to get the number of elements, or just pass the vector by itself.
In addition, you should be passing things like std::vector by either reference or const reference, depending on whether the passed-in vector will be changed or not. Passing std::vector by value (as you're doing now) incurs an (unnecessary) copy.

How to run this code in less than 1 second?

How can I solve this problem without getting time limit exceeded
http://codeforces.com/problemset/problem/474/B
I tried putting all ranges in a 2D vector then looking for the desired index using binary search but it seems that the loop in the fn BS() takes a lot to execute as the size of the vector can be 10^6.
here is my code:
#include <iostream>
#include <vector>
using namespace std;
int Search(vector <vector<int> > a,int key){
int start = 0;
int end = a.size() - 1;
while (start <= end){
int mid = start + (end - start) / 2;
if (a[mid][0] > key && a[mid][1] > key){
end = mid - 1;
}
else if (a[mid][0] < key && a[mid][1] < key){
start = mid + 1;
}
else {
return mid;
}
}
return -1;
}
vector <int> BS(vector <vector <int> > v, vector<int> keys){
int j = 0;
vector <int> piles;
for (int i = 0; i < keys.size(); i++){
piles.push_back(Search(v, keys[i])+1);
}
return piles;
}
vector < vector<int> > Range(vector<int> v){
vector < vector<int> > ranges(v.size());
int sum1 = 1;
int sum2 = v[0];
for (int i = 0; i < v.size(); i++){
if (i == 0){
ranges[i].push_back(sum1);
ranges[i].push_back(v[i]);
sum1 += v[i];
}
else{
ranges[i].push_back(sum1);
sum2 += v[i];
ranges[i].push_back(sum2);
sum1 += v[i];
}
}
return ranges;
}
int main(){
int n, m;
cin >> n;
vector <int> a, q;
vector < vector <int> > v;
for (int i = 0; i < n; i++){
int k;
cin >> k;
a.push_back(k);
}
cin >> m;
for (int i = 0; i < m; i++){
int l;
cin >> l;
q.push_back(l);
}
v = Range(a);
vector <int> jucy = BS(v, q);
for (int i = 0; i < jucy.size(); i++){
cout << jucy[i] << endl;
}
}
In fact i don`t think you need 2D vector at all, you need just 1D. Which for example would look like this [2,9,12,16,25], the upper bound of each pile, you can construct this really easy. Then for every juicy worm you do binary search in that manner that it returns index with value greater or equal to the value you are looking for. The index you got from the search is the pile you are looking for.
Some pseudo-code:
A[n] - vector of upper bounds
A[0] = a0
For each 0<i<=n A[i]=A[i-1]+ai
For each q do std lower_bound on A looking for q,
the index you get is with first value equal or greater than q, so the pile where is q.
and C++ code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
int n, m;
cin >> n;
vector<int>A;
A.resize(n);
int ai;
cin >> ai;
A[0]=ai;
for (int i = 1; i < n; i++){
cin >> ai;
A[i]=A[i-1]+ai;
}
cin >> m;
int q;
for (int i = 0; i < m; i++){
cin >> q;
cout << std::distance(A.begin(),std::lower_bound(A.begin(),A.end(),q))+1<<endl;
}
return 0;
}
You have to add +1 to distance because the piles are numbered from 1. Work for the example, and looks pretty fast.
The most obvious optimization opportunity is, instead of using a vector<vector<int>> use a vector<int> and manually adjust the 2D indices to 1D. You can write a simple wrapper class that does this for you.
The reason that that will be much faster is that then all the memory will be allocated as a single contiguous unit. If you have a vector of vectors, then each row will be somewhere else and you'll have lots of cache misses.
Here's a code example:
struct 2D_Vector {
std::vector<int> me_;
int ncols_;
2D_Vector(int nrows, int ncols) : me(nrows * ncols), ncols_(ncols) {}
int & get(int y, int x) { return me_[y * ncols_ + x]; }
const int & get(int y, int x) const { return me_[y * ncols_ + x]; }
...
};
If you preallocate this with all the space that it will need, then it should use memory very efficiently.
Also, passing large function parameters by value instead of by reference is very wasteful, because it results in needless copies being made and destroyed. (Like WhozCraig pointed out.)