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

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;
}

Related

error: no matching member function for call to 'erase'?

I was working with vector and trying to work with erase function from vector library.
Here is my code
#include <iostream>
#include <vector>
int leftover(std::vector<int> aList)
{
// size = 1 will be termination point
if (aList.size() == 1)
{
return aList.at(0);
}
else
{
aList.push_back(aList.at(0));
aList.erase(aList.at(0));
aList.erase(aList.at(1));
return leftover(aList);
}
}
int main()
{
int x;
std::cout << "Enter a number: ";
std::cin >> x;
std::vector<int> intVector;
for (int i = 0 ; i < x; i++) {
intVector.push_back(i+1);
}
for (const int& i : intVector)
{
std::cout << i << " ";
}
std::cout << "\n";
//int leftwith = leftover(intVector);
//std::cout << leftwith << "\n";
return 0;
}
Anything with remove the element at particular position would be much appreciated.

set of tuples of items in grocery

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;

Permutation and Combination c++ logical error

This is my assignment, i finished writing my code and it does compile but it is not giving the right answer. So i know there is some logical error but i cannot find out what.
Plz check and tell me, simple code to calculate permutations and combinations
#include <iostream>
using namespace std;
int factorial(int n)
{
if (n == 0 or n == 1)
{
return 1;
}
else
{
return n * factorial(n - 1);
}
}
int permutation(int a, int b)
{
//factorial(a);
int perm = factorial(a) / factorial(a - b);
return perm;
}
int combination(int a, int b)
{
int permutation(int a, int b);
int factorial(int n);
return permutation(a, b) / factorial(b);;
}
int main()
{
int n;
int r;
cout << "Enter n: " << endl;
cin >> n;
cout << "Enter r: " << endl;
cin >> r;
int factorial(int n);
int permutation(int n, int r);
int combination(int n, int r);
if (n >= r)
{
cout << "Permutuation: " << permutation << endl;
cout << "Combination: " << combination << endl;
}
else
{
cout << "Invalid" << endl;
}
return 0;
}
The answer given by the console
Enter n:
6
Enter r:
5
Permutuation: 00AC1375
Combination: 00AC133E
There are a number of errors in your code. First, you should not re-declare your 'permutation' and 'combination' functions inside other functions.
EDIT: Actually, this is not an error but, in my opinion, very bad practice. You could accidentally 'hide' the actual function declaration, which is already provided as you have defined both before any of the calling functions.
Second, your cout << permutation << endl; code is printing a function! This will be taken as meaning the address of that function, which is what you are seeing (HEX addresses).
Here's a 'fixed' version that works (with comments).
#include <iostream>
#include <iso646.h> // Need this in order to use "or" in place of "||"
using namespace std;
int factorial(int n)
{
if (n == 0 or n == 1) {
return 1;
}
else {
return n * factorial(n - 1);
}
}
int permutation(int a, int b)
{
//factorial(a);
int perm = factorial(a) / factorial(a - b);
return perm;
}
int combination(int a, int b)
{
// int permutation(int a, int b); // You don't need to redeclare function inside another one ...
// int factorial(int n);
return permutation(a, b) / factorial(b);;
}
int main()
{
int n, r;
cout << "Enter n: " << endl;
cin >> n;
cout << "Enter r: " << endl;
cin >> r;
// int factorial(int n);
int p = permutation(n, r); // This is how to call your functions ...
int c = combination(n, r); // and assign their returns to values.
if (n >= r) {
cout << "Permutuation: " << p << endl; // Output the values ...
cout << "Combination: " << c << endl; // ...from the functions
}
else {
cout << "Invalid" << endl;
}
return 0;
}
Feel free to ask for further explanations if there's anything I've done that you don't understand.

Printing the contents of a 2d Vector results without indexing each token as one

I'm attempting to print out the contents of a 2d vector in the same fashion in which they are initialized.
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<vector<int > > frontier = {{-1,0}, {1,0}, {0,-1}, {0,1}};
for (int i = 0; i < frontier.size(); i++) {
for (int j = 0; j < frontier[i].size(); j++) {
std::cout << frontier[i][j] << ", ";
}
}
cout << "End of frontier. " << endl;
/* This below is an implementation that I found online but found
no
* way to be able to implement the column reference.
*/
for (int i = 0; i < frontier.size(); ++i) {
for (int j = 0; j < col; ++j) {
cout << frontier[i + j * col] << ' ';
}
cout << endl;
}
}
This is to determine the contents of a 2d vector. So far, this code can print out every index separated by a comma. I, on the other hand, need to write code that will signify where a new vector begins.
output:
-1, 0, 1, 0, 0, -1, 0, 1,
expected output:
{{-1,0}, {1,0}, {0,-1}, {0,1}}
Here's how I might do it:
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector<std::vector<int>> frontier = { {-1,0}, {1,0}, {0,-1}, {0,1} };
std::string outerPrefix = "";
std::cout << "{";
for(const auto& outer : frontier)
{
std::cout << outerPrefix << "{";
std::string innerPrefix = "";
for(auto inner : outer)
{
std::cout << innerPrefix << inner;
innerPrefix = ",";
}
std::cout << "}";
outerPrefix = ", ";
}
std::cout << "}";
}
Output: {{-1,0}, {1,0}, {0,-1}, {0,1}}
In the first example I used a range-based for loop. If you're familiar with the concept of foreach in many languages it's basically the same thing. If you don't need an actual index variable it is safer because you don't have to worry about being off by one and indexing outside the container. It also works the same way on containers like map or set where you would need to use iterators rather than an index.
If you were to do the same thing with nested index loops like you had in your original it might look something like this:
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector<std::vector<int>> frontier = { {-1,0}, {1,0}, {0,-1}, {0,1} };
std::cout << "{";
for(size_t outer = 0; outer < frontier.size(); ++outer)
{
if (outer != 0)
{
std::cout << ", ";
}
std::cout << "{";
for(size_t inner = 0; inner < frontier[outer].size(); ++inner)
{
if (inner != 0)
{
std::cout << ",";
}
std::cout << inner;
}
std::cout << "}";
}
std::cout << "}";
}

Vector of random integer sets

I'm trying to write a little program to create a vector of random integer sets, but the problem is once the first set is created the program keeps storing the same set of numbers in subsequent iterations. Any help to explain or correct this problem would be very much appreciated. Thanks!
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<set>
#include<vector>
using namespace std;
typedef set<int> Set_I;
typedef set<int>::iterator It;
typedef vector<set<int> > vec_Set;
int random();
void print_set(Set_I s);
void print_vec(vec_Set v);
int main()
{
srand(time(0));
Set_I s;
vec_Set v;
v.resize(4);
for(int i=0; i<4;i++)
{
//cout << s.size() << " " <<endl;
while(s.size()<6)
{
s.insert(random());
}
v[i] = s;
s.empty();
}
//print_set(s);
print_vec(v);
cout << endl << s.size() <<endl << v.size();
system("PAUSE");
}
int random()
{
int r = 1 + rand()%49;
return r;
}
void print_set(Set_I s)
{
for(It it=s.begin(); it!=s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void print_vec(vec_Set v)
{
for(int i=0;i<v.size();i++)
{
cout << "{ ";
for(It j = v[i].begin() ; j != v[i].end() ;j++)
{
cout << *j << " ";
}
cout <<"}";
cout <<endl;
}
}
s.empty() returns a bool stating that the set is empty or not. It has no effect on the members of the set!!
you have to use s.clear() for emptying (clearing) your set.

Resources