In this problem, the user enters in two numbers. Each number represents an integer, whose characters are stored into a list. I need to modify the + operator, so that the program will take the two list characters, change them to ints, add them, and then change it back to a char list. Its confusing I know, but hopefully the code will help clear things up:
class LongInt
{
public:
friend LongInt operator+(const LongInt& x, const LongInt& y); //This function will add the value of the two integers which are represented by x and y's character list (val).
private:
list<char> val; //the list of characters that represent the integer the user inputted
}
This is the header file for the LongInt class. There are other parts too it such as a constructor, destructor, etc, but these are the only things that matter in this case. I don't know how to go about writing the code for the operator+ definition in the implementation file. Any ideas?
You would start the function something like this:
LongInt operator+(const LongInt& x, const LongInt& y) {
// code goes here
}
This function definition would go outside the class definition (presumably in a .cpp implementation file).
Inside this function, you would add the parameters x and y using normal longhand addition (add pairs of corresponding digits, handle any carry, etc). Build up the result in a local LongInt object, and return the computed value from your operator+() function.
If it hasn't already been decided for you, you will need to decide whether the least significant digit comes first or last in your val list. Either way is valid, but one choice is likely to be easier to work with than the other (I'll let you decide which one).
If you want to convert the list of chars to an int, you can do something like this:
std::list<char> digits;
int value = 0;
for(std::list<char>::iterator it = digits.begin();
it != digits.end();
++it)
{
value = value * 10 + *it - '0';
}
Related
I have read duplicates but really didn't help me.
I am trying to reach next behaviour.
Having a vector composed by pairs {Thing, set < Thing >}
I want a final result of{Thing, newSetOfThing < Thing >}
where that 'newSetOfThing' is the difference applied with every other
sets in the vector but himself. Difference means to have all values but contained on other sets. I am using std::set_difference.
Giving a closer example with numbers.
vector = {[1, {3,4,5,7}], [2,{1,3,9}], [3, {1,2,12}]};
==>
vectorResult = {[1, {4,5,7}], [2, {9}], [3, {2,12} }
Then my code looks like this:
class Thing {
public:
Thing () {
};
~Thing () {};
int position; //id
bool operator<(const Thing &Other) const;
};
bool Thing::operator<(const Thing &Thing) const
{
return(Other.position<position);
}
//The original vector
vector<pair<Thing, set<Thing>>> pairWithSet;
// I fill vector here [...]
// variable I define to store partial results
set<Thing> differenceResult;
// Vector I want to fill for results
vector<pair<Thing, set<Thing>>> newPairWithSet;
// Operation
for (pair<Thing, set<Thing>> currentPair : pairWithSet){
Thing currentThing= currentPair.first;
differenceResult = currentPair.second;
for (int i=0; i<pairWithSet.size();i++) {
if (pairWithSet[i].first.position != currentThing.position) {
set_difference(differenceResult.begin(),
differenceResult.end(),
pairWithSet[i].second.begin(),
pairWithSet[i].second.end(),
differenceResult.begin());
}
newPairWithSet.push_back(pair<Thing, set<Thing>>(currentThing, differenceResult));
}
I explain my objective to you have a point from where to go but at the end I think problem is more related of how wrong I am using set_difference operation and that I cant directly assign 'Thing'. So set_difference has not a way to check if they are the same. Because error is
binary '=': no operator found which takes a left-hand operand of type
'const Thing' (or there is no acceptable conversion
I say because maybe there are other errors to reach behaviour since I can't still debug until I solve problem with operator.
My question is if I need to declare that '=' operation and how. Or If I miss something and I need to perform by another way.
I can ensure problem is when I use set_difference, If I comment this part compiler does the task:
set_difference(differenceResult.begin(),
differenceResult.end(),
pairWithSet[i].second.begin(),
pairWithSet[i].second.end(),
differenceResult.begin());
And I think is because at the end it is trying to perform an assignment to a const (because std::pair declaration?), as it says error (then obviously compiler does not know how to operate). So I have not clear how to perform it recursive set_difference.
set_difference writes results into place pointed by its 5-th argument. You are passing differenceResult.begin() what is wrong, because begin for set always returns const iterator. You cannot do write operation where a destination is object pointed by const iterator.
If you want to store Thing objects into set as result of set_difference algorithm, you can use std::inserter:
set<Thing> res; // CREATE EMPTY SET
set_difference(differenceResult.begin(),
differenceResult.end(),
pairWithSet[i].second.begin(),
pairWithSet[i].second.end(),
std::inserter(res,res.begin())); // CREATE INSERT_ITERATOR WHICH INSERTS THINGS INTO RES
then you can copy res into newPairWithSet.
Pretty much as the title. I'm writing a linked list and I need a function to sort the list alphabetically, and I'm pretty stumped. Not sure how this has never come up before, but I have no idea how to do it other than to create my own function listing the entire alphabet and comparing positions of letters from scratch.
Is there any easy way to do this?
Edit for clarity:
I've got a linear linked list of class objects, each class object has a char name, and I'm writing a function to compare the name of each object in the list, to find the highest object alphabetically, and then find the next object down alphabetically, etc, linking them together as I go. I already have a function that does this for an int field, so I just need to rewrite it to compare inequalities between alphabetical characters where a is largest and z is smallest.
In hindsight that was probably a lot more relevant than I thought.
I think a couple of the answers I've gotten already should work so I'll pop back and select a best answer once I've gotten it working.
I'm also working with g++ and unity.
I think that in general case the best approach will be to use std::char_traits:
char a, b;
std::cin >> a >> b;
std::locale loc;
a = std::tolower(a, loc);
b = std::tolower(b, loc);
std::cout << std::char_traits::compare(&a, &b, 1u);
But in many common situations you can simply compare chars as you do it with other integer types.
My guess is that your list contains char* as data (it better contain std::strings as data). If the list is composed of the latter, you can simply sort using the overloaded std::string's operator<, like
return str1 < str2; // true if `str1` is lexicographically before `str2`
If your list is made of C-like null-terminated strings, then you can sort them using std::strcmp like
return std::strcmp(s1, s2);
or use the std::char_traits::compare (as mentioned by #Anton) like
return std::char_traits<char>::compare(s1, s2, std::min(std::strlen(s1), std::strlen(s2)));
or sort them via temporary std::strings (most expensive), like
return std::string(s1) < std::string(s2); // here s1 and s2 are C-strings
If your list simply contains characters, then, as mentioned in the comments,
return c1 < c2; // returns true whenever c1 is before c2 in the alphabet
If you don't care about uppercase/lowercase, then you can use std::toupper to transform the character into uppercase, then always compare the uppercase.
#include <stdio.h>
#include <ctype.h>
void main(void) {
char a = 'X', b = 'M';
printf("%i\n", a < b);
printf("%i\n", b < a);
printf("%i\n", 'a' < 'B');
printf("%i\n", tolower('a') < tolower('B'));
}
prints out:
0
1
0
1
chars are still numbers, and can be compared as such. The upper case letters and lower case letters are all in order, with the upper case letters before the lower. (Such that 'Z' < 'a'.) See an ASCII table.
As you can see from this ASCII table, all of the alphanumeric characters appear in the correct alphabetical order, regarding their actual values:
"Is there any easy way to do this?"
So yes, comparing the character values will provide to have them sorted in alphabetical order.
would something like below suffice ? convert everything to upper first.
class compareLessThanChar{
public:
bool operator()(const char a, const char b)
{ return toupper(a) < toupper(b); }
}
std::multiset<char, compareLessThanChar> sortedContainer;
I understand how binary trees are implemented for most native elements such as ints or strings. So I can understand an implementation of std::set that would have a constructor like
switch(typeof(T)) // T being the typename/class in the implementation
{
case int:
{
/* create a binary tree structure that uses the bitshift operator to
add elements, e.g. 13=1101 is created as
/
/
/
/
1
/
/
/
1
\
\
0
/
1
*/
}
case string:
{
/* Do something where the string is added to a tree by going letter-by-letter
and looking whether the letter is in the second half of the alphabet (?)
*/
}
// etcetera for every imaginable type
}
but obviously this is not how std::set is actually implemented, because it is able to create a tree even when I use a homemade data structure like
struct myStruct
{
char c;
bool b;
};
std::set<myStruct> mySet;
Could it be possible to create a generic binary tree class that looks at all the bits of a data structure and does something like the int case I mentioned above?
For instance, in the case of myStruct, the size of the structure is 2 bytes of 16 bits, so a myStruct element S with S.c = '!' and S.b = true could look like
00010101 00000001
(c part) (b part)
=
\
\
0
\
\
0
\
\
0
/
/
1
\
[etcetera]
since the ASCII value for '!' is 21 and a bool = true as an int is 1. Then again, this could be inefficient to do generically because a very large data structure would correspond to a gigantic tree that might take more time to traverse then just doing a basic linear search on the elements.
Does that make sense? I'm truly confused an would love if some people here could set me straight.
What you want is a good book on templates and template meta-programming.
In short, the std::set class only defines a prototype for a class, which is then instantiated at compile-type using the provided arguments (some Key-type Key, some value-type T, which deduces std::less<Key> and std::allocator<std::pair<Key, T>> if not given, or whatever else).
A big part of the flexibility comes from being able to create partial specialisations and using other templates and default arguments.
Now, std::less is defined for many standard-library types and all basic types, but not for custom types.
There are 3 ways to provide the comparison std::map needs:
Override the default template argument and provide it to the template (if the override has state, it might make sense to provide an object to the constructor).
Specialise std::less.
Add a comparison operator (operator<).
Let's try out your example:
#include <set>
struct myStruct {
char c;
bool b;
};
int main() {
std::set<myStruct> mySet;
mySet.insert(myStruct());
}
If we compile this, we actually get an error. I've reduced the error messages to the interesting part and we see:
.../__functional_base:63:21: error: invalid operands to binary expression ('const myStruct' and 'const myStruct')
{return __x < __y;}
We can see here that std::set, to do the work it needs to do, needs to be able to compare these two objects against each other. Let's implement that:
bool operator<(myStruct const & lhs, myStruct const & rhs) {
if (lhs.c < rhs.c)
return true;
if (lhs.c > rhs.c)
return false;
return lhs.b < rhs.b;
}
Now the code will compile fine.
All of this works because std::set<T> expects to be able to compare two T objects via std::less<T> which attempts to do (T) lhs < (T) rhs.
This is highly implementation specific: actual implementations can vary here. I hope to just give you an idea of how it works.
A binary tree typically will hold actual values at each spot in the tree: your diagram makes me think the values are only present at leaf nodes (are you thinking of a trie?). Consider a string binary tree, with memebers cat, duck, goose, and dog:
dog
/ \
cat duck
\
goose
Note here that each node is a value that exists in the set. (Here, our set has 4 elements.) While perhaps you could do some sort of 0/1 prefix, you'd need to be able to convert the object to a bitstring (looking at the raw underlying bytes is not guaranteed to work), and isn't really needed.
You need to understand templates in C++; Remeber that a set<T> is "templated" on T, that is, T is whatever you specify when you use a set. (a string (set<string>, your custom struct (set<MyStruct>), etc.) Inside the implementation of set, you might imagine a helper class like:
template<typename T>
struct node {
T value;
node<T> *left, *right;
}
This structure holds a value and which node is to the left and right of it. set<T>, because it has T to use in it's implementation, can use that to also template this node structure to the same T. In my example, the bit labeled "dog" would be a node, with value being a std::string with the value "dog", left pointing to the node holding "cat", and right pointing to the node holding "duck".
When you look up a value in a set, it looks through the tree for the value, starting at the root. The set can "know" which way to go (left or right) by comparing the value you're looking for / inserting / removing with the node it's looking at. (One of the requirements for a set is that whatever you template it on be comparable with <, or you give it a function to act in place of <: so, int works, std::string works, and MyStruct can work if you either define < or write a "comparator".)
You can always compare two of a kind by comparing their byte array, no matter what.
So, if the set is represented as a sorted binary tree, a memcmp with result -1 indicates insert left, and one with +1 says, insert right.
Later
I was so eager to show that there's no need to branch according to the bits of a set element that I did not consider that there's a restriction that requires a std::set element to implement operator<.
Am I forgiven?
I have been sitting for hours now trying to find a way to use complex values in a std::map. My code is
std::vector<std::complex<double>> coord; // bin coordinates
std::vector<std::string> ref; //A1,D4,...
std::map<std::string,std::complex<double>> bin; //coordinates and reference
std::string letter_ref[] = {"H","G","F","E","D","C","B","A"};
std::string int_ref[] = {"1","2","3","4","5","6","7","8"};
double x=0;
double y=0;
for(int i=0;i<8;++i){
for(int j=0;j<8;++j){
coord.push_back(std::complex<double>(7-i,j));
ref.push_back(letter_ref[i]+int_ref[j]);
bin.insert(std::pair<std::string,std::complex<double>>(letter_ref[i]+int_ref[j], (7-i,j)));
//bin.insert(std::pair<std::string,std::complex<double>>(letter_ref[i]+int_ref[j], (7-x,y)));
++y;
}
++x;
}
This is a part of a constructor. The reason that I have a map and two vectors that are supposed to show the same thing is because I started to use vectors, but found it to be a pain to work with. But I wanted to keep the old vectors for some more time to get the map right first.
However the map does not give the intended result. Printing the map with
std::map<std::string,std::complex<double>>::iterator it;
int i = 0;
for(it=bin.begin();it!=bin.end();++it){
std::cout<<"["<<it->first<<","<<it->second<<"] ";
if ((i+1) % 8 == 0)// & i>0)
std::cout<<"\n";
++i;
}
Does in the first case (uncommented) show that the imaginary part is 0, but the first part is correct. The second case (commented) still shows a 0 value for the imaginary part, but the real part does, instead of giving the values 0-7, give values 0-63.
Does anyone know how to properly use complex numbers in a map?
In the c'tor you want to store a complex number in your map with real part 7-i and imaginary part j. You do this by passing (7-i, j), but this will not invoke the c'tor of std::complex<double> the way you might expect (i.e. with re=7-i and im=j).
What you're actually using in your code is the comma operator. From Wikipedia:
In the C and C++ programming languages, the comma operator
(represented by the token ,) is a binary operator that evaluates its
first operand and discards the result, and then evaluates the second
operand and returns this value (and type).
So by passing (7-i, j) to the c'tor of std::complex<double> instead of creating an imaginary number with real part 7-i and imaginary part j you create a complex number with real part j and no imaginary part. So just replace your line
bin.insert(std::pair<std::string,std::complex<double>>(letter_ref[i]+int_ref[j], (7-i,j)));
with
bin.insert(std::pair<std::string,std::complex<double>>(letter_ref[i]+int_ref[j], std::complex<double>(7-i,j)));
to make it work as expected. This explicitly invokes the c'tor of std::complex<double> with the parameters you specified.
Is there any real sequence of characters that always compares greater than any other string?
My first thought was that a string constructed like so:
std::basic_string<T>(std::string::max_size(), std::numeric_limits<T>::max())
Would do the trick, provided that the fact that it would almost definitely fail to work isn't such a big issue. So I presume this kind of hackery could only be accomplished in Unicode, if it can be accomplished at all. I've never heard of anything that would indicate that it really is possible, but neither have I heard tell that it isn't, and I'm curious.
Any thoughts on how to achieve this without a possibly_infinite<basic_string<T>>?
I assume that you compare strings using their character value. I.e. one character acts like a digit, a longer string is greater than shorter string, etc.
s there any real sequence of characters that always compares greater than any other string?
No, because:
Let's assume there is a string s that is always greater than any other string.
If you make a copy of s, the copy will be equal to s. Equal means "not greater". Therefore there can be a string that is not greater than s.
If you make a copy of s and append one character at the end, it will be greater than original s. Therefore there can be a string that is greater than s.
Which means, it is not possible to make s.
I.e.
A string s that is always greater than any other string cannot exist. A copy of s (copy == other string) will be equal to s, and "equal" means "not greater".
A string s that is always greater or equal to any other string, can exist if a maximum string size has a reasonable limit. Without a size limit, it will be possible to take a copy of s, append one character at the end, and get a string that is greater than s.
In my opinion, the proper solution would be to introduce some kind of special string object that represents infinitely "large" string, and write a comparison operator for that object and standard string. Also, in this case you may need custom string class.
It is possible to make string that is always less or equal to any other string. Zero length string will be exactly that - always smaller than anything else, and equal to other zero-length strings.
Or you could write counter-intuitive comparison routine where shorter string is greater than longer string, but in this case next code maintainer will hate you, so it is not a good idea.
Not sure why would you ever need something like that, though.
You probably need a custom comparator, for which you define a magic "infinite string" value and which will always treat that value as greater than any other.
Unicode solves a lot of problems, but not that one. Unicode is just a different encoding for a character, 1, 2 or 4 bytes, they are still stored in a plain array. You can use infinite strings when you find a machine with infinite memory.
Yes. How you do it, I have no idea :)
You should try to state what you intend to achieve and what your requirements are. In particular, does it have to be a string? is there any limitation on the domain? do they need to be compared with <?
You can use a non-string type:
struct infinite_string {};
bool operator<( std::string const & , infinite_string const & ) {
return true;
}
bool operator<( infinite_string const &, std::string const & ) {
return false;
}
If you can use std::lexicographical_compare and you don't need to store it as a string, then you can write an infinite iterator:
template <typename CharT>
struct infinite_iterator
{
CharT operator*() { return std::numeric_limits<CharT>::max(); }
infinite_iterator& operator++() { return *this; }
bool operator<( const infinite_iterator& ) { return true; }
// all other stuff to make it proper
};
assert( std::lexicographical_compare( str.begin(), str.end(),
infinite_iterator, infinite_iterator ) );
If you can use any other comparisson functor and your domain has some invalid you can use that to your advantage:
namespace detail {
// assume that "\0\0\0\0\0" is not valid in your domain
std::string const infinite( 5, 0 );
}
bool compare( std::string const & lhs, std::string const & rhs ) {
if ( lhs == detail::infinite ) return false;
if ( rhs == detail::infinite ) return true;
return lhs < rhs;
}
if you need an artificial bound within a space of objects that isn't bounded, the standard trick is to add an extra element and define a new comparison operator that enforces your property.
Or implement lazy strings.
Well if you were to dynamically construct a string of equal length as the one that you are comparing to and fill it with the highest ASCII code available (7F for normal ASCII or FF for extended) you would be guaranteed that this string would compare equal to or greater than the one you compare it to.
What's your comparator?
Based on that, you can construct something that is the 'top' of your lattice.