Using an STL map, wrong number of template arguments? - c++

I'm having a little trouble utilizing a map, and I have never really used them before so I am really struggling here
My Code is as follows:
MSTapp.h
5 #ifndef MSTAPP_H
6 #define MSTAPP_H
7
8 #include"Graph.h"
9
10 #include<iostream>
11 #include<map>
12 #include<vector>
13 #include<string>
14
15 using namespace std;
16
17 class MSTapp
18 {
19 public:
20 void read_graph();
21 void print_v();
22 // void print_e();
23
24 private:
25 Graph my_graph;
26 };
27
28 #endif
29
MSTapp.cpp
5 #include"MSTapp.h"
6 #include"Graph.h"
7
8 #include<iostream>
9 #include<map>
10 #include<vector>
11 #include<stdlib.h>
12 #include<sstream>
13 #include<string>
14
15 using namespace std;
16
17 void MSTapp::read_graph()
18 {
19 string s;
20 int count = 0;
21
22 while(getline(cin, s))
23 {
24 if(count == 0)
25 {
26 istringstream my_words(s);
27 string word;
28 while(my_words >> word)
29 {
30 my_graph.add_vertex(word);
31 }
32 }
33 else
34 {
35 string first;
36 string last;
37 int key;
38
39 first = s.substr(0, s.find(" "));
40 s.erase(0,s.find(" ")+1);
41 last = s.substr(0, s.find(" "));
42 s.erase(0,s.find(" ")+1);
43 key = atoi(s.c_str());
44
45 my_graph.add_edge(first, last, key);
46 }
47 }
48 }
49
50 void MSTapp::print_v()
51 {
52 my_graph.print_vertices();
53 }
Graph.h
5 #include"MSTapp.h"
6 #include<map>
7 #include<iostream>
8 #include<string>
9 #include<vector>
10 #include<list>
11
12 using namespace std;
13
14 #ifndef GRAPH_H
15 #define GRAPH_H
16
17 class Graph
18 {
19 public:
20 // Graph();
21 // ~Graph();
22 void add_vertex(string name);
23 void print_vertices();
24 void add_edge(string from, string to, int weight);
25 // void print_edges();
26 // void min_span_tree(string start);
27
28 private:
29 // MinPriority min_queue;
30
31 class Vertex
32 {
33 public:
34 string name;
35 string pi;
36 int key;
37 };
38 class Neighbor
39 {
40 public:
41 string name;
42 int weight;
43 };
44
45 vector<Vertex> vertices;
46 map <string name, list<Neighbor> > adj_list;
4
48 };
49
50 #endif
Graph.cpp
5 #include"MSTapp.h"
6 #include"Graph.h"
7
8 #include<iostream>
9 #include<map>
10 #include<algorithm> // sort
11 #include<string>
12 #include<vector>
13 #include<list>
14
15 using namespace std;
35 void Graph::add_vertex(string name)
36 {
37 Vertex v1;
38 v1.name = name;
39 v1.pi = "NIL";
40 v1.key = 100;
41 bool check;
42
43 for(int i = 0; i < vertices.size(); i++)
44 {
45 if(vertices[i].name == v1.name)
46 {
47 check = true;
48 }
49 }
50
51 if(check == false)
52 {
53 vertices.push_back(v1);
54 }
55 }
56
57 void Graph::print_vertices()
58 {
59 for(int i = 0; i < vertices.size(); i++)
60 {
61 cout << vertices[i].name << " " << vertices[i].pi << " " << vertices[i].key << endl;
62 }
63 }
64
65 void Graph::add_edge(string from, string to, int weight)
66 {
67 string v_from = from;
68 string v_to = to;
69 int v_weight = weight;
70
71 Neighbor n1;
72 n1.name = v_to;
73 n1.weight = v_weight;
74
75 adj_list[v_from];
76 adj_list[v_from].push_back(n1);
77 adj_list[v_from].sort();
78 }
All the functions for the Vertices are working so just ignore those. The main problem I am having is the add_edge function in the Graph. For example my input would be something as follows:
A B C D E //Vertices, this is working
A B 3
so, with the A B 3, I would like to add the B and 3 the the neighbor, and do something like
adj_list[A].push_back(Neighbor)
The errors I am getting are regarding the map, it is saying I have the incorrect number of template arguments for the map in Graph.h.
Am I declaring my map incorrectly on line 46 of Graph.h?
If anyone could provide any insight as to what I am doing wrong or how I can get this working it would be GREATLY appreciated. If any additional clarifcation is needed, just ask. Thanks!

you should declare the map as:
map <string, list<Neighbor> > adj_list;

Related

reading for value in file giving wrong results - c++

posting again due to change in formatting and code
I'm trying to parse a csv file and search it to find values that match my randomly generated array.
I've tried a few methods but im getting lost, I need to access the entire file, search for these values and output the index column that it belongs to.
my code for my random array generator as well as my search csv function:
reproducible example:
#include <fstream>
#include <iostream>
#include <string>
#include <random>
using namespace std;
//fills array of size 6 with random numbers between 1-50
void random_array(int arr[])
{
for (int i = 0; i < 6; i++) {
int num = rand() % 51;
arr[i] = num;
}
}
int main()
{
string line;
fstream file;
int size = 6;
int numbers[size];
int found;
//gets random array from random_array func
srand(time(NULL));
random_array(numbers);
//opens file to search
file.open("CSV directory here");
if (file.is_open()) {
//print random array values
for (int i = 0; i < size; i++) {
cout << numbers[i] << " ";
}
cout << endl;
//get file contents and search if contents of array exist in file
while (getline(file, line)) {
for (int i = 0; i < size; i++) {
found = line.find(std::to_string(numbers[i]));
if (found != string::npos) {
//print found numbers
cout << found << " ";
}
}
}
}
return 0;
}
CSV sample format:
,Date,1,2,3,4,5,6,7
0,Wed 03 January 2001,5,6,16,17,19,22,40
1,Sat 06 January 2001,6,16,23,34,35,40,37
my output:
array generated:
35 35 38 37 16 31
numbers found (from entire csv not just sample above):
26 33 33 39 24 31 34 33 24 6 28 31 33 33 30 0 32 34 33 30 27 38 26 29
29 33 7 24 29 26 26 26 24 24 0 30 30 36 0 0 23 27 0 0 7 36 36 27 30 30
27 27 26 26 32 29 23 38 32 32 28 28 7 25 29 37 25 29 29 26 23 34 31 28
25 31 28 28 34 32 32 35 38 40 25 37 37 35 40 40 30 30 42 42 42 36 35
28 31 25 37 7 27 36 33 36 33 29 39 29 35 34 34 40 40 43 31
Obviously you can see these numbers aren't correct and are almost completely random. The numbers dont match what's within my array, am I doing something wrong with my file parsing?

cycle detection in an undirected graph using dfs and height array

My job is to complete the isCyclic() function in following program. I can handle this job with visited array and passing parent to dfs() function but I am trying another solution, So I use a height array to keep track of distance of nodes in DFS tree for determining parents and cycle. this height array initial by zero. If distance of two node be exactly one these two node are parent child.
But I cannot understand why my solution doesn't work. can someone tell me why output of this code is not correct?
thanks for your help.
An example of graph and height value of nodes:
/*
.1
/ \
.2 .2
/ \
.3 .3
*/
#include<bits/stdc++.h>
using namespace std;
class Graph
{
int V;
list<int> *adj;
public :
Graph(int V);
void addEdge(int v,int w);
bool isCyclic();
};
vector<int> g[100001];
Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int v,int w)
{
adj[v].push_back(w);
adj[w].push_back(v);
}
int main()
{
int T;
cin>>T;
while(T--)
{
int _size,N;
cin>>_size>>N;
Graph *g = new Graph(_size);
for(int i=0;i<N;i++)
{
int u,v;
cin>>u>>v;
g->addEdge(u,v);
}
cout<<g->isCyclic()<<endl;
}
}
/*Please note that it's Function problem i.e.
you need to write your solution in the form of Function(s) only.
Driver Code to call/invoke your function is mentioned above.*/
/*The structure of the class is as follows
which contains an integer V denoting the no
of vertices and a list of adjacency vertices.
class Graph
{
int V;
list<int> *adj;
public :
Graph(int V);
void addEdge(int v,int w);
bool isCyclic();
};*/
/*You are required to complete this method*/
bool dfs(int v, int hi, list<int> *adj, int *h) {
h[v] = hi;
list<int>::iterator it;
for(it = adj[v].begin(); it != adj[v].end(); it++) {
int u = *it;
//cycle detect
if (h[u]>0 && hi - h[u] > 1)
return true;
if (h[u]==0 && dfs(u, hi+1, adj, h))
return true;
}
return false;
}
/*You are required to complete this method*/
bool Graph :: isCyclic()
{
//Your code here
int h[V];
for(int i = 0; i < V; i++) h[i] = 0;
for(int i = 0; i< V; i++)
if ( h[i] == 0 && dfs(i, 1, adj, h) ) return true;
return false;
}
A input that make my answer incorrect:
Input:
85 59
0 34 32 54 6 16 45 44 82 52 57 15 20 60 52 44 75 77 48 18 53 75 14 40 39 46 24 26 32 0 39 74 34 29 43 41 45 45 0 42 54 14 58 75 31 67 34 63 16 39 81 69 29 52 67 26 14 6 52 3 48 49 77 83 78 78 81 38 38 38 38 8 53 53 40 84 77 31 63 9 70 16 78 57 69 60 83 83 23 7 43 72 56 35 27 6 70 23 2 24 61 40 74 71 50 29 28 42 60 48 51 2 64 2 59 48 19 57
Its Correct output is:
1
And Your Code's output is:
0

C++ merge sort passed by value

I am trying to recursively implement the merge sort algorithm by only passing in a vector value to the function (no left or right index). The while loop in the following code works when the list to be sorted is passed as a pointer void merge_sort_array(int* v, int l, int r) or reference void merge_sort_ref(vector<int>& v, int l, int r) but I cannot for the life of me understand why the following code will not properly sort my list. I have a feeling it is something to do with either the starting values of i, j, k or the bounds within my while loop but I've tried anything that makes sense to me and can't figure it out.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> merge_sort_value(vector<int> v) {
int n = v.size();
if(n == 1){
return v;
}
else{
int m = n/2;
vector<int> v1(v.begin(), v.begin()+m);
vector<int> v2(v.begin()+m, v.begin()+n);
merge_sort_value(v1);
merge_sort_value(v2);
vector<int> tmp(v.begin(), v.begin()+m);
int i = 0;
int j = m;
int k = 0;
while((i < m) or (j < n)){
if(i == m){
v[k] = v[j];
j +=1;
}
else if((j == n) or (tmp[i] < v[j])){
v[k] = tmp[i];
i+=1;
}
else{
v[k] = v[j];
j+=1;
}
k+=1;
# print output for debugging
for(auto x = v.begin(); x != v.end(); ++x)
cout << *x << " ";
cout << "" << endl;
cout << i << "\t"<< j << "\t" << k << endl;
}
return v;
}
}
int main(int argc, char** argv) {
vector<int> v(10);
for(int i=0; i < 10; ++i)
v[i] = rand() % 100;
v = merge_sort_value(v);
return 0;
}
I have included a sample output for reference below:
28 28
0 2 1
28 80
1 2 2
21 21
0 2 1
21 92
1 2 2
14 92 21
1 1 1
14 92 21
1 2 2
14 92 21
1 3 3
14 28 14 92 21
0 3 1
14 80 14 92 21
1 3 2
14 80 28 92 21
2 3 3
14 80 28 92 21
2 4 4
14 80 28 92 21
2 5 5
21 57
1 1 1
21 57
1 2 2
78 83
1 1 1
78 83
1 2 2
78 78 83
0 2 1
78 83 83
0 3 2
78 83 96
1 3 3
21 57 96 78 83
1 2 1
21 57 96 78 83
2 2 2
21 57 96 78 83
2 3 3
21 57 96 78 83
2 4 4
21 57 96 78 83
2 5 5
21 28 14 92 21 21 57 96 78 83
0 6 1
21 57 14 92 21 21 57 96 78 83
0 7 2
21 57 80 92 21 21 57 96 78 83
1 7 3
21 57 80 28 21 21 57 96 78 83
2 7 4
21 57 80 28 14 21 57 96 78 83
3 7 5
21 57 80 28 14 92 57 96 78 83
4 7 6
21 57 80 28 14 92 21 96 78 83
5 7 7
21 57 80 28 14 92 21 96 78 83
5 8 8
21 57 80 28 14 92 21 96 78 83
5 9 9
21 57 80 28 14 92 21 96 78 83
5 10 10
Thank you, any help is greatly appreciated!
after reviewing you code it seems you're making mistakes in the algorithm it self and in C++ as language so i've edited your algorithm to be more neat and more readable algorithm i will explain some part of the code
Code
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> merge_sort_value(vector<int> v) {
int n = v.size();
if(n == 1){
return v;
}
else{
int m = n/2;
vector<int> v1(v.begin(), v.begin()+m);
vector<int> v2(v.begin()+m, v.begin()+n);
v1 = merge_sort_value(v1); /* passing by value will left v1 with no sorting so you need to copy from the returned
object */
v2 = merge_sort_value(v2);
int i = 0;
int j = 0;
int k = 0;
const size_t left_vecS = v1.size();
const size_t right_vecS = v2.size();
while (i<left_vecS&&j<right_vecS) { // we must keep i (AND) j valid
if (v1[i] < v2[j])
v[k++] = v1[i++];
else
v[k++] = v2[j++];
}
while(i<left_vecS) // if we sorted v2 then what insert the rest of v1 in v as what kept from v1 will be sorted
v[k++] = v1[i++];
while(j<right_vecS)
v[k++] = v2[j++];
}
return v;
}
int main(int argc, char** argv) {
vector<int> v(10);
std::vector<int> x;
for(int i=0; i < 10; ++i)
v[i] = rand() % 100;
v = merge_sort_value(v);
for(auto&i:v)
std::cout << i << std::endl;
return 0;
}
1- I get rid of the printing inside the sorting function so we keep the code clean
2-
the first error you've did at the language level is you didn't copy the returned sorted vector object from merge_sort_value to the vectors.(i've mentioned that in the code in a comment) so that's the first thing to keep in mind
3- the logic part of the algorithm wasn't clear to me because i didn't see how you're sorting specially that part else if ((j == n) or (tmp[i] < v[j])) {
v[k] = tmp[i];
i += 1;
}
like you're comparing unsorted sub vector to another unsorted vector and you're giving it unsorted value again (you must compare v1 against v2)
the whole logic is missed up i think you need to review it
anyway i hope that helped

c++ Bus Error (core dumped)

I successfully compiled following codes, but when I tried to run the codes, a "Bus error (core dumped)" occurred every time I finished my first input of "cin >> instruct >> name >> Bal". I searched online about the bus error, but I still couldn't find my error. Please help me with this, thanks a lot !!
// Bank.h
1 #ifndef BANK_H
2 #define BANK_H
3 using namespace std;
4
5 class BankAccount{
6 private:
7 string _name;
8 double _balance;
9
10 public:
11 BankAccount(string, double);
12 string getName();
13 void setName(string);
14 double getBalance();
15 void setBalance(double);
16 void Withdraw(double);
17 void Deposite(double);
18 void interest(int, int);
19
20 };
21 #endif
//Bank.cpp
1 #include<iostream>
2 #include<string>
3 #include "Bank.h"
4 using namespace std;
5
6 BankAccount::BankAccount(string name, double balance):_name(name),
7 _balance(balance){}
8
9 string BankAccount::getName(){ return _name;}
10
11 double BankAccount::getBalance(){ return _balance;}
12
13 void BankAccount::setName(string name){
14 _name = name;
15 return;
16 }
17
18 void BankAccount::setBalance(double balance){
19 _balance = balance;
20 return;
21 }
22
23 void BankAccount::Withdraw(double balance)
24 {
25
26 _balance = _balance - balance;
27 return;
28 }
29
30 void BankAccount::Deposite(double balance)
31 {
32
33 _balance = _balance + balance;
34 return;
35 }
36
37 void BankAccount::interest(int interestRate, int M)
38 {
39 double interest;
40
41 interest = _balance*(interestRate/1200*1.0)*M;
42 _balance = _balance + interest;
43
44 return;
45 }
//BankMain.cpp
1 #include<iostream>
2 #include<string>
3 #include "Bank.h"
4 using namespace std;
5
6 int main()
7 {
8 int x, p, check=1, i=0, j;
9 double Bal;
10 BankAccount* Account[100];
11 string name;
12 string instruct;
13
14 cin >> x >> p;
15
16 while(check)
17 {
18 cin >> instruct >> name >> Bal;
19
20 if(instruct == "Create")
21 {
22 Account[i]->setName(name);
23 Account[i]->setBalance(Bal);
24 Account[i]->interest(x, p);
25 i++;
26 }
27 else
28 {
29 if(instruct == "Withdraw")
30 {
31 for(j=0; j<i;j++)
32 {
33 if(Account[j]->getName() == name)
34 break;
35 }
36 Account[j]->Withdraw(Bal);
37
38 }
39
40 if(instruct == "Deposite")
41 {
42 for(j=0; j<i; j++)
43 {
44 if(Account[j]->getName() == name)
45 break;
46 }
47 Account[j]->Deposite(Bal);
48 }
49 }
50
51 if(instruct == "0")
52 check = 0;
53 }
54
55 cout << i;
56 for(j=0; j<i; j++)
57 {
58 cout << Account[j]->getName() << " " << Account[j]->getBalance();
59 cout << endl;
60 }
61
62 return 0;
63 }
You have many pitfalls in your code.
The first one is that you defined an array of pointers BankAccount* Account[100]; and you access it as they are initialized... Why? This array contains junk and if you need to create a new account use new BankAccount(name, balance) first and assign it to the appropriate index in this array.
Then all your internal loops which scan for a specific name assume that this name is found and access Account[j]->... but what if j==i and this name was not found?
These are the main ones that I saw.
Of course there are more but they should not cause "core dump".
Like passing string by value or dividing integer by 1200 (if that integer is smaller than 1200 you will get 0).

Printing an array of STL list

I'm having some trouble printing an array of lists (ex. list<string> hashTable[100] )
Heres what I have so far, my question is at the bottom:
hash2.h
1 #ifndef __HASH2_H
2 #define __HASH2_H
3
4 #include<string>
5 #include<list>
6 #include<fstream>
7
8 using namespace std;
9
10 class Hash
11 {
12 public:
13 void processFile(string fileName);
14 void print();
15
16 private:
17 list<string> hashTable[100];
18
19 private:
20 int hf(string ins);
21
22
23 };
24
25 #endif
hash_function2.cpp
1 #include<iostream>
2 #include<string>
3 #include<fstream>
4 #include "hash2.h"
5
6 using namespace std;
7
8 void Hash::processFile(string fileName)
9 {
10 string word;
11 ifstream myIfile(fileName.c_str());
12 while(getline(myIfile, word))
13 {
14 int index = hf(word);
15 hashTable[index].push_back(word);
16 }
17 myIfile.close();
18 }
19
20 void Hash::print()
21 {
22 for(int i = 0; i < 100; i++)
23 {
24 if(hashTable[i] != NULL)
25 {
26 list<int>::iterator i;
27 for(i = hashTable[i].begin(); i != hashTable[i].end(); ++i)
28 {
29 cout << *i << endl;
30 }
31 }
32 }
33 }
34
35 int Hash::hf(string ins)
36 {
37 return ( (int) ins[0] ) % 100;
38 }
main2.cpp
1 #include "hash2.h"
2 #include<iostream>
3 #include<iomanip>
4 #include<fstream>
5
6 using namespace std;
7
8 int main()
9 {
10 Hash hashTable;
11 hashTable.processFile("test1.txt");
12 hashTable.print();
13 }
So, what I have now is the processFile function, which takes the text file, reads each word in, performs the hash function(crappy, i know), then puts that word in the array index which the hash function returned. That is working fine I think.
What im having issues with is essentially using the STL list. So, in hash_function2.cpp, i want to print my hash table. I'm not sure how to check if the array index is empty(doesn't have any of the words I stored), and I am also not sure how to print all the strings in the list at a given array index. Basically what I would like to do is just print my hash table; get my print() function working.
If anyone could point me in the right direction that would be awesome! It would be greatly appreciated.
You shouldn't be checking for NULL because you have an array of std::list objects, not pointers.
You can check if the list at index i has any elements with:
if (!hashTable[i].empty())
{
// there are elements in the list
}
Or
if (hashTable[i].size())
{
// there are elements in the list
}
Also in your print() function, you're using an iterator of type std::list<int>, but it should be std::list<string>, which matches the declaration of hashTable.
Your problem is not with std list, it is with the array.
You could try using the std::array
#include <array>
std::array< std::list<string>, 100> hashTable;
this way you can check if it is emtpy
if (!hashTable.empty())
{
// do stuff
}
and inside you can check each list
if(!hashTable[i].empty())
{
// do even more stuff
}
Awesome, Thanks a lot guys! I understand how to check each array index and iterate through the list! Heres what I did:
1 #include "hash2.h"
2
3 #include<iostream>
4 #include<string>
5 #include<fstream>
6
7 using namespace std;
8
9 void Hash::processFile(string fileName)
10 {
11 string word;
12 ifstream myIfile(fileName.c_str());
13 while(getline(myIfile, word))
14 {
15 int index = hf(word);
16 hashTable[index].push_back(word);
17 }
18 myIfile.close();
19 }
20
21 void Hash::print()
22 {
23 for(int i = 0; i < 100; i++)
24 {
25 if(hashTable[i].empty() != true)
26 {
27 list<string>::iterator r;
28 for(r = hashTable[i].begin(); r != hashTable[i].end(); ++r)
29 {
30 cout << *r << endl;
31 }
32 }
33 }
34 }
35
36 int Hash::hf(string ins)
37 {
38 return ( (int) ins[0] ) % 100;
39 }