Local Variable / Class variable increment - c++

So essentially what my program does is read in a data stream of words, and count the occurrence of each word, and the total number of unique words. It will will read them into a map. My program works perfectly except for one problem...when I call p.print(), the value for total is still at 0. There seems to be some problem where total is incremented in the for_each statement, but when I p.print, it acts as if was never incremented...My print function is defined as follows:
void print_words(const map<string,int> &aMap) {
PRN p(aMap.size());
for_each(aMap.begin(), aMap.end(), p);
p.print();
}
I have a class that is in charge of processing each word, here is the definition:
//CLASS PRN FUNCTIONS
// constructor
PRN::PRN(const int& s, const int& c, const int& t) {
sz=s;
cnt=c;
total=t;
}
// overloaded operator, where P is defined as
// typedef pair < string, int > P;
void PRN::operator()(const P& p) {
if(cnt%NO_ITEMS == 0 && cnt != 0)
cout << '\n';
cout << setw(ITEM_W) << left << p.first << " : " << setw(NO_W) << left << p.second;
total += p.second;
cnt++;
}
// to printout final value of total
void PRN::print() const {
cout << '\n' << '\n';
cout << "no of words in input stream : " << total << endl;
cout << "no of words in output stream : " << sz << endl;
}

Figured it out...I need to have
p = for_each(aMap.begin(), aMap.end(), p);
No better feeling then figuring out your own problem!

Related

Recursive function showing segmentation issue C++

This code is for recursive function practice. When I run the code, it stops at the "POWER" cout line, then my compiler shows a segmentation error. The function that follows the POWER line is supposed to recursively raise number "a" to the power of number "b". I'm not sure how to fix this, can anyone help?
#include <iostream>
#include <string>
#include <vector>
using namespace std;
/**** Recursive backwards print, prints a string starting from last index to first*****/
void printReverse(string s, int i)
{
if(i < s.size())
{
printReverse(s.substr(1), i);
cout<<s[i];
}
else
{
return;
}
}
/**** Recursive power function, computes a^b, where b can be positive or negative*****/
int recPower(double a, int b)
{
int i = b; //i = b, so int a can be multiplied int b times
if (i == 0) //base
return 1;
else //multiply A by B, B times
{
a *= b;
return recPower(a, b); //recursive
i--; //decrement i until it equals 0
}
}
/**** Recursive string replace, replaces all instances of a character in a string with another character*****/
string recReplace(string s2, int i, char old, char neW)
{
if(s2[i] == old) //search for old char
{
i = neW; //replace it
i++; //iterate i
}
recReplace(s2, i, old, neW); //call function
return s2;
}
/**** Recursive list find > Searches if x exists in list, returns true if found, false otherwise*****/
int recListFind(vector<int> v, int i, int x)
{
if(v[i] == x)
{
cout << x << " exists in the vector."<<endl;
i++;
recListFind(v, i, x);
}
return true;
}
int main()
{
cout << "PRINT REVERSE" << endl;
cout << "----------" << endl;
string s1 = "hello world";
cout << "String: " << s1 << endl;
cout << "Reversed: ";
printReverse(s1, 0);
cout << endl;
/* Computes a^b (power function) */
cout << "POWER" << endl;
cout << "----------" << endl;
int a = 2, b = -3;
cout << a << "^" << b << " = ";
cout << recPower(a, b) << endl;
cout << endl;
/* Replaces a character in a string with a new one */
cout << "REPLACE" << endl;
cout << "----------" << endl;
string s2 = "-h-e-l-l-o-";
char oldChar = '-';
char newChar = ' ';
cout << "String: " << s2 << endl;
cout << "> Replace '" << oldChar << "' with '" << newChar << endl;
recReplace(s2, 0, oldChar, newChar);
cout << "String: " << s2 << endl;
cout << endl;
/* Searches for value in vector */
cout << "FIND" << endl;
cout << "----------" << endl;
int x = 7;
cout << "Does " << x << " exist in the vector? "; vector<int> v = {5, 1, 6, 7, 9};
cout << recListFind(v, 0, 7) << endl;
cout << endl;
return 0;
}
The issue is quite straight forward, you are doing the recPower function with b. In the function, if b is not 0, you call recPower with an unmodified value of b (whilst ever modifying a). This will always end up with infinite recursion which is going to overflow your stack.
A solution could be:
int recPower(double a, int b, int times) {
if (times == 0)
return a;
else
return b * recPower(a, b, --times);
}
int recPower(double a, int b) {
return recPower(a, b, b);
}
Even if you fix this, you have another problem. b can be negative, which based on your logic will continue to recurse while decrementing until it overflows and goes back to 0. You will cause this case with your first test case. You should think about the types that are allowed in this function, consider making them unsigned, or dealing explicitly with the negative b case.

set::find() not working with user define data type

When I am searching for a key which is not present in my set then find() instead of returning iterator to end is returning an iterator to an another object which is not equal to key but present in set.
I have no idea whats going wrong.
CODE
class node{
public:
int a, b;
node(int a, int b):a(a), b(b){}
bool operator>(const node &ob)const{
return (this->b - this->a) > (ob.b - ob.a);
}
bool operator==(const node &ob)const{
return ((this->a == ob.a) && (this->b == ob.b));
}
};
void print(set<node,greater<node>> &s){
cout << "[ ";
for(const node &ob: s){
cout << "(" << ob.a << "," << ob.b << ") ";
}
cout <<"]\n--------------------------------" << endl;
}
set<node,greater<node>> s;
int main(){
s.insert(node(0,3));
s.insert(node(3,8));
print(s);
s.erase(node(3,8));
cout << "After erasing (3, 8)" << endl;
print(s);
cout << "Searching for key (3,6)" << endl;
set<node,greater<node>>::iterator i = s.find(node(3,6));
if(i == s.end()){
cout << "Not Found" << endl;
}else{
cout << "Found : " << "(" << i->a << "," << i->b << ")" << endl;
}
return 0;
}
OUTPUT
[ (3,8) (0,3) ]
--------------------------------
After erasing (3, 8)
[ (0,3) ]
--------------------------------
Searching for key (3,6)
Found : (0,3)
When comparing objects as equal or not std::set uses the comparison function (i.e. greater<node> which uses node::operator>) but not node::operator== (as you expected).
In imprecise terms, two objects a and b are considered equivalent if neither compares less than the other: !comp(a, b) && !comp(b, a).
For node(3,6) and node(0,3), both operator> (node(3,6), node(0,3)) and operator> (node(0,3), node(3,6)) return false, then they're considered equivalent.

print multiple numbers in ascending order in C++

So I'm working on this project where I have to gather 2 integers from a user 3 times (loop), and each time I have to print the two integers in ascending order. The restriction is that you can only have two cout statements within your loop (one is asking for their input and the second is outputting the ascending order).
My only issue with that is, when I think about ascending order, I would do it like (which has two count statements):
if (m<n) {
cout << m << n << endl;
if (m>n){
cout << n << m << endl;
So far, this is what I have:
#include <iostream>
using namespace std;
int main(int,char**) {
int n, m, z;
for (n=0;n<3;n++){
cout << "Give me two numbers: ";
cin >> m;
cin >> z;
//if (m>z);
//cout << m << z << "sorted is: " << m << z << endl;
// This is where I'm getting stuck because I need two count statements to organize in ascending order as shown above
}
}
So have you considered to change which variable holds the lower number? e.g.
if(m > n){
int temp = n;
n = m;
m = temp;
}
Then you can just use one print
cout << m << " " << n << endl;
This is where I'm getting stuck because I need two count[sic]
statements to organize in ascending order as shown above
You have marked this post as C++:
Additional options to consider:
use algorithm lib:
#include <algorithm>
std::cout << std::min(m,n) << " " << std::max(m,n) << std::endl;
or use conditional / ternary operator in your cout:
std::cout << ((m<n) ? m : n) << " " << ((n<m) ? m : n) << std::endl;
References are sometimes fun ... but perhaps this challenge is too trivial.
// guess m < n
int& first = m;
int& second = n;
if(!(m<n)) { first = n; second = m; }
std::cout << first << " " << second << std::endl;
Pointers can do the same:
// guess m < n
int& first = &m;
int& second = &n;
if(!(m<n)) { first = &n; second = &m; }
std::cout << *first << " " << *second << std::endl;
or you can use
lambda expressions, or
c++ functions, or
c++ class methods
But I think each of these would be directly comparable to either of the first alternatives.

Seemingly empty vector

I've added some slight multi threading to a simple c++ program and have encountered a few issues along the way.
The latest of these issues is that historical::assignthreads for some reason is receiving an empty vector from the function historical::writeData.
Looking at the code below you will see that writeData iterates through a vector and puts the data in a placeholder before sending it forward to assignthreads (after 5 iterations) - meaning that the vector being sent from writeData to assignthreads shouldn't be empty.
However in assignthreads you will see that there are two cout:s, one before and one after the loop. Both writes to cout without the loop even starting.
Does anyone have any idea of how this could be the case?
void historical::writeData(std::vector<std::vector<std::wstring>> in, const string& symbol) {
std::cout << "Sending data to database connector" << std::endl;
std::vector<std::vector<std::wstring>> temp;
std::vector<std::vector<std::wstring>>::iterator it;
int count = 0;
for (it = in.begin(); it != in.end(); it++) {
if (count = 5) {
cout << "I'm in count 5" << endl;
assignthreads(temp, symbol);
temp.clear();
count = 0;
}
else {
cout << "I'm in count 0" << endl;
temp.push_back(*it);
count++;
}
}
if (!temp.empty()) {
cout << "I'm in empty" << endl;
assignthreads(temp, symbol);
}
else cout << "I'm empty!!" << endl;
}
void historical::assignthreads(std::vector<std::vector<std::wstring>>& partVec, const string& symbol) {
int i = 0;
cout << "I'm in assign" << endl;
vector<thread> threads(size(partVec));
std::vector<std::vector<std::wstring>>::iterator it;
for (it = partVec.begin();
it != partVec.end();
it++) {
cout << "I'm in the loop" << endl;
std::shared_ptr<database_con> sh_ptr(new database_con);
threads.at(i) = std::thread(&database_con::start, sh_ptr, *it, symbol);
i++;
}
cout << "I've finished" << endl;
for (auto& th : threads) th.join();
}
void historical::writer(string* pInput) {
ofstream mf("test.csv");
if (mf.is_open()) {
mf << *pInput;
mf.close();
}
else cout << "Unable to open file" << endl;
}
Your fundamental problem here is that count = 5 is an assignment and is therefore always true. You intended to use count == 5.
It's worth noting that particularly as your vector becomes large copying it is very wasteful, and you're doing this 2 ways:
The vector is passed into writeData by value, change to copying by reference: void writeData(std::vector<std::vector<std::wstring>>& in, const string& symbol)
temp will eventually copy every element of in, use iterators instead so your code would have to change to:
#define SIZE 5
void assignthreads(std::vector<std::vector<std::wstring>>::iterator start, std::vector<std::vector<std::wstring>>::iterator finish, const string& symbol) {
cout << "I'm in assign" << endl;
vector<thread> threads(distance(start, finish));
for(auto i = 0; start != finish; ++i, ++start) {
cout << "I'm in the loop" << endl;
std::shared_ptr<database_con> sh_ptr(new database_con);
threads.at(i) = std::thread(&database_con::start, sh_ptr, *start, symbol);
}
cout << "I've finished" << endl;
for (auto& th : threads) th.join();
}
void writeData(std::vector<std::vector<std::wstring>>& in, const string& symbol) {
std::cout << "Sending data to database connector" << std::endl;
auto count = 0;
while(count < in.size() - SIZE) {
auto start = next(in.begin(), count);
count += SIZE;
auto finish = next(in.begin(), count);
assignthreads(start, finish, symbol);
}
assignthreads(next(in.begin(), count), in.end(), symbol);
cout << "I'm empty!!" << endl;
}

std::list looping forever, scope issue?

I have a Node class. It contains x,y coordinates, an id and a list of Node pointers which holds the adjacent nodes.
I am having problem with the list data structure inside the class. The printAdj() function works fine but I need to iterate through the adjacency list of a node from outside the class by acquiring adjList member using adjs() function.
class Node{
public:
// constructors & destructors
Node(double x, double y, unsigned id) : x_(x), y_(y),
id_(id) {}
// setters & getters
std::list<Node*> adjs() const { return adjList; }
// member functions
void addAdj(Node* n) { adjList.push_back(n); }
void printAdj() const{
for(std::list<Node*>::const_iterator it = adjList.begin();
it != adjList.end() ; ++it){
std::cout << "\t" << (*it)->id() << " " << std::endl;
}
}
private:
std::list<Node*> adjList;
double x_, y_;
unsigned id_;
};
The outside loop runs forever.
list<Node*> RRT_graph; //global
void print(){
for(list<Node*>::const_iterator it = RRT_graph.begin() ;
it != RRT_graph.end() ; ++it){
cout << "Node ID: " << (*it)->id() << "\tX: " << (*it)->x()
<< "\tY: " << (*it)->y() << endl;
cout << "\tAdjacency List:" << endl;
(*it)->printAdj(); // member function correctly prints adjacency list
// nothing wrong with the size, it displays correctly
cout << "-----------------------------------" << endl;
cout << "(" << (*it)->adjs().size() << ")" << endl;
// but when the list is looped, it goes forever.
unsigned count = 0;
for(list<Node*>::const_iterator ite = (*it)->adjs().begin() ;
ite != (*it)->adjs().end() ; ++ite)
cout << count++ << endl;
}
Since two adjacency list printing loops are identical and only member function works, I suspect a scope issue here but I'm sort of lost.
What's wrong here?
Just return const reference in adjs(), it should work. Currently it is returning a copy, hence when you take iterator in (*it)->adjs().begin() and in (*it)->adjs().end(), it gives iterators to different copies
const std::list<Node*>& adjs() const { return adjList; }