set of tuples of items in grocery - set

I was doing a question given vectors of itemName, price, and quantity in which I had to find out how many duplicates are there in them when combined. So I did solve the problem by using the set of tuples but then I thought of unpacking them and print them. Here's my code:
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<string> name{"ball", "bat", "glove", "glove","glove"};
vector<int> price{2,3,1,2,1};
vector<int> w{2,5,1,1,1};
set<tuple<string,int,int>> s;
for(int i = 0; i < name.size(); i++){
s.insert({name[i],price[i],w[i]});
}
for(int i = 0; i < s.size(); i++){
string st;
int p;
int we;
tie(st,p,we) = s[i]; **statement**
cout<<st<<" "<<p<<" "<<we<<'\n';
}
cout<<name.size() - s.size();
return 0;
}
But there's an error in the statement line. Can't unpack. Need help. Thanks.

Unfortunately you cant unpack a tuple using tie.
Although, if you are using c++17, you could use structural bindings like this (pardon the indentation):
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<string> name{"ball", "bat", "glove", "glove","glove"};
vector<int> price{2,3,1,2,1};
vector<int> w{2,5,1,1,1};
set<tuple<string,int,int>> s;
for(int i = 0; i < name.size(); i++){
s.insert({name[i],price[i],w[i]});
}
for(auto tup : s){
auto [a, b, c] = tup;
cout<<a<<" "<<b<<" "<<c<<'\n';
}
cout<<name.size() - s.size();
return 0;
}
In C++11/14, you might consider printing it directly:
cout << get<0>(tup) << " " << get<1>(tup) << " " << get<2>(tup) << endl;

Related

basic k way merge: terminate called after throwing an instance of 'std::logic_error'

I am trying to implement basic merge k sorted array algorithm but with strings.
I am getting the following error.
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
The code works fine if the names vector has just 2 sub vectors, but when I add another list in the names vector I am getting the above error.
Whats wrong with the code?
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> merge_2_names(vector<string> a, vector<string> b){
int i = 0 ; int j = 0;
vector<string> res;
while(i < a.size() && j < b.size()){
if (a[i].compare(b[j]) < 0){
res.push_back(a[i]);
i++;
}else{
res.push_back(b[j]);
j++;
}
}
while (i < a.size()){
res.push_back(a[i]);
i++;
}
while(j < a.size()){
res.push_back(b[j]);
j++;
}
return res;
}
vector<string> merge_k_names(vector<vector<string>> names){
vector<string> result;
cout << names.size() << "\n";
for (string s: names[0]){
result.push_back(s);
}
for(int i=1;i<names.size();i++)
{
result=merge_2_names(result,names[i]);
}
return result;
}
int main() {
vector<vector<string>> names {{"adam" , "raja" , "zync"},
{"edam" , "some" , "zian"},
{"mike" , "jimm" , "pame"}};
cout << names.size() << "\n";
vector<string> res = merge_k_names(names);
for (string s: res){
cout << s << " ";
}
return 0;
}

Finding maximum difference b/w index in an array, with constraint a[i]<=a[j] where i<j

Here is my code, showing the wrong answer on a few test cases, can anyone tell me where it's failing.
I am not able to figure it out even after multiple attempts.
#include <iostream>
using namespace std;
int main() {
//code
int t,n;
cin >> t;
while(t--)
{
cin >> n;
long long int a[n],max=0;
for(int i=0;i<n;i++)
cin >> a[i];
int i=0,j=n-1;
while(i<=j)
{
if(a[j]>=a[i]){
max=j-i; break;}
else if(a[j-1]>=a[i] || a[j]>=a[i+1])
{ max=j-i-1; break;}
else
i++;
j--;
}
cout << max<<"\n";
}
return 0;
}
There is a solution in O(n log n):
Create a vector of index = 0 1 2 ... n-1
Sort (in a stable way) the indices i, j such that a[i] < a[i]
Determine the max_index values
max_index[i]= max (index[j], j >= i)
This can be calculated in a recursive way O(n)
For each index[i], determine index_max[i+1] - ind[i]); and determine the max of them
The maximum we obtained is the value we are looking for.
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
int diff_max (const std::vector<long long int> &a) {
int n = a.size();
std::vector<int> index(n), index_max(n);
int dmax = 0;
std::iota (index.begin(), index.end(), 0);
std::stable_sort (index.begin(), index.end(), [&a] (int i, int j) {return a[i] < a[j];});
index_max[n-1] = index[n-1];
for (int i = n-2; i >= 0; --i) {
index_max[i] = std::max (index_max[i+1], index[i]);
}
for (int i = 0; i < n-1; ++i) {
dmax = std::max (dmax, index_max[i+1] - index[i]);
}
return dmax;
}
int main() {
int t, n;
std::cin >> t;
while(t--) {
std::cin >> n;
std::vector<long long int> a(n);
for (int i = 0; i < n; ++i)
std::cin >> a[i];
auto max = diff_max (a);
std::cout << max << "\n";
}
return 0;
}
One known case where the algorithm fails:
1
5
5 7 6 2 3
The output, in this case, is 0, but it should be 2.
If the first two if conditions are not satisfied then you are incrementing i, here you are only comparing i with j and j-1, but there can be some other value of k such that k < j-1 and (i,j) is the answer.

C++ : Why it dont work?

I was trying to solve
In which you have given a array of int and you have to return its sum.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main(){
int n;
cin >> n;
int k;
vector<int> arr(n);
for(int arr_i = 0;arr_i < n;arr_i++){
cin >> arr[arr_i];
k = k + arr[arr_i];
//cout << "arr = " << arr[arr_i] << " k " << k << endl; // [0]
if (arr_i == (n-1))
{
cout << k;
}
}
return 0;
}
This return a afkard no. instead of sum.
But when uncomment out [0] line. code starts working as it should.
P.S. i found out the solution by changing cout to cerr.
but wanted to know why it doesn't work.
as the other answer, initialize k, move if outside of loop
vector<int> arr(n);
int k = 0;
for(int arr_i = 0;arr_i < n;arr_i++){
cin >> arr[arr_i];
k = k + arr[arr_i];
//cout << "arr = " << arr[arr_i] << " k " << k << endl; // [0]
}
cout << k;
as your question, there is no need std::vector anymore
int sum = 0, num;
for(int arr_i = 0;arr_i < n;arr_i++){
cin >> num;
sum = sum + num;
}
std::cout << sum << std::endl;
Initialize k before you use, else it will contain junk value int k = 0;
As the other answers (+1) suggested, you need to initialize k. However, I think it is slightly better to assign it the first value initially and reduce the number of iterations therefore:
vector<int> arr(n);
if (n > 0) {
int k = arr[0];
for(int arr_i = 1;arr_i < n;arr_i++){
//Your cycle
}
}

Can somebody tell me what this sorting algorithm is called?

So my teacher told me about the bubble sorting technique and it looks like it runs too many times, so I came up with this, I'm fairly sure that it's already been made and I want to know what it's called.
Here it is:
#include <iostream>
using namespace std;
int main()
{
int n, k = 0, i, min, aux;
cout << "N:";cin >> n;
int v[n];
for(i=0;i<n;i++)
cin >> v[i];
do{
for(i=k;i<n;i++){
if(i==k)
min = i;
if(v[i] < v[min])
min = i;
}
aux = v[k];
v[k] = v[min];
v[min] = aux;
k ++;
}while(k<n-1);
cout << "\n";
for(i=0;i<n-1;i++){
cout << v[i] << ",";
}
cout << v[n-1] << ".";
}
This is called selection sort. Good job coming up with it on your own, you can read about it here.

Parallel Matrix Multiplication in C++

I am trying to implement Parallel Multi-threaded Matrix multiplication in C++. The method i follow involves dividing Arrays into 4 sub-arrays and carry out parallel Multiplication using 4 threads on these 4 sub arrays.
I have written a C++ code but it is throwing error and terminates explicitly. Error :
"terminate called after throwing an instance of std::system_error
what():invalid Argument"
Here is my complete code. I am relatively new to C++ and multi-threading.
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <algorithm>
#include <string>
#define N 4
using namespace std;
mutex mu;
void stage_1_multiply(int *a,int *b,int *d){
int *xij;
int *yij;
int *zij;
int COLS = N,ROWS = N;
cout<< " thread "<< this_thread::get_id() << " "<<endl;
for(int i = 0;i<(N/2);++i){
for(int j = 0;j < (N/2); j++){
for(int k = 0; k<(N/2);k++){
mu.lock();
xij = a + ((COLS * i) + k);
yij = b + ((COLS * k) + j);
zij = d + ((COLS * i) + j);
*zij += ( (*xij) * (*yij) );
mu.unlock();
}
}
}
}
int main(){
int A[4][4],B[4][4],C[4][4],D_1[4][4],D_2[4][4];
for(int i = 0;i<4;i++){
for(int j = 0;j<4;j++){
A[i][j] = i + 1;
B[i][j] = i + 1;
C[i][j] = 0;
D_1[i][j] = 0;
D_2[i][j] = 0;
}
}
for(int i = 0;i<4;i++){
for(int j = 0;j< 4;j++){
cout << A[i][j] << " ";
}
cout << endl;
}
for(int i = 0;i<4;i++){
for(int j = 0;j< 4;j++){
cout << B[i][j] << " ";
}
cout << endl;
}
vector< thread> threads(8);
int th = 0;
threads[th++] = thread(stage_1_multiply,&A[0][0],&B[0][0],&D_1[0][0]);
threads[th++] = thread(stage_1_multiply,&A[0][2],&B[2][0],&D_2[0][0]);
threads[th++] = thread(stage_1_multiply,&A[2][0],&B[0][2],&D_1[2][2]);
threads[th++] = thread(stage_1_multiply,&A[2][2],&B[2][2],&D_2[2][2]);
for( auto& t : threads){
t.join();
}
threads[th++] = thread(stage_1_multiply,&A[0][0],&B[0][2],&D_1[0][2]);
threads[th++] = thread(stage_1_multiply,&A[0][2],&B[2][2],&D_2[0][2]);
threads[th++] = thread(stage_1_multiply,&A[2][0],&B[0][0],&D_1[2][0]);
threads[th++] = thread(stage_1_multiply,&A[2][2],&B[2][0],&D_2[2][0]);
for( auto& t : threads){
t.join();
}
// code to add The Matrices D_1 and D_2 goes here.
for(int i = 0;i<4;i++){
for(int j = 0;j< 4;j++){
cout << D_1[i][j] << " ";
}
cout << endl;
}
cout << " Main Close "<<endl;
return 0;
}
What am doing wrong? is it anything related to parallel access of shared memory? If so how can i correct it?
PS: This is a homework Assignment.

Resources