How to store a bi-directional graph using map in C++? - c++

I am trying to store a bi-directional graph as an adjacency list using std::map<int,vector<int>>. The idea here is to store n nodes, from 1 to n in this map.
The input is given as u v, which denotes an edge between node u and node v. We get n such inputs on n lines.
My code for storing the graph:
int u,v;
map<int,vector<int>> graph();
for(int i=0;i<n;i++) {
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}
This should work, but it gave me errors when complied with C++ 14. I then compiled this with C++ 17 and the errors still persists.
Errors(as displayed on my terminal):
/home/chirag/chiragC/forces/try.cpp: In function ‘void solve()’:
/home/chirag/chiragC/forces/try.cpp:68:10: warning: pointer to a function used in arithmetic [-Wpointer-arith]
graph[u].push_back(v);
^
/home/chirag/chiragC/forces/try.cpp:68:12: error: request for member ‘push_back’ in ‘*(graph + ((sizetype)u))’, which is of non-class type ‘std::map<int, std::vector<int> >()’
graph[u].push_back(v);
^~~~~~~~~
/home/chirag/chiragC/forces/try.cpp:69:10: warning: pointer to a function used in arithmetic [-Wpointer-arith]
graph[v].push_back(u);
^
/home/chirag/chiragC/forces/try.cpp:69:12: error: request for member ‘push_back’ in ‘*(graph + ((sizetype)v))’, which is of non-class type ‘std::map<int, std::vector<int> >()’
graph[v].push_back(u);
^~~~~~~~~
[Finished in 1.5s with exit code 1]
I feel the script I am using to store the graph is correct, as my friend was able to run this code completely fine on his system. I don't know why it is giving errors.
My System: debian 10
Headers used: #include<bits/stdc++.h>
Some info on my Compiler:
chirag#debian10:~/chiragC/forces$ ls /usr/bin | grep g++
arm-none-eabi-g++
avr-g++
g++
g++-8
x86_64-linux-gnu-g++
x86_64-linux-gnu-g++-8
chirag#debian10:~/chiragC/forces$ g++ --version
g++ (Debian 8.3.0-6) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
chirag#debian10:~/chiragC/forces$

Your bug is that you are trying to make a function named graph() remove the parenthesis then all will be fine.

Related

max_element with lambda: how to compile?

I am learning some new C++ features and couldn't get the following code compiled.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> numbers;
numbers.push_back(1);
numbers.push_back(5);
numbers.push_back(3);
numbers.push_back(9);
numbers.push_back(10);
numbers.push_back(8);
std::cout << std::max_element(numbers.begin(), numbers.end(), [](int a, int b) { return a < b;}) << std::endl;
return 0;
}
My gcc version:
$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The output when I try to compile:
$ g++ test_max_element.C
test_max_element.C: In function ‘int main()’:
test_max_element.C:15:99: warning: lambda expressions only available with -std=c++0x or -std=gnu++0x [enabled by default]
test_max_element.C:15:100: error: no matching function for call to ‘max_element(std::vector<int>::iterator, std::vector<int>::iterator, main()::<lambda(int, int)>)’
test_max_element.C:15:100: note: candidates are:
/usr/include/c++/4.6/bits/stl_algo.h:6229:5: note: template<class _FIter> _FIter std::max_element(_FIter, _FIter)
/usr/include/c++/4.6/bits/stl_algo.h:6257:5: note: template<class _FIter, class _Compare> _FIter std::max_element(_FIter, _FIter, _Compare)
How can I fix this compilation error?
I have 2 hints here.
Syntax Error
std::cout << *std::max_element(numbers.begin(), numbers.end(), [](int a, int b) { return a < b;}) << std::endl;
Note the * operator. You need it because max_element returns an iterator, so in order to print the value you have to deference it.
Obsolete Compiler Version
You're trying to using a modern C++ features with a too old compiler. I suggest you to upgrade it.
Anyway you can use the current compiler's version you have just add the flag -std=c++0x to the compiler command. But seeing from your question probabily the flag is enable by default.

error using auto: does not name a type, c++ version of numpy's arange

Looking for code to implement numpy's arange function in c++, I found this answer.
I placed the following code in a file test_arange_c.cpp:
#include <vector>
template<typename T>
std::vector<T> arange(T start, T stop, T step = 1)
{
std::vector<T> values;
for (T value = start; value < stop; value += step)
values.push_back(value);
return values;
}
int main()
{
double dt;
dt = 0.5;
auto t_array = arange<double>(0, 40, dt);
return 0;
}
When I try to compile it, I get the following error:
$ c++ test_arange_c.cpp -o test_arange_c.out
test_arange_c.cpp: In function ‘int main()’:
test_arange_c.cpp:14:8: error: ‘t_array’ does not name a type
auto t_array = arange<double>(0, 40, dt);
Without doubt, I've made a mistake that will be obvious to seasoned c++ users. But, after searching Google for a while, I haven't come up with what it is.
As #Brian suggested, I had not enabled C++11 support.
$ c++ --version
c++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This fails:
$ c++ test_arange_c.cpp -o test_arange_c.out
test_arange_c.cpp: In function ‘int main()’:
test_arange_c.cpp:16:8: error: ‘t_array’ does not name a type
auto t_array = arange<double>(0, 40, dt);
^
This works:
$ c++ -std=c++11 test_arange_c.cpp -o test_arange_c.out
$

Evaluating 2 variable function using bind(func,_1,_2) function

I am testing an example code to implement bind(func,_1,_2) function. the code is the following:
#include <functional>
#include <iostream>
using namespace std;
using namespace std::placeholders;
int multiply(int a, int b)
{
return a * b;
}
int main()
{
auto f = bind(multiply, 5, _1);
for (int i = 0; i < 10; i++)
{
cout << "5 * " << i << " = " << f(i) << endl;
}
return 0;
}
a very simple code which should just return the first 9 multiples of 5.
Now, I've update my gcc compiler (basically removed the old one and went through the ordinary installation process, going from 4.2.1 to 4.6 - don't know why it didn't download the latest directly...) but I'm not sure if the g++ command is using the latest. if I press
g++ --version
I get
g++ (GCC) 4.6.0
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
however, when I try to compile my code, this is what I get:
test.cpp:5:17: error: ‘placeholders’ is not a namespace-name
test.cpp:5:29: error: expected namespace-name before ‘;’ token
test.cpp: In function ‘int main()’:
test.cpp:14:10: error: ‘f’ does not name a type
test.cpp:17:44: error: ‘f’ was not declared in this scope
I don't get it. the namespace should be within the header, and the header should be within the version of gcc I have (4.6.0), and yet I still get compilation errors
help pleeeease, this thing is driving me crazy :(

error: ‘unique_ptr’ is not a member of ‘std’

I guess it's pretty self explanatory - I can't seem to use C++11 features, even though I think I have everything set up properly - which likely means that I don't.
Here's my code:
#include <cstdlib>
#include <iostream>
class Object {
private:
int value;
public:
Object(int val) {
value = val;
}
int get_val() {
return value;
}
void set_val(int val) {
value = val;
}
};
int main() {
Object *obj = new Object(3);
std::unique_ptr<Object> smart_obj(new Object(5));
std::cout << obj->get_val() << std::endl;
return 0;
}
Here's my version of g++:
ubuntu#ubuntu:~/Desktop$ g++ --version
g++ (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04) 4.7.3
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Here's how I'm compiling the code:
ubuntu#ubuntu:~/Desktop$ g++ main.cpp -o run --std=c++11
main.cpp: In function ‘int main()’:
main.cpp:25:2: error: ‘unique_ptr’ is not a member of ‘std’
main.cpp:25:24: error: expected primary-expression before ‘>’ token
main.cpp:25:49: error: ‘smart_obj’ was not declared in this scope
Note that I've tried both -std=c++11 and -std=c++0x to no avail.
I'm running Ubuntu 12.04 LTS from a flash drive on an Intel x64 machine.
You need to include header where unique_ptr and shared_ptr are defined
#include <memory>
As you already knew that you need to compile with c++11 flag
g++ main.cpp -o run -std=c++11
// ^
So here what I learned in 2020 - memory.h is at /usr/include AND in /usr/include/c++/4.8.5 and you need the second to be found before the first.
In Eclipse set the order using Project->Properties->Path and Symbols->Includes->Add... path if needed and set first
You need to include #include that will solve the problem, at least on my ubunto linux machine

ostringstream operator<< for long?

$ uname -a
Darwin Wheelie-Cyberman 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun 7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386
$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ cat nolove.cc
#include <iostream>
#include <sstream>
using namespace std;
int main(int argc, char ** argv) {
unsigned long long i = 0;
ostringstream o();
// Compiles fine
cout << i;
// Explodes, see below
o << i;
return 0;
}
$ g++ -o nolove nolove.cc
nolove.cc: In function ‘int main(int, char**)’:
nolove.cc:14: error: invalid operands of types ‘std::ostringstream ()()’ and ‘long long unsigned int’ to binary ‘operator<<’
I'm somewhat new to C++ (but not to programming or OO design, etc) so I'm assuming I'm just doing it wrong. In practice the unsigned long long above equates to an unsigned 64bit integer on my targeted platforms (above and g++ 4.4.1 on linux 2.6), a different type that amounted to the same thing would also be acceptable (but I haven't found any.)
Can I use an ostringstream to format this (or similar) type? If not, can I do it without dragging in stdio and snprintf? More philosophically, how does the typing work out that cout can do it, and why wasn't that functionality extended to the string stream stuff?
This is becuse this
ostringstream o();
doesn't declare a variable, but a function returning a stream.
Try this instead
ostringstream o;
See also
Most vexing parse: why doesn't A a(()); work?