In the input I would like to erase all non unique values. I want the subset after removing the double items to be identical to the input. Somehow some characters remain in the input and not all characters are removed. It seems like the std::map inside the predicate is also decrementing in size.
The predicate to std::remove_if() I am using is:
template<class T>
class RemovePredicate {
public:
RemovePredicate() : m_oldsize(0) {}
bool operator()(const T& value)
{
//
bool retval;
m_uniques[value] ='a'; // 'a' could be any value
cout << m_uniques.size() << endl;
retval = m_uniques.size() == m_oldsize;
m_oldsize = m_uniques.size();
return retval;
}
private:
std::map<T, char> m_uniques;
unsigned m_oldsize;
};
I designed the predicate in such way that when I can see the size increases I have not encountered the input. So when the size is not the same I don't remove the input. When the size remains the same I've encountered that input value again, then I do remove it.
The code to test this is:
template<class T>
void print(T iterable)
{
for (auto c : iterable)
cout << c;
cout << endl;
}
int main(int argc, char** argv){
if (argc != 2)
return 1;
char * str= argv[1];
vector <char> charvec (str, str + strlen(str));
print(charvec);
auto itend = std::remove_if(charvec.begin(),
charvec.end(),
RemovePredicate<char>()
);
print(charvec);
// apply erase remove idiom
charvec.erase(itend, charvec.end());
print(charvec);
return 0;
}
a example input is:
./remove_duplicates deadbeef
output gives
deabef
But as you can see there is still a double 'e' inside the output. But on the bright side the original ordering is maintained.
What am I doing wrong?
There's no guarantee that every call to the predicate is made on the same copy of the function object.
You need to arrange for copies to share a single map (or set or unordered_set), e.g. by declaring the map at a wider scope and keeping a reference, or by using shared_ptr (so the function objects as a group still own it).
Related
To improve the readability, I'm trying to get out of the habit of reinventing the wheel.
Problem:
Consider a black-box function, Foo, which has an integer as input and output. We want to find the input that maximises the output. Consider that all the possible inputs belong to a single, contiguous range of integers; and that the range is small enough that we can try each one.
Speed is important, so we don't use containers. Even if the user has already created a container for all the possible inputs, it's still about 100x faster to calculate the next input (++input) than to get it from memory (cache misses).
Example:
Range: [5, 8)
Foo(5); // 19
Foo(6); // 72
Foo(7); // 31
We want to make a function that should return 6:
InputOfMaxOutputOnRange(5, 8, Foo); // 6
Custom solution:
template <typename T, typename Func>
T InputOfMaxOutputOnRange (T begin_range, T end_range, Func && Scorer)
{
// initialise:
auto max_o = Scorer(begin_range);
T i_of_max_o = begin_range;
// now consider the rest of the range:
++begin_range;
for (T i = begin_range; i < end_range; ++i)
{
auto output = Scorer(i);
if (max_o < output)
{
max_o = output;
i_of_max_o = i;
}
}
return i_of_max_o;
}
Question:
I use functions like this so often that I think there should be an STL way to do it. Is there?
C++20 ranges can do this:
template<typename T, typename F>
T argmax_iota(T begin, T end, F &&score) { // can't really think of a good name for this; maybe it doesn't even deserve its own function
return std::ranges::max(std::views::iota(begin, end), std::less{}, std::ref(score));
// over the values in the range [begin, end) produced by counting (iota)...
// find the one that produces the greatest value (max)...
// when passed to the projection function score...
// with those values under the ordering induced by std::less
}
Godbolt
iota does not store the whole range anywhere. Iterators into the range hold a single T value that is incremented when the iterator is incremented.
In general, the algorithms in the STL work on sequences of values, that are traversed by iterators. They tend to return iterators as well. That's the pattern that it uses.
If you're doing a lot of things like this, where your input "sequence" is a sequential list of numbers, then you're going to want an iterator that "iterates" over a sequence (w/o any storage behind it).
A little bit of searching turned up Boost.CountingIterator, which looks like it could do what you want. I'm confident that there are others like this as well.
Warning - completely untested code
auto iter = std::max_element(boost::counting_iterator<int>(5),
boost::counting_iterator<int>(8),
// a comparator that compares two elements
);
return *iter; // should be '6'
As others have observed, std::max_element is defined to get the largest element in a a range.
In your case, the "iterator" is an integer, and the result of dereferencing that iterator is...some result that isn't related to the input in an obvious (but apparently you have some way to getting it efficiently nonetheless).
This being the case, I'd probably define a specialized iterator class, and then use it with std::max_element:
#include <iostream>
#include <iterator>
#include <algorithm>
// your association function goes here. I've just done something
// where the relationship from input to output isn't necessarily
// immediately obvious
int association_function(int input) {
int a = input * 65537 + 17;
int b = a * a * a;
return b % 127;
}
class yourIterator {
int value;
public:
// create an iterator from an int value
explicit yourIterator(int value) : value(value) {}
// "Deference" the iterator (get the associated value)
int operator*() const { return association_function(value); }
// advance to the next value:
yourIterator operator++(int) {
yourIterator temp(value);
++value;
return temp;
}
yourIterator &operator++() {
++value;
return *this;
}
// compare to another iterator
bool operator==(yourIterator const& other) const { return value == other.value; }
bool operator!=(yourIterator const& other) const { return value != other.value; }
// get the index of the current iterator:
explicit operator int() const { return value; }
};
int main() {
// For demo, print out all the values in a particular range:
std::cout << "values in range: ";
std::copy(yourIterator(5), yourIterator(10), std::ostream_iterator<int>(std::cout, "\t"));
// Find the iterator that gives the largest value:
yourIterator max = std::max_element(yourIterator(5), yourIterator(10));
// print out the value and the index that gave it:
std::cout << "\nLargest element: " << *max << "\n";
std::cout << "index of largest element: " << static_cast<int>(max);
}
When I run this, I get output like this:
values in range: 64 90 105 60 33
Largest element: 105
index of largest element: 7
So, it seems to work correctly.
If you need to use this with a variety of different association functions, you'd probably want to pass that as a template parameter, to keep the iteration part decoupled from the association function.
// pass association as a template parameter
template <class Map>
class mappingIterator {
int value;
// create an instance of that type:
Map map;
public:
// use the instance to map from iterator to value:
int operator*() const { return map(value); }
Then you'd have to re-cast your association function into a form suitable for use as a template parameter, such as:
struct association_function {
int operator()(int input) const {
int a = input * 65537 + 17;
int b = a * a * a;
return b % 127;
}
};
Then in main you'd probably want to define a type for the iterator combined with an association function:
using It = mappingIterator<association_function>;
It max = std::max_element(It(5), It(10));
You can use std::max_element defined in <algorithm>.
This will return the iterator to the maximum element in a specified range. You can get the index using std::distance.
Example copied from cppreference.
std::vector<int> v{ 3, 1, -14, 1, 5, 9 };
std::vector<int>::iterator result;
result = std::max_element(v.begin(), v.end());
std::cout << "max element at: " << std::distance(v.begin(), result) << '\n';
I want to create a function in which I can iterate over an array/vector containing a variable amount of strings, and I need to know the length of the strings before I send them to the function. How can I achieve this in an efficient way?
I have some loose idea of the function, but how do I efficiently sent an array/vector of strings to it and the size of all those strings combined. For example, the function could look something like this:
myFunc(vector<string> s, int totalWordLength) {
// Loop over strings in vector.
}
I could do something like this to create a vector of strings.
const char *args[] = {"12345", "678"};
vector<string> s(args, end(args));
But how do I then find out the size of the strings (8) in this without looping through it so that I can send it to myFunc(s, sizeOfStrings)?
If you have an idea to achieve the same result, by using an array instead or something, please let me know. I'm trying to do this as efficient as possible.
Iterate through container (container class irrelevant)
const char *args[] = {"12345", "678"};
vector<string> s(args, end(args));
size_t sizOfS = 0;
for( auto& item : s )
sizOfS += item.length();
Another way unites process of filling array and calculating length:
const char *args[] = {"12345", "678"};
std::vector<std::string> s;
s.reserve(sizeof(args)/sizeof(args[0]));
size_t sizOfS = 0;
for( const std::string& item : args )
{
sizOfS += item.length();
s.push_back(item);
}
Regardless of what you do, cost of the process would be O(n), where n = strings * their-total-length. There is no other defined way, but several functions which can turn loop into one-liner. Even if define your own container that would track length of strings, its cost would have same order.
Which container to use depends on what kind of actions you expect to perform, vector got constant cost of random access to container items, but linearly increasing cost of growing its storage. list may have cheap insertion\push cost but it got sequential iterator.
If you want to know the lengths of all of the strings in the vector and query it often (its not a one-off thing) then you can calculate the length of the strings when they are added together and store the total with the vector.
A quick example of this with a class:
class MyClassFoo {
public:
std::vector<std::string> items;
std::size_t total_item_sizes = 0;
void addItem(const std::string& item) {
total_item_sizes += item.length(); // Add its length to the total
items.emplace_back(item); // Add the item to the vector
}
}
Then you can pass this object around and query it.
If you want to be more efficent pass by reference or move single use parameters. This is important with something like a std::vector as you probably don't want to copy all it's elements.
As an aside it is unlikely this is actually neccasary, unless you are trying to sum the lengths of all the strings very frequently and there are a lot of them, your bottleneck will not be iterating over an std::vector. Your demand for 'efficency' smells like premature optimisation. Remember the 20-80 rule (80% of your program execution time is spent running 20% of your code).
Given your scenario, an approach could be to calculate the length of the strings at the time of construction of the vector.
One solution using a variadic template could be a wrapper like this (live):
#include <iostream>
#include <vector>
#include <string>
struct V
{
template <typename ... T>
V( T&& ... t ) : v{ std::forward<T>(t)... }
{
for ( const auto& s : v ) size += s.size();
}
std::vector<std::string> v;
std::size_t size {0};
};
int main()
{
const char *args[] = { "12345678", "6789", "1234", "5678" };
V obj ( std::begin(args), std::end(args) );
std::cout << "No. of Strings : " << obj.v.size() << '\n';
std::cout << "Total Length : " << obj.size << '\n';
return 0;
}
Output:
No. of Strings : 4
Total Length : 20
The following structure :
struct SomeStructure {
uint64_t value;
uint64_t data;
};
bool operator > (const SomeStructure& v1, const SomeStructure& v2) {
return (v1.value > v2.value);
}
bool operator < (const SomeStructure& v1, const SomeStructure& v2) {
return (v1.value < v2.value);
}
bool operator == (const SomeStructure& v1, const SomeStructure& v2) {
return (v1.value == v2.value);
}
Is used in a code similar to the following:
SomeStructure st1, st2;
st1.value = st2.value = 10; // has the same 'value'
st1.data = 20; // but is assigned a different number for the 'data'.
st2.data = 40;
std::set<SomeStructure> TheSet;
TheSet.insert(st1);
TheSet.insert(st2);
Will inserting st2 after st1 replace the value of the element present in the set?
In the above example, because the operators > and < are overloaded to only depend on the member SomeStructure::value, both st2 and st1 are considered to be equal while inserting them into TheSet. But the value of SomeStructure::data is different for both these objects. So will it replace the existing element in TheSet or will it ignore the insertion operation if the element is already present?
Is there a way to explicitly enforce either of these two behaviors?
Will this behavior change with compiler and platform?
Edit 1:
I just tested this out in g++ compiler (with c++11 enabled). It does not replace. So is there a way to explicitly enforce this to replace the existing element?
Edit 2:
Actually, there is no standard way to "enforce" this behavior, but it can be done using a simple hack through. Though This method is not recommended, let me present it here:
This method must be used in place of the member function insert within std::set
template <typename T>
void insert_replace(std::set <T>& theSet, const T& toInsert) {
auto it = theSet.find(toInsert);
if(it != theSet.end())
*((T*)&(*it)) = toInsert;
else
theSet.insert(toInsert);
}
And the above code must be replaced with:
int main() {
SomeStructure st1, st2;
st1.value = st2.value = 10; // has the same 'value'
st1.data = 20; // but is assigned a different number for the 'data'.
st2.data = 40;
std::set<SomeStructure> TheSet;
insert_replace (TheSet, st1);
insert_replace (TheSet, st2);
for(auto ii : TheSet) {
std::cout << ii.data;
}
return (0);
}
This method works fine on my compiler, giving the output : 40, instead of 20. But I think people might say this not a recommended method because, the line *((T*)&(*it)) = toInsert; fools the compiler into thinking that the iterator it isn't a constant (but when it actually is). I believe this is the only way we can force std::set to insert by replacing. Is it fine to use this method in my code? or will it cause problems in the future (even if I document it)?
From the documentation:
the insertion operation checks whether each inserted element is equivalent to an element already in the container, and if so, the element is not inserted
So TheSet.insert(st2); will not insert anything, because st2 is equal to st1, which is already in the set.
If you want to be able to insert both of them, you need to change the comparison functions so they test both value and data, or use std::multiset, which allows duplicate entries.
This question already has answers here:
How to check if a string is in a list of strings?
(8 answers)
Closed 11 months ago.
#include <iostream>
#include <string>
using namespace std;
bool in_array(string value, string *array)
{
int size = (*array).size();
for (int i = 0; i < size; i++)
{
if (value == array[i])
{
return true;
}
}
return false;
}
int main() {
string tab[2] = {"sdasd", "sdsdasd"};
string n;
cin >> n;
if (in_array(n, tab)) {
}
return 0;
}
I want to check in C++ if n string is in tab array, but the code return an error.
What I am doing wrong? Maybe I should use the vectors?
int size = (*array).size();
It will not tell you the size of array, it tells you the length of first string in that array, you should pass the length of array to the function separately. The function should look like:
bool in_array(string value, string *array, int length)
But a better choice is using std::vector and std::find:
#include <vector>
#include <algorithm>
bool in_array(const std::string &value, const std::vector<std::string> &array)
{
return std::find(array.begin(), array.end(), value) != array.end();
}
and then, you can use it like:
std::vector<std::string> tab {"sdasd", "sdsdasd"};
if (in_array(n, tab))
{
...
}
When passing an array as an argument to a function which takes only a pointer, you can't query the size of the array within the function (since it got converted to a "stupid" pointer to the first element, nothing more). You typically add a "count" parameter to your signature or an "end" iterator instead.
What you're trying to implement is basically std::find. It takes two iterators (begin and end of the sequence) and the element to be found. Simply use this function.
std::find(std::begin(tab), std::end(tab), n);
will return an iterator to the element if it was found, the end iterator otherwise. Checking for equality with the end iterator will tell you if the element was found in the array.
If you don't like the "iterator interface" of the std algorithms, you can achieve your PHP-like signature by wrapping around std::find by using a template function:
template<class Element, class Container>
bool in_array(const Element & element, const Container & container)
{
return std::find(std::begin(container), std::end(container), element)
!= std::end(container);
}
Please note: This answer assumes C++11. If you use an older compiler, it might not work or it only works if you add -std=c++11 to the compiler flags.
masoud answer is correct but it overly complicated. all you need is this.
bool isInVect=false;
isInVect = std::find(vector.begin(), vector.end(), stringToFind) != vector.end();
if (isInVect == true)
{
cout << "Found string in Vector ..." << endl;
}
How can input a word and reverse the output of it. I made a function to calculate the length of the word and from here I have to reverse the word depending on the length of it.
How can I do that?
#include<iostream>
using std::cout;
using std::endl;
using std::cin;
int LengthOfString( const char *); // declaring prototype for length of the string
int reverse(const char []);
int main()
{
char string1[100];
cout<<"Enter a string: ";
cin>>string1;
cout<<"Length of string is "<<LengthOfString(string1);
system("PAUSE");
return 0;
}
int LengthOfString( const char *x)
{
int index;
for(index = 0; *x!='\0';x++,index++);
return index;
}
int reverse(const char y[])
{
/* my attempted loop, its not right i know.
a[] = *index; // length of the word
for(int i=0; i<=index/2; i++)
for(j=0; j == length, j--) */
}
This wheel has already been invented, and exists in the standard library.
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string word;
std::cout << "Enter a word: ";
std::cin >> word;
std::reverse(word.begin(), word.end());
std::cout << "Reverse: " << word << std::endl;
return 0;
}
To understand exactly what's going on here, there are a few things that you must cover first:
data structures (classes)
containers
iterators
I hope you already know what a class is. In case you're still in introductory stuff, a class is basically a user defined collection of state and behavior. The author can choose to restrict access to the state or behavior of a class for a variety of reasons. In the case of std::string, the standard library string class, all of the state is hidden and only behavior is accessible.
The string class is a container that contains characters. There are numerous other container classes, each of which with different strengths and weaknesses. The string class contains a sequence of characters with a strict order. Other containers exist, such as std::set, std::vector, std::list, and others. std::string bears a passing resemblance to std::vector, and is a distant cousin of std::list. Each collection behaves differently and is suited for different things.
You might think you need to understand how the string class stores its data in order to reverse it, but you don't. This is where iterators come in. std::string owns a typedef, std::string::iterator, which is a special object which stores the location of a single element in a string. std::reverse is a library function which takes 2 iterators and repeatedly swaps their contents and moves them towards each other. This looks like this as it's happening:
v v <-- positions of iterators (start at the start, end at the end)
ABC <-- initial state
v v <-- the end iterator moved back
ABC
v v
CBA <-- the iterators swapped their values
vv <-- the begin iterator moved forward
CBA
V <-- the end iterator moved back; both iterators are in the same place
CBA <-- therefore, we're done, the string is reversed
One thing about iterators is they're kind of like pointers. In fact, you can pass pointers to some functions that expect iterators because they behave syntactically the same. Therefore, you should be able to write your own reverse function that uses pointers that basically does the same thing this did, except with char *s.
Here's some pseudocode that you should be able to write the function with (I won't write it out completely because it's homework):
namespace BaidNation
{
void reverse(char *begin, char *end)
{
loop forever
{
if (end equals begin):
done;
move end backwards;
if (end equals begin):
done;
swap end's and begin's characters;
move begin forwards;
}
}
}
Keep in mind that BaidNation::reverse (as well as std::reverse) expects for end the iterator that references the element AFTER the end of the collection, not the one that references the last element. How does it then make sense to use this?
Your LengthOfString function returns the number of non-null characters in a string. Since arrays are zero-indexed, we know that, like any other array, if we check string1 + LengthOfString(string1), we'll get a pointer to the character after the end which is, for once, exactly what we want.
Thus, we can use this to reverse the string:
BaidNation::reverse(string1, string1 + LengthOfString(string1));
If you have to use exactly the signature earlier, you can adapt this design into the other one:
int reverse(const char str[])
{
char *start = str, *end = str + LengthOfString(str);
BaidNation::reverse(start, end);
}
Based on the fact that the return type of your prototype function is int, it looks to me like you want to do an in-place reversal of a string. You first need to find out how long the string is (although you computed that before, you didn't pass the result to this function), then swap elements until you get to the middle. To make this work you need to pass, not a const char[], but just a char* (indicating that you will be changing the content):
int reverse(char* y)
{
int ii, n;
n = LengthOfString(y); // "no built in functions - otherwise, use strlen()
for(ii=0; ii<n/2;ii++) {
char temp;
temp = y[ii];
y[ii] = y[n - ii - 1];
y[n - ii] = temp;
}
}
Declare a new char* of the same length, and then loop as follows -
for(int i=0;i<stringLength;i++){
newString[i]=oldString[stringLength-i];
}
return newString;
Also you might want to consider using the String class instead of char*.