I am trying to form a set of vectors of integers and on checking if the same solution already exists in the set, I am not getting correct answer.
This is in regards to C++11. I had posted a similar kind of query earlier as well but had not got any meaningful replies.
Why is it that whenever we form a map or set of vectors, is is not able to recognize if I insert a vector which is identical to the one I have already inserted ?
I have been searching for an answer since months. Also, since this behavior is allowed in other languages like Java, there must be a work around this. It would be great if someone can point out why this behavior isn't working the way I expect it to and what should be the probable solution to this.
The code below is a solution to 3Sum problem on Leetcode, but doesn't work because of exactly what I have explained above.
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>>result;
unordered_map<int,int>m;
set<vector<int>>res;
bool flag=false;
if(nums.size()<=2)
return result;
vector<int>temp;
for(int i=0;i<nums.size()-1;i++)
{
int comp=-(nums[i]+nums[i+1]);
if(m.find(comp)!=m.end())
{
auto location=m.find(comp);
temp.push_back(comp);
temp.push_back(nums[i]);
temp.push_back(nums[i+1]);
if(res.find(temp)==res.end())
{
res.insert(temp);
result.push_back(temp);
}
temp.clear();
}
else
{
m[nums[i]]=i+1;
m[nums[i+1]]=i+2;
}
}
return result;
}
On giving input as
[0,0,0,0]
Answer should be:
[0,0,0]
Whereas I get :
[[0,0,0], [0,0,0]]
You could use tuples in the set instead of vectors.
#include <tuple>
#include <set>
#include <iostream>
using std::get;
int main(int argc, char* argv[]) {
std::set<std::tuple<int,int,int>> sums;
auto tup1 = std::make_tuple(0, 0, 0);
sums.insert(tup1);
auto tup2 = std::make_tuple(0,0,0);
sums.insert(tup2);
std::cout << sums.size() << std::endl;
for (auto& item : sums) {
std::cout << "(" << get<0>(item) << "," << get<1>(item) << "," << get<2>(item) << ")\n";
}
return 0;
}
Related
I have come up with this problem on my own. I am only a beginner and learning C++ currently.
Q. Find all the repeated elements in an array and provide their index number.
I am trying to solve this question using for loops.
#include <iostream>
using namespace std;
void arfn(int var1[],int length){
int x,y;
int store[length];
for(x=0;x<length;x++){
store[x]=var1[x];}
for(int counter=0;counter<length;counter++)
{
cout<<store[counter]<<endl;
for(x=0;x<length;x++) {
for (y=0;y!=x && y<length;y++)
/*By these loops i expect to find index number of repeated elements,
eliminating the case of program showing the same index numbers*/
{
if(store[x]=store[y]) {
cout<<store[x]<<" "<<x<<" "<<y<<" "<<endl;
}
}
}
}
}
int main()
{
int numbers[]={22,33,44,55,55};
int length=5;
arfn(numbers,length);
return 0;
}
I expect to find the output as
55 3 4
but the output is really huge and is nowhere close to the desired output.
I might suggest, that you get acquainted with the STL first, if you are willing to make C++ a power tool for you.
The following program does the job by transforming a vector to a map, which takes care of the indices.
#include <iostream>
#include <vector>
#include <iterator>
#include <map>
void printDuplicates(const std::vector<int>& arr)
{
std::map<int, std::vector<int>> map;
for (auto iter=arr.begin(); iter!=arr.end(); iter++)
{
auto index = std::distance(arr.begin(), iter);
map[*iter].push_back(index);
}
for (auto& iter : map)
{
if (map[iter.first].size()>1)
{
std::cout << iter.first << " ";
for (auto iterIndices : map[iter.first])
{
std::cout << iterIndices << " ";
}
std::cout << std::endl;
}
}
}
int main() {
std::vector<int> arr{ 1,2,5,7,2,8,4,7 };
printDuplicates(arr);
}
You can find many articles on this algorithmic problem
here is one:
Solving Algorithmic Problems: Find a Duplicate in an Array
You should approach this challenge with some questions
What is the expected input size?
What is the required complexity?
Can I use more memory to optimize the complexity?
Is my input sorted or not?
Then you may start with the naive implementation and try to figure
how can it be optimized
For example:
Which parts of my code run more than once
As for using C++, try looking for C++ specifics,
use std::vector or std::array instead of C style arrays
look for STL algorithms which may solve some of your questions
I want to find indices of an array that equal with specific value. so i've Written this code:
vector<int> _classes = { 2,2,1,1,3,3,3,3,5,5,4,4,5,6,6 };
vector<int> labelVec = {1,2,3,4,5,6};
vector<int> index;
for (int i = 0; i < labelVec.size(); i++)
{
compare(_classes, labelVec[i], index, CMP_EQ);
std::vector<int>::iterator nn = find(index.begin(), index.end(), 255);
}
but i have this error : Unhandled exception at 0x760B5608 in compareFuncTest.exe: Microsoft C++ exception: cv::Exception at memory location 0x004DDC44. if i define index as Mat, this problem will be resolved. but if i define index as Mat, i can't use from find(). also in this documentation states: output array (in my code as index) that has the same size and type as the input arrays. PLZ help me to fix this code.
I still do not get what is the point of this test, I guess this will be in some other algorithm... So, I give you two possible solutions.
1) Without OpenCV
First, you must know that
std::vector<int>::iterator nn = find(index.begin(), index.end(), 255);
Will only give you the first occurrance. Knowing this, here is a way you could check if the label is inside the _classes vector.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> _classes = { 2,2,1,1,3,3,3,3,5,5,4,4,5,6,6 };
std::vector<int> labelVec = {1,2,3,4,5,6,7};
for (const auto& label: labelVec)
{
std::vector<int>::iterator nn = find(_classes.begin(), _classes.end(), label);
if (nn != _classes.end())
{
std::cout << "I got the value from _classes: " << *nn << std::endl;
} else
{
std::cout << "I couldn't find the value with label:" << label << std::endl;
}
}
}
Here I iterate over all the labels (as you did) and then use the find directly in the classes, but with the label variable. Then I check if I found the label or not, if not, it will give you a value equal to _classes.end() which will give error if you try to use it (look at the extra label 7 which is not found).
This example can be tested here online.
2) With OpenCV
no oline test here. But this one is also easy to do. If you have a Mat in index you will only need to change the iterators to be templated. Like this:
auto nn = find(index.begin<int>(), index.end<int>(), 255);
If you a cv::Mat of classes you can also do it as in the method before and skip the comparison part (this would be faster)
Update
Since you want is the indices and all of them, then you have to iterate over it :/ if you wanted the values you could have used copy_if. You can create a lambda function to easily do the job.
like this:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
auto getIndices = [](const std::vector<int>& vec, const int value){
std::vector<int> result;
for (size_t t = 0; t < vec.size(); t++)
{
if (vec[t] == value)
{
result.push_back(static_cast<int>(t));
}
}
return result;
};
std::vector<int> _classes = { 2,2,1,1,3,3,3,3,5,5,4,4,5,6,6 };
std::vector<int> labelVec = {1,2,3,4,5,6,7};
for (const auto& label: labelVec)
{
std::vector<int> nn = getIndices(_classes, label);
std::cout << "I got the following indices for value"<< label<< ": [ ";
for (const auto& n : nn)
{
std::cout << n << ",";
}
std::cout << " ]" << std::endl;
}
}
I need a way to assign numbers to letters in C++, for example, '$' would represent the number 1. I obviously need to be able to obtain the number from the character with something like a function, e.g. getNumFromChar('$') would return 1 and getNumFromChar('#') would return 2. Is there an easy and fast way to do this in C++?
The fastest way is to write a 256 entry lookup table, containing the mapped values in the character's ASCII index. This is similar to how isdigit and tolower work, for example:
int getNumFromChar(char c)
{
static const int table[256] = {/* table entries */};
return table[c & 0xff];
}
If you would like to assign the values yourself use a map and store your key to letter combinations. If you are ok with preassigned unique values mapped to each letter, and are only using ASCII characters, then type cast them to integers... ex) std::static_cast< int >('$');
Create a vector std::vector<int> v(256,0); which is indexed by your characters and initially all of their numbers are zeros that you could treat as invalid numbers. Finally assign for each 'numbered' character some number e.g. v['$'] = 1; v['#'] = 2; using a fact that characters are actually integers from 0 to 255.
As pointed out in the comments, you can use a std::map in the following way:
#include <iostream>
#include <map>
#include <cstring>
struct myComp
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
int main()
{
std::map<const char*, int, myComp> test;
test["$"] = 1;
test["#"] = 2;
std::cout << "$ -> " << test["$"] <<"\n";
std::cout << "# -> " << test["#"] <<"\n";
return 0;
}
Live demo here.
Majority of the other answers will work only if you have a maximum of 256 values to be stored. However, using Maps, you can store just any number of elements.
A lot of people are suggesting std::map<char,int>, which is fine and works, but a faster (?) way of doing this with no dependencies is to just use a massive switch statement
int getNumFromChar(char c){
switch(c){
case '$':
return 1;
case '#':
return 2;
//etc
}
return -1; //just in case of error, for style points
}
Depending on how much you care about performance/memory usage and how many case statements you'd have to write, this may or may not be a viable way to do what you want. Just thought I'd throw it out there since at the time of this writing I don't believe anyone has.
EDIT: Also, depending on the frequency of use of each individual character, and if you know the entire mapping before using this function or if you ever change the mapping, a std::map is way better, but I believe this is faster otherwise.
You could do something like this:
#include <map>
#include <iostream>
#include <exception>
typedef std::map<char, int> easymap_type;
class EasyMap {
public:
EasyMap() {}
virtual ~EasyMap() {}
void assign_int_to_char(const int& i, const char& c)
{
_map[c] = i;
}
int get_int_from_char(const char& c) const
{
easymap_type::const_iterator it = _map.find(c);
if (it == _map.end())
{
std::cerr << "EasyMap Error: uninitialized key - '" << c << "'" << std::endl;
throw std::exception();
}
return it->second;
}
private:
easymap_type _map;
};
int main()
{
EasyMap ezmap;
ezmap.assign_int_to_char(42, 'a');
std::cout << "EasyMap[a] = " << ezmap.get_int_from_char('a') << std::endl;
std::cout << "EasyMap[b] = " << ezmap.get_int_from_char('b') << std::endl;
return 0;
}
I handled an uninitizialized key by throwing an exception, but you could do it different ways.
If your compiler support c++11 feature,you can use std::unordered_map as container to store char and double like std::unordered_map<char,double>.
Unordered map is an associative container that contains key-value pairs with unique keys. Search, insertion, and removal of elements have average constant-time complexity.In your problem char is the key and double is your value,char-double must be the key-value stored in container.
There are already a lot of reasonable answers... I prefer the static_cast<int>('#')
And there always has to be the most stupid useless compile time template idea about how to solve a problem.
I know it's stupid, and I'm not good at this kind of things, but here is my shot at it in c++11. Don't take me seriously. I just had to do something dumb.
#include <string>
#include <array>
#include <utility>
#include <iostream>
constexpr uint kNbChars {3};
constexpr std::array<std::pair<char, int>, kNbChars> kCharToInt {
std::make_pair('$', 1)
, std::make_pair('#', 2)
, std::make_pair('#', 3)
};
template <char c>
int getInt()
{
for (auto pair : kCharToInt)
{
if (pair.first == c)
{ return pair.second; }
}
return -1;
}
int main()
{
std::cout << getInt<'#'>() << std::endl;
std::cout << getInt<'g'>() << std::endl;
}
I think you can make getInt() constexpr too in c++14, but I may be wrong and cannot check it right now.
Of course it really is useless since you have to know the letter at compile time, but you could work around that by, well, just not making getInt a template function...
I've been playing with a simple example using C++11 and some standard algorithms, and I'm not sure whether to use std::accumulate or std::for_each. The problem is to count letters in a word, so, for example, for an input of "abracadabra", you get
'a' => 5
'b' => 2
'c' => 1
'd' => 1
'r' => 2
My first cut was to use std::accumulate. The reason this seemed natural is that we're really accumulating a value (a set of frequencies). Also I've been doing some functional programming recently and accumulate seemed to be the natural translation of folding a list.
vector<int> charsInWord(const string& text)
{
return
std::accumulate(text.begin(), text.end(), vector<int>(256),
[] (const vector<int>&v, char c)
{
vector<int> v2(v);
v2[c]++;
return v2;
} );
}
However this solution seemed rather cumbersome and took a little while to get right. Moreover, even with the new move semantics I couldn't quite convince myself that there wouldn't be any unnecessary copying.
So I went for for_each instead.
vector<int> charsInWord2(const string& text)
{
vector<int> charCounts(256);
std::for_each(text.begin(), text.end(),
[&] (char c)
{
charCounts[c]++;
} );
return charCounts;
}
This is probably easier to write and understand, and I certainly feel happier about its efficiency (although I miss the declarative, functional style of accumulate).
Is there any good reason to prefer one over the other in examples like these? From the comments and answers so far, it seems like if the value I am accumulating is non-trivial, say an stl container rather than an int, I should always prefer for_each, even when I am really "accumulating".
For the sake of completeness, the rest of the code to get this to compile and test is below
#include <string>
#include <vector>
#include <numeric> // accumulate
#include <algorithm> // for_each
using std::string;
using std::vector;
#include <iostream>
// ... insert code above ...
int main(int argc, char* argv[])
{
const vector<int> charCounts = charsInWord("abracadabra");
for(size_t c=0; c<charCounts.size(); ++c) {
const int count = charCounts[c];
if (count > 0) {
std::cout << "'" << static_cast<char>(c) << "'" << " => " << count << "\n";
}
}
return 0;
}
Personally I would not have written the accumulate like that:
vector<int> charsInWord(const string& text)
{
std::vector<int> result(256); // One version never copied.
int count = std::accumulate(text.begin(), text.end(), 0,
[&result] (int count, char c)
// ^^^^^^^^^ capture
{
result[c]++;
return count+1;
} );
// Might use count in the log file.
return result;
}
But If I am doing that it seems just as easy to use for_each()
vector<int> charsInWord2(const string& text)
{
vector<int> result(256);
std::for_each(text.begin(), text.end(),
[&result] (char c)
{
result[c]++;
} );
return result;
}
I don't see anything wrong with the for_each version.
But why not go with a simple for() loop?
vector<int> charsInWord2(const string& text)
{
vector<int> result(256);
for(char c : text) {result[c]++;}
return result;
}
There was some discussion about using std::map in the comments (and then in some deleted questions). Just to capture that here and expand.
We could have used std::map<char,int> instead of vector<int>. The difference are:
From: #Dave std::map has O(ln(n)) lookup time while vector is O(1). So there is a performance consideration. Note also that the fixed cost for map will be higher than vector. Though this is small but worth noting.
From: #Dave std::vector has a fixed size of approx 256*4 (1024), while map has a size of approx 12*number of unique characters (min 12 max 3072). So no real space consideration in modern machine. But may be worth optimizing on phones and such.
From: #POW The third point is the std::map makes printing the result much easier as you do not need to check for empty values.
Vector print
for(size_t c=0; c<charCounts.size(); ++c) {
if (count > 0) {
std::cout << "'" << static_cast<char>(c) << "' => " << charCounts[c] << "\n";
}
}
Map Print
for(auto loop: charCounts) {
std::cout << "'" << loop.first << "' => " << loop.second << "\n";
}
I have two questions but they are interlinked.:
part:a->
I have been trying to display the elements of vector in reverse order. But nothing is working. I have used iterotar like;
for (it=vec.end(); it!=vec.begin(); --it){
// it is iterator not reverse_iterator.
// do work
}
P.S I am not much familiar with iterators. I have used them for the first time today to
display elem in reverse order.
also tried;
for (int i=vec.size(); i!=0; i--){
//display
}
No matter what I do it always display the elem in same order as they are present i.e not in the reverse order.
part_b->
Is there any way that I can store the output of a recursive function direct into a vector. like the code is:
I know this does not work. I have tried but just giving you an idea
what I am upto.
#include <iostream>
using namespace std;
#include "vector"
int func(int num);
vector <int> vec;
int main() {
int num=34;
// I know this would not work. But is there any possibilitiy that
// I can store the output in a vector.
vec = binary(num);
// trying to display the vector.
for (int i=vec.size();i!=0;i--) {
cout<<vec[i]<<" ";
} // not working for reverse display.
} //main.
int func(int num) {
if (num==1) {
//vec.push_back(1);
return 1;
}
else if(num==0) {
//vec.push_back(0);
return 0;
}
else {
//vec.push_back(input%2);
return binary(input/2);
}
} //func.
I hope you do unnderstand the question. if I am able to do the part b the there is no need to reverse the elem of the vector.
The standard solution uses reverse iterators:
for (auto it = v.rbegin(); it != v.rend(); ++it)
{
if (it != v.rbegin()) { std::cout << ' '; }
std::cout << *it;
}
Alternatively, you can use indices, but keep the "reversal" idiom and increment the index:
for (std::size_t i = 0; i != v.size(); ++i)
{
if (i != 0) { std::cout << ' '; }
std::cout << v[v.size() - i - 1];
}
Note that reverse iterators are literally just doing something very similar to the explicit loop under the hood. In particular, the base() member function of a reverse iterator gives you the corresponding ordinary iterator offset by one, just as we have a - 1 in the index computation. (E.g. rbegin() is just end() under the hood, but decrements by one upon dereferencing.)
Use reverse iterators:
for (auto it = vec.crend(); it != vec.crbegin(); ++it) {
std::cout << *it << ' ';
}
std::cout << '\n';
Part A
Assuming you haven't got access to C++11:
vector<int>::const_reverse_iterator it;
for (it=vec.rbegin(); it!=vec.rend(); ++it)
{
// do work
}
Part B
It looks very much like you're trying to display a number in binary. Unfortunately the standard flags on ostream only allow hex, decimal or octal as far as I'm aware, but can I suggest a simpler way of doing this?
#include <bitset>
bitset< sizeof(int) << 3 > b(34);
cout << b << endl;
Which gives:
00000000000000000000000000100010
The rather ugly looking sizeof(int) << 3 is just a way of getting the size of an int in bits to avoid truncation.
I wrote little program which may help. Maybe your vector is empty?
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<int> vec;
vec.insert(vec.begin(), 1, 1);
vec.insert(vec.begin(), 1, 2);
vec.insert(vec.begin(), 1, 3);
vector<int>::iterator i;
for (i = vec.end(); i != vec.begin(); --i)
{
cout << *i;
}
cout << *i;
return 0;
}