getting this error expected a declaration. using vscode - c++

getting this error expected a declaration. using vscode to solve leetcode problems
#include <iostream>
#include <vector>
using std::vector;
class solution{
public:;
<int> twoSum(vector <int>& nums, int target)
{
unordered_map<int, int> _map;
for(int i =0; i < nums.size(); i++){
int num = nums[i];
int complement = target - num;
auto it = _map.find(complement);
if(it != _map.end()){
return {it->second, i};
}
_map[num] = i;
}return {}
}
};
error:
"message": "expected a declaration",
"source": "C/C++",
"startLineNumber": 8,
"startColumn": 4,
"endLineNumber": 8,
"endColumn": 5

You probably want this:
...
#include <vector>
#include <unordered_map>
...
using namespace std;
class solution {
public:
vector<int> twoSum(vector <int>& nums, int target)
{
unordered_map<int, int> _map;
for (int i = 0; i < nums.size(); i++) {
int num = nums[i];
int complement = target - num;
auto it = _map.find(complement);
if (it != _map.end()) {
return { it->second, i };
}
_map[num] = i;
}
return {};
}
};

Related

Segmentation Fault - unordered_map(tarjan's algorithm)

I have implemented Tarjan's algorithm to find strongly connected component in a graph and getting Segmentation fault for some large input.
#include <iostream>
#include <sstream>
#include <vector>
#include <stack>
#include <unordered_set>
#include <unordered_map>
using namespace std;
class Graph {
public:
int n, m;
unordered_map<int, unordered_set<int>> graph;
Graph(int n, int m): n(n), m(m) {}
void add_edge(int u, int v) {
graph[u].insert(v);
if(graph.find(v) == graph.end()) graph[v] = unordered_set<int>();
}
void scc_helper(int u, unordered_map<int, int>& disc, unordered_map<int, int>& low, stack<int>& st, unordered_map<int, bool>& inStack, vector<unordered_set<int>>& scc, int& time) {
disc[u] = low[u] = time++;
st.push(u);
inStack[u] = true;
for(const int& ch: graph[u]) {
if(disc[ch] == 0) {
scc_helper(ch, disc, low, st, inStack, scc, time);
low[u] = min(low[u], low[ch]);
} else if(inStack[ch]) {
low[u] = min(low[u], disc[ch]);
}
}
if(disc[u] == low[u]) {
scc.push_back(unordered_set<int>());
while(st.top() != u) {
scc.back().insert(st.top());
inStack[st.top()] = false;
st.pop();
}
scc.back().insert(st.top());
inStack[st.top()] = false;
st.pop();
}
};
vector<unordered_set<int>> get_scc() {
unordered_map<int, int> disc, low;
stack<int> st;
unordered_map<int, bool> inStack;
vector<unordered_set<int>> scc;
int time = 1;
for(const auto& p: graph) {
if(disc[p.first] == 0)
scc_helper(p.first, disc, low, st, inStack, scc, time);
}
cerr << "completed" << endl;
return scc;
}
};
void read(string& input) {
do {
getline(cin, input);
} while(input.length() > 0 && input[0] == '%');
}
Graph read_graph() {
string input;
istringstream ss;
int n, m, v;
read(input); ss.str(input);
ss >> n >> m;
ss.clear();
Graph G(n, m);
for(int u=1; u<=n; u++) {
read(input); ss.str(input);
while(ss >> v) {
G.add_edge(u, v);
} ss.clear();
if(G.graph.find(u) == G.graph.end()) G.graph[u] = unordered_set<int>();
}
return G;
}
int main() {
Graph G = read_graph();
cerr << "read input\n";
vector<unordered_set<int>> scc = G.get_scc();
cout << scc.size() << "\n";
}
After debugging, I have found that the condition if(disc[u] == low[u]) is not getting evaluated to true when program throws segmentation fault.
Another thing is that, Segmentation fault was received on lines disc[u] = low[u] = time++;, st.push(u); and inStack[u] = true; and at that time there were approx. 20,000 entries in each of the unordered_map and in stack.
Some details about input:
for, n=16384 m=283794, the program is working correctly
but for, n=58960 m=269439, it is throwing segmentation fault.

Get Disjunctive Support for itemset?

Disjunctive Support :
let an itemset I formed by any non-empty subset from C
Supp(I) is the number of transactions containing at least one item of I for example i have :
vector < vector <int> > transactions = {{1, 2},
{2, 3, 7},
{4,6},
{1,5,8}};
vector<int> I ={1,2};
expected result :
Supp(I) = 3
but my code return Supp(I) = 1
#include <iostream>
#include <vector>
using namespace std;
int getSupport(vector < vector<int> > &transactions, vector<int> item) {
int ret = 0;
for(auto&row:transactions){
int i, j;
if(row.size() < item.size()) continue;
for(i=0, j=0; i < row.size();i++) {
if(j==item.size()) break;
if(row[i] == item[j]) j++;
}
if(j==item.size()){
ret++;
}
}
return ret;
}
int main() {
vector < vector <int> > transactions = {{1, 2},
{2, 3, 7},
{4,6},
{1,5,8}};
vector <int> I={1,2};
int D = getSupport(transactions, I);
printf("Disjunctive support = %d",D);
return 0;
}
You wrote that:
Supp(I) is the number of transactions containing at least one item of
I
But your implementation looks like you are trying to count transactions containing all the items of I.
Anyway if you still need implementation for the defintion you supplied, you can try this:
#include <iostream>
#include <vector>
int getSupport(std::vector<std::vector<int>> const & transactions, std::vector<int> const & item) {
int ret = 0;
for (auto const & tran : transactions) {
bool bFoundAtLeastOne{ false };
for (auto const & tran_elem : tran) {
for (auto const & item_elem : item)
{
if (tran_elem == item_elem)
{
ret++;
bFoundAtLeastOne = true;
break;
}
}
if (bFoundAtLeastOne) {
break;
}
}
}
return ret;
}
int main() {
std::vector<std::vector<int>> transactions =
{ { 1, 2 },
{ 2, 3, 7 },
{ 4,6 },
{ 1,5,8 } };
std::vector<int> I = { 1,2 };
int D = getSupport(transactions, I);
printf("Disjunctive support = %d\n", D);
return 0;
}
Some notes:
Better to avoid using namespace std - see here Why is "using namespace std;" considered bad practice?
I changed passing all the vectors by const& for efficiency and safety.

How to get the future value?

In using packaged_task, I collected all the futures in a vector. After that, I push back the future values with get(). However, I got the wrong answer. Can anyone help? Thank you very much.
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>
using namespace std;
vector<int> subFun(int n) {
vector<int> a{ 2 * n, 3 * n };
return a;
}
int main() {
vector<boost::future<vector<int>>> g;
vector<vector<int>> x(10, vector<int>(2));
int i;
for (i = 0; i < 10; i++) {
boost::packaged_task<vector<int>> task{ boost::bind(&subFun, i) };
g.push_back(task.get_future());
boost::thread t{ std::move(task) };
}
for (auto& m : g) {
x.push_back(m.get());
}
cout << x[3][0] << endl;//should be 6, now is 0
return 0;
}
The realest issue is that you push_back into x, but you already had it initialized here:
vector<vector<int>> x(10, vector<int>(2));
So, you just add 10 more elements, instead of putting the result at indices 0..9. I'd suggest not pre-filling, like #patrick's answer, or instead filling the designated slot:
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>
using namespace std;
void subFun(int n, vector<int>& into) {
into = { 2 * n, 3 * n };
}
int main() {
vector<boost::future<void>> futures;
vector<vector<int>> x(10, vector<int>(2));
for (size_t i = 0; i < x.size(); i++) {
boost::packaged_task<void> task{ boost::bind(&subFun, i, std::ref(x[i])) };
futures.push_back(task.get_future());
boost::thread(std::move(task)).detach();
}
for (auto& f : futures)
f.wait();
cout << x[3][0] << endl;
}
Of course you can be more complex:
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>
struct TaskResult {
int index;
std::vector<int> data;
};
TaskResult subFun(int n) {
return { n, { 2 * n, 3 * n } };
}
int main() {
std::vector<boost::future<TaskResult>> futures;
std::vector<std::vector<int>> x(10, std::vector<int>(2));
for (size_t i = 0; i < x.size(); i++) {
boost::packaged_task<TaskResult> task{ boost::bind(&subFun, i) };
futures.push_back(task.get_future());
boost::thread(std::move(task)).detach();
}
for (auto& f : futures) {
auto r = f.get();
x[r.index] = r.data;
}
std::cout << x[3][0] << std::endl;
}
After much tinkering, I found this program works without abort traps (which I'm surprised you weren't getting):
#include <future>
#include <thread>
#include <functional>
#include <vector>
#include <iostream>
std::vector<int> subFun(int n) {
std::vector<int> a { 2 * n, 3 * n };
return a;
}
int main() {
std::vector<std::future<std::vector<int>>> g;
std::vector<std::vector<int>> x;
int i;
for (i = 0; i < 10; i++) {
std::packaged_task<std::vector<int>(int)> task{ subFun };
g.push_back(task.get_future());
std::thread { std::move(task), i }.detach();
}
for (auto& m : g) {
m.wait();
x.push_back(m.get());
}
std::cout << x[3][0] << std::endl; // is now 6
return 0;
}
Convert to boost as necessary. This answer was extremely helpful in finding a couple of key issues.

Combination of lists by type algorithm

I'm attempting to create an algorithm in C++ which will give me all of the possible combinations of a set of list items (input in a map format). I want to avoid duplicates and make sure to cover all possible combinations. To simplify the example, here's what the input may look like:
map<string, vector<string> > sandwichMap;
sandwichMap["bread"].push_back("wheat");
sandwichMap["bread"].push_back("white");
sandwichMap["meat"].push_back("ham");
sandwichMap["meat"].push_back("turkey");
sandwichMap["meat"].push_back("roastbeef");
sandwichMap["veggie"].push_back("lettuce");
sandwichMap["sauce"].push_back("mustard");
I'd feed this map into the algorithm, and it should spit out a vector with all of the possible combinations (using one of each key type):
wheat+ham+lettuce+mustard
wheat+turkey+lettuce+mustard
wheat+roastbeef+lettuce+mustard
white+ham+lettuce+mustard
white+turkey+lettuce+mustard
white+roastbeef+lettuce+mustard
It needs to work for any map of string vectors. So far I've tried and gotten close, but I end up with duplicate combinations and missed combinations:
sandwichList getCombinations(sandwichMap sMap)
{
locList retList;
int totalCombos = 1;
for (sandwichMapIt i = sMap.begin(); i != sMap.end(); ++i)
{
totalCombos *= i->second.size();
}
retList.resize(totalCombos);
int locCount;
for (sandwichMapIt a = sMap.begin(); a != sMap.end(); ++a)
{
locCount = 0;
for (locListIt l = a->second.begin(); l != a->second.end(); ++l)
{
for (unsigned int i = 0; i < totalCombos / a->second.size(); ++i)
{
retList[i + a->second.size() * locCount] += *l;
}
locCount++;
}
}
return retList;
}
Any help would be greatly appreciated!
Updated code:
#include <vector>
#include <map>
#include <list>
#include <iostream>
typedef std::vector<std::string> strVec;
typedef std::list<std::string> strList;
typedef std::map<std::string, strVec> sandwichMap;
int main()
{
sandwichMap sMap;
sMap["bread"].push_back("wheat");
sMap["bread"].push_back("white");
sMap["meat"].push_back("ham");
sMap["meat"].push_back("turkey");
sMap["meat"].push_back("roastbeef");
sMap["veggie"].push_back("lettuce");
sMap["sauce"].push_back("mustard");
strList finalSandwichList;
for (sandwichMap::iterator i = sMap.begin(); i != sMap.end(); ++i)
{
strList tmpSandwich;
for (strVec::iterator j = i->second.begin(); j != i->second.end(); ++j)
{
if (finalSandwichList.empty())
{
tmpSandwich.push_back(*j);
}
else
{
for (strList::iterator k = finalSandwichList.begin(); k != finalSandwichList.end(); ++k)
tmpSandwich.push_back(*k + "+" + *j);
}
}
tmpSandwich.swap(finalSandwichList);
}
for (strList::iterator i = finalSandwichList.begin(); i != finalSandwichList.end(); ++i)
{
std::cout << *i << std::endl;
}
return 0;
}
//solution
std::list<std::string> result;
for(auto i=sandwichMap.begin(); i!=sandwichMap.end(); ++i) {
std::list<std::string> new_result;
for(auto j=i->second.begin(); j!=i->second.end(); ++j) {
if(result.empty())
new_result.push_back(*j);
else
for(auto k=result.begin(); k!=result.end(); ++k)
new_result.push_back(*k + "+" + *j);
}
new_result.swap(result);
}
This should work :
#include<iostream>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
map<string, vector<string>> sMap;
vector<string> add;
int sett[200], countt;
void solve(map<string, vector<string>>::iterator itt, int ct, vector<string> addd){
vector<string> tmp = itt->second;
if(ct == countt){
for(int j=0;j<addd.size();j++){
cout<<addd[j]<<" ";
}
cout<<endl;
return;
}
itt++;
for(int i=0;i<tmp.size();i++){
//cout<<tmp[i]<<" ";
addd.push_back(tmp[i]);
solve(itt, ct+1, addd);
vector<string>::iterator tempIt = addd.end();
addd.erase(tempIt--);
}
}
int main(){
sMap["bre"].push_back("wh");
sMap["bre"].push_back("whi");
sMap["me"].push_back("ham");
sMap["me"].push_back("tur");
sMap["me"].push_back("rr");
sMap["veg"].push_back("let");
sMap["sau"].push_back("mus");
countt = sMap.size();
solve(sMap.begin(), 0, add);
return 0;
}
I have used backtracking to evaluate every possible combination.
Note : it is in c++11 you might need to change some part of the code for lower version of c++
link to output : http://ideone.com/Ou2411
The code is kinda long because of the helper methods, but it does the job:
#include <vector>
#include <string>
#include <map>
#include <iostream>
using namespace std;
template <class T>
vector<T> Head(const vector<T> &v) {
return vector<T>(v.begin(), v.begin() + 1);
}
template <class T>
vector<T> Tail(const vector<T> &v) {
auto first = v.begin() + 1;
auto last = v.end();
return vector<T>(first, last);
}
template <class T>
vector<T> Concat(const vector<T> &v1, const vector<T> &v2) {
vector<T> result = v1;
result.insert(result.end(), v2.begin(), v2.end());
return result;
}
vector<vector<string>> CombineVectorWithScalar(const vector<vector<string>> &v, const string &scalar) {
vector<vector<string>> result = v;
for (unsigned i = 0; i < v.size(); i++) {
result[i].push_back(scalar);
}
return result;
}
vector<vector<string>> CombineVectorWithVector(const vector<vector<string>> &v1, const vector<string> &v2) {
if (v2.empty()) {
return vector<vector<string>>();
}
else {
auto headCombination = CombineVectorWithScalar(v1, v2.front());
auto tailCombination = CombineVectorWithVector(v1, Tail(v2));
return Concat(headCombination, tailCombination);
}
}
vector<string> GetKeys(const map<string, vector<string>> &mp) {
vector<string> keys;
for (auto it = mp.begin(); it != mp.end(); ++it) {
keys.push_back(it->first);
}
return keys;
}
vector<vector<string>> CombineMapValues(const map<string, vector<string>> &mp) {
vector<string> keys = GetKeys(mp);
vector<vector<string>> result;
auto &firstVector = mp.begin()->second;
for (auto it = firstVector.begin(); it != firstVector.end(); ++it) {
vector<string> oneElementList;
oneElementList.push_back(*it);
result.push_back(oneElementList);
}
vector<string> restOfTheKeys = Tail(keys);
for (auto it = restOfTheKeys.begin(); it != restOfTheKeys.end(); ++it) {
auto &currentVector = mp.find(*it)->second;
result = CombineVectorWithVector(result, currentVector);
}
return result;
}
void PrintCombinations(const vector<vector<string>> & allCombinations) {
for (auto it = allCombinations.begin(); it != allCombinations.end(); ++it) {
auto currentCombination = *it;
for (auto itInner = currentCombination.begin(); itInner != currentCombination.end(); ++itInner) {
cout << *itInner << " ";
}
cout << endl;
}
}
int main() {
map<string, vector<string> > sandwichMap;
sandwichMap["bread"].push_back("wheat");
sandwichMap["bread"].push_back("white");
sandwichMap["meat"].push_back("ham");
sandwichMap["meat"].push_back("turkey");
sandwichMap["meat"].push_back("roastbeef");
sandwichMap["veggie"].push_back("lettuce");
sandwichMap["sauce"].push_back("mustard");
auto allCombinations = CombineMapValues(sandwichMap);
PrintCombinations(allCombinations);
return 0;
}
void generate_all(std::map<std::string,std::vector<std::string>>::iterator start,
std::vector<std::string::iterator> accomulator,
std::map<std::string,std::vector<std::string>>& sMap){
for (auto it=start; it!=sMap.end(); ++it){
for (auto jt=it->second.begin(); jt!=it->second.end(); jt++){
generate_all(start+1,accomulator.pus_back[jt],sMap);
}
}
if (accomulator.size() == sMap.size()){
// print accomulator
}
}
Call with generate_all(sMap.begin(),aVector,sMap);
If the map is too big to go recursively, you can always generate an equivalent iterative code.
This solution is not recursive. Basically what it does is the following:
Compute how many combinations are actually possible
Know that for each key in the map, you're going to have to add nrCombinations/nrItemsInKey of them in total.
You can see it as a tree growing, branching more and more the more keys you have visited.
If you keep track of how many there are, how spaced they are and where they start you can automatically fill all combinations.
Code
#include <vector>
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, std::vector<std::string> > sandwichMap;
sandwichMap["bread"].push_back("wheat");
sandwichMap["bread"].push_back("white");
sandwichMap["meat"].push_back("ham");
sandwichMap["meat"].push_back("turkey");
sandwichMap["meat"].push_back("roastbeef");
sandwichMap["veggie"].push_back("lettuce");
sandwichMap["sauce"].push_back("mustard");
sandwichMap["sauce"].push_back("mayo");
// Compute just how many combinations there are
int combinationNr = 1;
for ( auto it : sandwichMap ) {
combinationNr *= it.second.size();
}
std::vector<std::vector<std::string>> solutions(combinationNr);
// We start with empty lists, thus we only have one cluster
int clusters = 1, clusterSize = combinationNr;
for ( auto category : sandwichMap ) {
int startIndex = 0;
int itemsNr = category.second.size();
int itemsPerCluster = clusterSize / itemsNr;
for ( auto item : category.second ) {
for ( int c = 0; c < clusters; ++c ) {
for ( int i = 0; i < itemsPerCluster; ++i ) {
// We sequentially fill each cluster with this item.
// Each fill starts offset by the quantity of items
// already added in the cluster.
solutions[startIndex+i+c*clusterSize].push_back(item);
}
}
startIndex += itemsPerCluster;
}
clusters *= itemsNr;
clusterSize = combinationNr / clusters;
}
for ( auto list : solutions ) {
for ( auto element : list ) {
std::cout << element << ", ";
}
std::cout << "\n";
}
return 0;
}

How to convert arrays to vectors using STL

This code is a linear search program using arrays. Out of curiosity, I was wondering how this code could be rewritten using STL vectors in place of arrays but still have the same output.
#include <iostream>
#include <string>
using namespace std;
template <typename T>
int linearSearch(T list[], int key, int arraySize)
{
for (int i = 0; i < arraySize; i++)
{
if (key == list[i])
return i;
}
return -1;
}
int main()
{
int intArray[] =
{
1, 2, 3, 4, 8, 15, 23, 31
};
cout << "linearSearch(intArray, 3, 8) is " << linearSearch(intArray, 3, 8) << endl;
cout << "linearSearch(intArray, 10, 8) is " << linearSearch(intArray, 10, 8) << endl;
return 0;
}
you can do it by changing your parameter type and in main.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template <typename T>
int linearSearch(vector<T> list, int key)
{
for (size_t i = 0; i < list.size(); i++)
{
if (key == list[i])
return i;
}
return -1;
}
int main()
{
int intArray[] =
{
1, 2, 3, 4, 8, 15, 23, 31
};
vector<int> list(intArray, intArray+8);
cout << "linearSearch(list, 3,) is " << linearSearch(list, 3) << endl;
cout << "linearSearch(list, 10) is " << linearSearch(list, 10) << endl;
return 0;
}
This could work (it is based on the STL implementation):
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template <typename ForwardIter, typename Type>
int linearSearch(ForwardIter beg, ForwardIter end, Type key )
{
int i = 0;
for (;beg != end; ++beg)
{
if (key == *beg)
return i;
i++;
}
return -1;
}
int main()
{
vector< int > vec = { 1, 2, 3, 4, 5, 6, 7 };
cout << "linearSearch 1 is " << linearSearch(vec.begin(), vec.end(), 4) << endl;
cout << "linearSearch 2 is " << linearSearch(vec.begin()+2, vec.end(), 1) << endl;
return 0;
}
Note: it can also work for, std::list and std::deque. I think it will produce correct results even in a normal array.
template <typename T>
int linearSearch(const vector<T> &list, const T &key)
{
auto itr = std::find(list.begin(), list.end(), key);
if (itr != list.end())
return std::distance(list.begin(), itr);
else
return -1;
}
int main()
{
int intArray[] = {1, 2, 3, 4, 8, 15, 23, 31};
std::vector<int> vec(intArray, intArray + 8);
int i = linearSearch(vec, 15);
}
Note: C++11 is enabled
With as few changes as possible you could do this:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Using const std::vector<T> & to prevent making a copy of the container
template <typename T>
int linearSearch(const std::vector<T> &list, int key)
{
for (size_t i = 0; i < list.size(); i++)
{
if (key == list[i])
return i;
}
return -1;
}
int main()
{
std::vector<int> arr = { 1 ,2, 3, 4, 8, 15, 23, 31 } ;
cout << "linearSearch(intArray, 3) is " << linearSearch(arr, 3) << endl;
cout << "linearSearch(intArray, 10) is " << linearSearch(arr, 10) << endl;
return 0;
}
I would recommend not using using namespace std;.
template <typename T>
int linearSearch(T list, int key)
Changing the two first lines of your code as above, as well as replacing arraySize with list.size() should suffice for any kind of container supporting operator [] (including vectors), and indices as consecutive int.
Note that while your template tries to abstract the content of the array as the typename T, it implicitely assumes it is int in the type of key. A more generic implementation would be:
template <typename T>
int linearSearch(T list, typename T::value_type key)
Another issue in this solution is the passing mode of list. We can overcome this issue by converting it to a reference like so:
// includes ...
#include <type_traits>
using namespace std;
template <typename T>
int linearSearch(add_lvalue_reference<T> list, typename T::value_type key){
for (size_t i = 0; i < list.size(); i++) {
if (key == list[i])
return i;
}
return -1;
}
Please look at the following example that uses STL linear search algorithm. And see possible implementations of std::find and an example of usage it for a vector here: https://en.cppreference.com/w/cpp/algorithm/find
It would give you a good answer on your question.
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> intsCollection {1, 2, 3, 4, 8, 15, 23, 31};
std::vector<int>::iterator val1 = std::find(intsCollection.begin(), intsCollection.end(), 3);
int pos1 = (val1 != intsCollection.end()) ? (val1 - intsCollection.begin()) : -1;
std::vector<int>::iterator val2 = std::find(intsCollection.begin(), intsCollection.end(), 10);
int pos2 = (val2 != intsCollection.end()) ? (val2 - intsCollection.begin()) : -1;
std::cout << "linearSearch(intsCollection, 3, 8) is " << pos1 << std::endl;
std::cout << "linearSearch(intsCollection, 10, 8) is " << pos2 << std::endl;
}