I included the "not using strings" part in the title because when I was searching to find an answer on here I saw this problem a lot but it was with people using strings and getting chars mixed up. This is not my issue.
Trying to call an element of a 2D vector and see if it equals a certain number. I'm getting the comparison between pointer/integer error and I don't understand why. Here's my code, any help would be really appreciated.
bool UsedInRow(vector< vector<int> > vec(int n, vector<int> (int n)), int row, int num)
{
int n;
for (int col = 0; col < n; col++)
{
if (vec[row][col] == num)
{
return true;
}
}
return false;
}
Try this:
bool UsedInRow(const vector< vector<int> >& vec, int row, int num) { ... }
The expression you used vector< vector<int> > vec(int n, vector<int> (int n)) is actually a function pointer.
The compiler thinks that you are passing a function pointer.
Instead, pass the vector by reference:
bool UsedInRow(vector< vector<int> > &vec, int row, int num)
As the other answers point out, vec is a function pointer, not a vector.
You're being advised to change vec to a vector, but it's not clear that that's the right solution. There's no ambiguity in your declaration; vec is defined as a parameter of function pointer type.
If that's what you intended, you need to replace the reference to vec inside the function with a function call. For example, you might change
if (vec[row][col] == num)
to
if ((vec(42, something))[row][col] == num)
where something would itself have to be a function pointer, pointing to a function that takes an int argument and returns a vector<int> result.
The declaration of your UsedInRow function is quite complicated, and I can't tell how it's intended to be used.
If vec really should be just a vector, then you can make it one by deleting the (int n, vector<int> (int n)) part of the parameter declaration -- but then I'd have to wonder why you wrote it in the first place.
For a definitive answer, you'd need to explain to us what your UsedInRow function is supposed to do.
Related
I was doing a problem on TopCoder for finding the longest path in an acyclic directed graph. I have used vector of type bool for visiting vertices. But it is giving me these errors (highlighted in the code below):
error: no match for ‘operator=’ (operand types are ‘std::vector<bool>’ and ‘bool’)
visited[cur_ver]=true;
error: no match for ‘operator==’ (operand types are ‘std::vector<bool>’ and ‘bool’)
if(visited[i]==false)
Here is my code:
#include<bits/stdc++.h>
using namespace std;
class Circuits{
vector<int>adj[51];
vector<int>cost[51];
vector<int>T[51];
vector<bool>visited[51];
vector<int>dist[51];
int glm=0;
public:
void topological_sorting(int cur_ver,int n){
visited[cur_ver]=true; //error 1
for(int i=0;i<adj[cur_ver].size();i++){
if(visited[i]==false) //error 2
topological_sorting(i);
}
T.insert(T.begin(),cur_ver);
}
void Longest_Path(int s,int n){
for(int i=0;i<=n;i++)
dist[i]=NINF;
dist[s]=0;
for(int i=0;i<=n;i++){
int u=T[i]
if(dist[u]!=NINF)
for(int j=0;j<adj[i].size();j++){
int v=adj[u][j];
if(dist[v]<dist[u]+cost[u][v])
dist[v]=dist[u]+cost[u][v];
}
}
for(int i=0;i<=n;i++)
if(dist[i]>glm)
glm=dist[i];
}
int howLong(vector<string>connects,vector<string>costs){
for(int i=0;i<connects.size();i++){
for(int j=0;j<connects[i].size();j++){
adj[i].push_back(int(connects[i][j]));
cost[i].push_back(int(costs[i][j]));
}
}
int n=connects.size();
for(int i=0;i<=n;i++)
visited[i]=false;
topological_sorting(0,n);
int lm=0;
for(int i=0;i<=n;i++){
Longest_Path(i,n);
if(glm>lm)
lm=glm;
glm=0
}
return lm;
}
};
You are confusing built-in array syntax and syntax of the std::vector<T> class. Precisely, with
std::vector<int> myVec[51]
you declare and array of 51 vectors of type int. Thus, the code
visited[cur_ver]=true;
means "take element 52 of the array myVec, and assign true to it". However, that element is not of type bool, but of type std::vector<int>. There is no operator that would allow to assign bool values to a vector object.
To specify the size of a vector, which is your intention, use the appropriate constructor or the resize() method. When you're sure that the size of your container is fixed and known at compilation time, you may use std::array<size_t, T>, which is a fixed-length array container, available in C++11. But this is not the case with your code - you insert elements later on.
Thus, to fix the error, fix the syntax for vector declarations, and then resize in your class' constructor:
vector<int> adj;
// other vectors follow ...
// in Circuit::Circuit:
Circuit:Circuit() {
adj.resize(51); // others follow ...
}
Be sure to replace the 51 with a properly named constant. "Magic" constants are evil!
Vectors are like dynamic arrays with an ability to resize. We've only two ways of the declaration of the vector in c++.
vector <int> myVector;
vector <int> myVector2(4,1000);
The second will initialize a vector of size 4 with initial value 1000. If you want to provide a size maybe you can use like this.
vector <int> myVector(12);
So I've read other Stack posts about this, and they all suggest that I use find. I'm attempting this, but it doesn't work for me.
bool findInArray(int number, int array[]){
// Finds if the number is in the array
bool exists = find(begin(array), end(array), number) != end(array);
return exists;
}
But I keep getting the following error:
error: no matching function for call to ‘begin(int*&)’
It's even the accepted answer here: How can I check if given int exists in array?
You need a template:
template <std::size_t N>
bool findInArray(int number, const int (&array)[N]) {
// Finds if the number is in the array
return std::find(std::begin(array), std::end(array), number) != std::end(array);
}
You also need to pass the array by lvalue, since you cannot pass arrays by prvalue in C++, and instead the array would decay to a pointer to its first element, thereby losing the size information.
In case you do not know template and looking for an other answer to this question, use STL algorithms.
#include<iostream>
#include<algorithm>
bool findInArray(int number, int array[], int size_array){
int* p = std::find(array, array+size_array, number);
if (p != array+size_array) {
return 1;
} else {
return 0;
}
And from main, you can call :
findInArray(5, a, sizeof(a)/sizeof(a[0]));
I am trying to solve a dynamic programming problem and I need to take the user input in the form of a 2-d array and use the values from the 2-d array inside the function.
The values of the 2-d array will not be changed when used inside the function.
In the function int dp i am getting the
error:
declaration of 'a' as multidimensional array must have bounds for all dimensions except the first
int max(int a,int b,int c)
{
if(a>=b && a>=c)return a;
if(b>=c && b>=a)return b;
else return c;
}
int max2(int a,int b)
{
if(a>b)return a;
else return b;
}
int dp(int i,int j,int a[][],int p,int q)
{
if((i-1)>=0 && (j-1)>=0 &&(i+1)<p &&(j+1)<q )
return max(a[i][j]+dp(i-1,j+1,a,p,q),a[i][j]+dp(i+1,j+1,p,q),
a[i][j]+dp(i,j+1,p,q));
if(i==0 && j!=0 && (j+1)<q)
return max2(a[i][j]+dp(i+1,j+1,p,q),a[i][j]+dp(i,j+1,p,q));
}
int main()
{
int p,q,r,s,T,a,b,i,j,k;
scanf("%d",&T);
for(a=0;a<T;a++)
{
scanf("%d %d",p,q);
int z[p][q];
int max=0;
for(i=0;i<q;i++)
{
for(j=0;j<p-1;j++)
scanf("%d ",&z[j][i]);
scanf("%d",&z[j+1][i]);
}
for(i=0;i<p;i++)
{
if(dp(i,0,z,p,q)>max)
max=dp(i,0,z,p,q);
}
}
}
It's all in the error message:
declaration of 'a' as multidimensional array must have bounds for all dimensions except the first
Your function signature does not have bounds for a's 2nd dimension:
int dp(int i,int j,int a[][],int p,int q)
// ^^^^^
You need to fill it in with a[][N] where N is whatever the correct bound is. The issue is that you are using VLAs here:
scanf("%d %d",p,q);
int z[p][q];
That is non-standard C++, and basically means you cannot write the signature of dp, since the second bound has to be known as a compile-time constant. You could either make it a single-dimensional array:
int* z = new int[p*q];
int dp(int i, int j, int* a, int p, int q)
// ^^^^^^
or dynamically allocate it in 2 dimensions and just pass it in that way:
int** z = new int*[p];
for (int i = 0; i < p; ++i) {
z[i] = new int[q];
}
int dp(int i, int j, int** a, int p, int q)
// ^^^^^^^
The function dp needs some information to perform meaningful index calculations, either done by the compiler or in the actual inplementation. Either a dimension must be specified in the type or the argument a could be of type int** while its dimensions are provided as separate arguments to dp. As this is C++, a type of std::vector< std::vector< int > > might be more suitable for the task.
You get that error because you cannot leave both the index(row,column) empty in int a[][] in your function declaration. You must have both specified or atleast the value of column index.
Use dynamic declaration
int **z = new int*[p];
for (int i = 0; i < p; i++)
z[i] = new int[q];
Change the parameter int a[][] to int **a
You can't dynamically declare an array on the stack as the size has to be known at compile time. The only way to do this would be by allocating memory for the array on the heap using the new keyword, then you could declare the size at run time.
Far easier, however, would be just to use a container class, or in your case, a container of containers like a vector of vector of ints;
#include <vector>
vector< vector<int> > arrArray(rows, vector<int>(columns));
The syntax might look a bit strange, but breaking it down;
vector<int> - a vector of type int
vector< vector<int> > - a vector of vectors of type int
arrArray(rows, vector<int>(columns)); - here in the first parameter, we are saying; create rows number of vector<int>'s in our array, and the second parameter initalises the array to some value. If it were just a 2D array of int, we might initalise it to 0, or omit the second parameter and rely on the default value of int. But, because our multidimensional vector also contains vectors, we set each row of our main vector to store a vector of int's which holds columns amount of integers.
Now you can access the array like you would any other;
arrArray[2][0] = 5;
You also get all the added benefits that container classes contain, including iterators and a lot of useful class methods for manipulating and checking your array. Once you understand the syntax of creating container classes, you'll find them much easier to work with than arrays. You also don't have to worry about having to manage your own memory, and have the ability to do bounds checking before accessing vector elements.
Here is my problem:
I have a struct:
struct point
{
int x;
int y;
};
and then I have an array:
for (int i = 0;i < n;i++)
{
arr[i].x=rand() % n + 1;
}
I defined the quicksort function as follows:
void quicksort(int *a, int left, int right);
and I want to sort the point by X coordinate, so I call the quicksort:
quicksort(arr.x, 0, n-1);
And this is the error message:
error: request for member 'x' in 'arr', which is of non-class type 'point [(((unsigned int)(((int)n) + -0x000000001)) + 1)]'
Sorry if the question is too stupid or badly formulated, the truth is I'm a newbie and I'm really willing to learn as much as possible and I'd be very thankful for your help!
If you always want to sort by x, then you can hard-code it into the sort function, and just pass a pointer to the array to sort:
void quicksort(point * arr, int left, int right) {
// test points with
// if (arr[i].x < arr[j].x) {/* i sorts before j */}
}
quicksort(arr, 0, n-1);
To specify a class member to sort by, you need a pointer-to-member, not a pointer; something like:
void quicksort(point * arr, int point::*member, int left, int right){
// test points with
// if (arr[i].*member < arr[j].*member) {/* i sorts before j */}
}
quicksort(arr, &point::x, 0, n-1);
More generically, you could follow the example of std::sort and accept any comparison functor:
template <typename RandIter, typename Compare>
void quicksort(RandIter begin, RandIter end, Compare compare) {
// test points with
// if (compare(*it1, *it2)) {/* *it1 sorts before *it2 */}
}
quicksort(arr, arr+n,
[](point const &lhs, point const &rhs) {return lhs.x < rhs.x;});
And of course, unless you're learning how to implement a sorting algorithm, just use std::sort.
quicksort(arr,0,n-1);
then within quicksort, try to compare the arr[i].x
There are a few problems with your code.
1. quicksort accepts int* but you try to pass int value x
2. You try to pass int but you actually call an undefined variable arr.x
What you need to do is either call in the form of &arr[i].x, but to accomplish what you want, you probably want to pass the entire struct as a pointer.
You need to pass arr as the parameter, as that is the array to be sorted. arr.x is meaningless. You are not passing the string "arr.x" as a parameter which can somehow be interpreted as meaning sort on the x field - when the compiler sees this, it is looking for an x element of arr, which doesn't exist, as the error message suggests - only the elements of arr (e.g. arr[0]) have x elements (accessed as arr[0].x).
Assuming this is for academic purposes (why else would you declare your own sorting algorithm instead of using one of the ones already implemented with a custom comparator?), you can do this a few ways:
Array
std::array<point, 10> myArray; // declares an array of size 10 for points
template<size_t N>
void quicksort(std::array<point, N>& arr, ...)
{
// implement sort operating on arr
}
Vector
std::vector<point> myVector; // declares a dynamic array/vector of points
void quicksort(std::vector<point>& arr, ...)
{
// implement sort operating on arr
}
If for some god-awful reason, you want to keep it in C:
Legacy
const size_t SIZE = 10;
point arr[SIZE]; // declare an array of 10 points
void quicksort(point* p, const size_t n, ...)
{
// implement sort operating on elements in p passing in SIZE for n
}
I'd rather defined the function as:
void quicksort(void *a,int left,int right, size_t size, int (*fp)(void*,void*));
size is the size of one element of array and fp is a compare function which returns true if the two arguments are equal. Now you can pass the call the function as:
quicksort(arr,0,n-1,sizeof(arr)/sizeof(arr[0]), compare);
where function compare is something like:
int compare(void* a, void* b) { return *((int*)a) >= *((int*)b); }
Rest of the implementation of function is trivial I think.
(almost) never try to fool the system by passing a pointer to a member when you really want to pass a pointer to an object. Do as Grijesh suggested. Passing a member can lead to horrible side effects. For example, quicksort is going to sort all the integers together, regardless of which of them are X's and which are Y's. In milder cases you may get wrong compare criteria, and often hard to debug effects such as incorrect pointer optimization. Just be honest with the compiler and pass the object pointer if you need to pass an object pointer. There are very very very few exceptions, mostly to do with low-level system programming where the "other side' of the function call won't be able to handle the object.
This question already has answers here:
How to find out if an item is present in a std::vector?
(18 answers)
Closed 12 months ago.
I have a vector that I am trying to perform a contains function on. I am receiving some sort of casting error and I can't piece together a solution. I am also wanting to know whether or not what I am doing is the appropriate way to check if a vector contains a value.
Here is the code:
#include "stdafx.h"
#include <vector>
static void someFunc(double** Y, int length);
static bool contains(double value, std::vector<double> vec);
int main()
{
double doubleArray[] = { 1, 2, 3, 4, 5 };
double *pDoubleArray = doubleArray;
int size = sizeof doubleArray / sizeof doubleArray[0];
someFunc(&pDoubleArray, size);
return 0;
}
static void someFunc(double** Y, int length)
{
std::vector<double> vec();
for(int i = 0; i < 10; i++)
{
//error: 'contains' : cannot convert parameter 2 from 'std::vector<_Ty> (__cdecl *)(void)' to 'std::vector<_Ty>'
if(contains(*(Y[i]), vec))
{
//do something
}
}
}
static bool contains(double value, std::vector<double> vec)
{
for(int i = 0; i < vec.size(); i++)
{
if(vec[i] == value)
{
return true;
}
}
return false;
}
When you declare a variable with it's default constructor, you don't put () after it (although it's optional when you use new to allocate space on the free store). So this line:
std::vector<double> vec();
should become
std::vector<double> vec;
If you leave it as you did, it thinks that line is a function prototype of a function called vec taking no parameters and returning a std::vector<double>, which is why you're getting a compiler error.
And yes, your code for finding an item will work (it's called a linear search). Also if you want to, you can use std::find:
if (std::find(vec.begin(), vec.end(), value) != vec.end())
// found value in vec
If your vector is in sorted order, you can also use binary_search which is much faster than find, and the usage is the same except binary_search returns a bool instead of an iterator (so you don't need to test it against vec.end()). Make sure you include the algorithm header if you use either of these.
std::vector<double> vec();
Oddly, this does not declare a vector using the default constructor. This declares a function taking no arguments and returning a vector. Try this instead:
std::vector<double> vec;
You can use std::find to check an STL datastructure to contain a certain value.