Unordered multimap finding all values - c++

I would like to see whether it is possible to see all values that we have emplaced. For example:
#include <iostream>
#include <unordered_map>
using namespace std;
int main () {
unordered_multimap<string,int> hash;
hash.emplace("Hello", 12);
hash.emplace("World", 22);
hash.emplace("Wofh", 25);
for (int i = 1; i < 10; i++) {
hash.emplace("Wofh", i);
}
cout << "Hello " << hash.find("Hello")->second << endl;
cout << "Wofh " << hash.count("Wofh") << endl;
cout << "Wofh " << hash.find("Wofh")->second << endl;
return 0;
}
The output is :
$ ./stlhash
Hello 12
Wofh 10
Wofh 9
Whereas I want the last line to show from 25,1,2... to 9. Apparently find only takes first and second pointer as first is the value and second is the corresponding value. Is there any way to do this?

The operation you need is called equal_range
Example from the cplusplus.com:
// unordered_multimap::equal_range
#include <iostream>
#include <string>
#include <unordered_map>
#include <algorithm>
typedef std::unordered_multimap<std::string,std::string> stringmap;
int main ()
{
stringmap myumm = {
{"orange","FL"},
{"strawberry","LA"},
{"strawberry","OK"},
{"pumpkin","NH"}
};
std::cout << "Entries with strawberry:";
auto range = myumm.equal_range("strawberry");
for_each (
range.first,
range.second,
[](stringmap::value_type& x){std::cout << " " << x.second;}
);
return 0;
}

Related

Test an integer value to determine if it is odd or even in C++

I have to write a program to test an integer value to determine if it is odd or even, and make sure my output is clear and complete. In other words, I have to write the output like "the value 4 is an even integer". I was also hinted that I have to check the value using the remainder modulo.
The issue I have is with the scanf() function. I get a syntax error:
'%=' expected a ')'
How do I fix this?
#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
int main()
{
int number = 0;
cout << "enter an integer ";
int scanf(%=2 , &number);
if (number == 0)
cout << "the value" << number << "is even";
else
cout << "the value" << number << "is odd";
return 0;
}
You are using scanf() incorrectly (read the scanf() documentation on cppreference.com). The first parameter expects a null-terminated string containing the format to scan, but you are not passing in anything that even resembles a string. What you are passing in is not valid string syntax, per the C++ language standard. That is why you are getting a syntax error.
You need to change this line:
int scanf(%=2 , &number);
To this instead:
scanf("%d", &number);
Though, in C++ you really should be using std::cin instead for input (you are already using std::cout for output):
std::cin >> number;
Try this:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
int number = 0;
cout << "enter an integer ";
if (cin >> number)
{
if ((number % 2) == 0)
cout << "the value " << number << " is even";
else
cout << "the value " << number << " is odd";
}
else
cout << "the value is invalid";
return 0;
}
I know this question is a little dated, however, if you are able to use modern C++ features. You can write a constexpr helper function such as this:
#include <cstdint>
constexpr bool isEven(uint32_t value) {
return ((value%2) == 0);
}
Then in your main function, you can traverse through a loop of N integers and output your display such as:
#include <iostream>
#include <iomanip>
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << " is "
<< (isEven(i) ? "even" : "odd") << '\n';
}
return 0;
}
It's literally that simple. Here's another nice feature of using the constexpr helper function... You can also format your output as such:
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << ": "
<< std::boolalpha << isEven(i) << '\n';
}
return true;
}
If you are looking for something that is more efficient than using the modulo operator you can bitwise & with the least significant digit... The code above would then become:
#include <cstdint>
constexpr bool isOdd(uint32_t value) {
return (value&1);
}
And using it would be very similar as above, just make sure you reverse the wording in your output to match that from the function being used...
#include <iostream>
#include <iomanip>
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << " is "
<< (isOdd(i) ? "odd" : "even") << '\n';
}
return 0;
}
Again you can use the std::boolalpha manipulator to get this kind of output:
int main() {
for ( int i = 0; i < 100; i++ ) {
std::cout << std::setw(3) << std::setfill('0') << i << ": "
<< std::boolalpha << isOdd(i) << '\n';
}
return true;
}

How to count duplicates in a vector (C++)

I was working through an exercise in C++ Primer. Actually, I refined my first version. Problem is I not only want to detect duplications in a vector, but also how many times they were duplicated. I'm having trouble with the latter.
Here is my code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> nums{1,3,1,5,7,8,9,7};
sort(nums.begin(), nums.end());
for(unsigned int i = 0; i != nums.size(); ++i){
if(nums[i] == nums[i + 1]){
cout << nums[i] << " is a duplicated number" << endl;
}
}
return 0;
}
EDIT: Also just noticed my logic is flawed. If a number appears more than twice it will print out multiple times it's a duplicate. Which is redundant.
Use a std::map
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
int main()
{
map<int, int> duplicate;
vector<int> nums{1,3,1,5,7,8,9,7,1};
vector<int> nums_sorted{nums};
sort(begin(nums_sorted), end(nums_sorted));
auto beg = begin(nums_sorted) + 1;
for (;beg != end(nums_sorted); ++beg) {
if (*beg == *(beg - 1)) {
duplicate[*beg]++;
}
}
for (const auto& i : duplicate)
cout << i.first << " appear " << i.second+1 << " times" << '\n';
}
Outputs:
1 appear 3 times
7 appear 2 times
You can pair up std::unique<>() with std::distance<>():
std::sort(nums.begin(), nums.end());
auto unique_end = std::unique(nums.begin(), nums.end());
std::cout << std::distance(nums.begin(), unique_end);
You were almost there, here is my suggested solution:
live
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> nums{1,3,1,5,7,8,9,7};
sort(nums.begin(), nums.end());
for(auto it = std::cbegin(nums); it != std::cend(nums); ) {
int dups = std::count(it, std::cend(nums), *it);
if ( dups > 1 )
cout << *it << " is a duplicated number, times: " << dups << endl;
for(auto last = *it;*++it == last;);
}
return 0;
}
A stupid but quick solution:
#include <map>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> nums{1,3,1,5,7,8,9,7,1};
std::map<int, int> dups;
for(int i : nums)
++dups[i];
for(auto& dup : dups)
cout << "Number " << dup.first << " has " << dup.second - 1 << " duplicates\n";
}

Eigen Increment Column by One

How to increment a column of a dynamic matrix by one, as an in place operation (without creating copies/intermediates) ?
Attempt:
#include <Eigen/Dense>
#include <iostream>
#include <stdint.h>
int main(void){
Eigen::MatrixXf A;
A = Eigen::MatrixXf::Random(3, 5);
std::cout << A << std::endl << std::endl;
A.col(1) = A.col(1)*2; //this works.
A.col(1) = A.col(1) + 1; //this doesn't work.
std::cout << A << std::endl;
}
I found a way to do this. But I don't know if the operation is in place.
This is similar to eigen: Subtracting a scalar from a vector
#include <Eigen/Dense>
#include <iostream>
int main(void){
Eigen::MatrixXf A;
A = Eigen::MatrixXf::Random(3, 5);
std::cout << A << std::endl << std::endl;
A.col(1) = A.col(1)*2;
A.col(1) = A.col(1) + Eigen::VectorXf::Ones(3);
std::cout << A << std::endl;
}
Another way is to use array operation. This way seem better (I guess).
https://eigen.tuxfamily.org/dox/group__TutorialArrayClass.html
#include <Eigen/Dense>
#include <iostream>
int main(void){
Eigen::MatrixXf A;
A = Eigen::MatrixXf::Random(3, 5);
std::cout << A << std::endl << std::endl;
A.array() += 1;
A.col(1).array() += 100;
std::cout << A << std::endl;
}

Increase all elements of a List in C++

#include <iostream>
#include <vector>
#include <iterator>
#include <iostream>
#include <cmath>
#include <string>
#include <utility>
#include <cstring>
#include <list>
using std::vector;
using std::cout;
using std::list;
using std::endl;
using std::string;
using namespace std;
template <typename T>
void showContents(T& input)
{
typename T::iterator it;
for (it=input.begin(); it != input.end(); it++)
{ cout << *it << " "; }
cout << endl;
}
int main()
{
int B[10] = {0,1,2,3,4,5,6,7,8,9};
cout<< "The first array is: "<< "\n";
int i;
for (i = 0; i<10; i++)
{cout<< B[i]<< " ";}
vector<int> KVec(B,B+10);
cout << "\n \n" << "The first vector is: " << endl;
showContents(KVec);
list<int> BList(B,B+10);
cout << "\n" << "The first list is: " << endl;
showContents(BList);
int BCopy [10];
cout<< "\n" <<"The second array is: "<< endl;
for(int i = 0; i <10; i++)
{
BCopy[i] = B[i];
BCopy[i] += 2;
cout<< BCopy[i]<< " ";
}
vector<int> KVec2(KVec);
cout<< "\n \n" << "The second vector is: "<< endl;
for (int i = 0; i<KVec2.size(); i++){
KVec2[i] += 3;
}
showContents(KVec2);
cout<< "\n" << "The second list is: "<< endl;
std::list<int> BList2 (BList);
for (std::list<int>::iterator b = BList.begin(); b!=BList.end(); ++b)
{
( *b += 5 );
showContents(BList2);
}
This is the code I have. I was able to correctly copy all the arrays, vectors , and lists and increasing the values of those accordingly. The only one I have not been able to increment in the list. My goal is to increment all the elements of the second list by 5. I have been using mulitple references to try and do it but I have tried everything and can not get it to work. Below I have my latest attempt at trying to increment all the values but that doesn't seem to work either so now I need help. That is the only thing left to do in this assignment so any help would be appreciated. Thank you.
Since my comment fixed your problem, I am converting it into an answer.
You copy constructed BList2 using values from BList (I am changing to brace initialization to avoid Most vexing parse). But then, you are iterating over values of BList again. Also, you don't need parentheses around *b += 5. Finally, your showContents function is probably meant to be outside of the loop.
std::list<int> BList2 {BList};
for (std::list<int>::iterator b = BList2.begin(); b != BList2.end(); ++b)
{
*b += 5;
}
showContents(BList2);

C++ with Boost Library. Reading Columns. Excel/CSV

I'm reading in a CSV that has 3 columns. On each column I need to perform the mean, var, and std calculations. I'm able to get the output for the first column but dont know how to have it print all 3 columns. Thanks.
I tried adding ','
after line
in
while (getline(inNew, line, ','))
but that doesnt work for me
int main()
{
ifstream inNew("C:/Users/A.csv");
accumulator_set<double, stats<tag::mean, tag::variance >> acc;
if (inNew)
{
string line;
while (getline(inNew, line))
{
acc(stod(line));
}
cout << "Expected return is: " << mean(acc) << std::endl;
cout << "Variance: " << variance(acc) << std::endl;
cout << "Std Dev: " << sqrt(variance(acc)) << std::endl;
}
inNew.close();
system("pause");
return 0;
}
Since you're already using boost, use boost::split to split each line into its columns. Then accumulate each column separately. You'll need an accumulator_set for each column.
Code might look something like this:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/variance.hpp>
#include <boost/algorithm/string.hpp>
int main()
{
using namespace std;
using namespace boost;
using namespace boost::accumulators;
ifstream inNew("C:/Users/A.csv");
size_t columns = 3;
vector<accumulator_set<double, stats<tag::mean, tag::variance>>> acc(columns);
if (inNew)
{
string line;
while (getline(inNew, line))
{
vector<string> strs;
split(strs, line, is_any_of("\t ,"));
if (strs.size() == columns)
{
for (size_t i = 0; i < columns; ++i)
{
acc[i](stod(strs[i]));
}
}
}
for (size_t i = 0; i < columns; ++i)
{
cout << "Stats for column " << (i + 1) << endl;
cout << "Expected return is: " << mean(acc[i]) << endl;
cout << "Variance: " << variance(acc[i]) << endl;
cout << "Std Dev: " << sqrt(variance(acc[i])) << endl;
}
}
inNew.close();
system("pause");
return 0;
}
Of course, you could make this more fancy and robust by not hardcoding the number of columns.