How does s.compare member function behave in the C++ code below? - c++

I have this C++ code below to solve for a homework and after I ran it with Code::Blocks, it tells me that i=0, which means the expression s.compare(t)<0 is false. But, the way I see it, it's the other way around: (s<t, because AbcA < AAbcA). Can someone please explain it to me?
#include <iostream>
#include <string>
using namespace std;
int main(void) {
string s = "Abc", t = "A";
s=s+t;
t=t+s;
int i = s.compare(t)<0;
int j = s.length()<t.length();
cout<<i+j<<endl;
return 0;
}

According to the reference std::string::compare returns:
negative value if *this appears before the character sequence specified by the arguments, in lexicographical order
zero if both character sequences compare equivalent
positive value if *this appears after the character sequence specified by the arguments, in lexicographical order
Lexicographical comparison being defined as:
Lexicographical comparison is a operation with the following properties:
Two ranges are compared element by element.
The first mismatching element defines which range is lexicographically less or greater than the other.
If one range is a prefix of another, the shorter range is lexicographically less than the other.
If two ranges have equivalent elements and are of the same length, then the ranges are lexicographically equal.
An empty range is lexicographically less than any non-empty range.
Two empty ranges are lexicographically equal.
"AbcA" comes lexicographically after "AAbc", because the first nonequal character 'b' (ASCII 0x62) comes after 'A' (ASCII 0x41)

Related

What does > mean in comparing vectors [duplicate]

This question already has answers here:
What does the > operator do when comparing two C++ containers?
(1 answer)
Comparing 2 vectors using relational operators
(2 answers)
Closed 27 days ago.
I was learning on a website today and came upon this code
//code removed
vector<int> ans, path;
void dfs(int x, int y)
{
if (!x)
{
if (!ans.size() || ans>path) ans=path;
return;
}
//code removed
}
int main()
{
//code removed
}
In line 9, what does the ans>path mean? Both ans and path are vector<int> so I don't know what is being compared.
I originally thought ans>path mean ans.size()>path.size() but the code gave me a different result. I have searched online for any solutions but nothing came up. Any help is appreciated!
operator> performs lexicographical comparison. The comparison is described here:
Lexicographical comparison is an operation with the following properties:
Two ranges are compared element by element.
The first mismatching element defines which range is lexicographically less or greater than the other.
If one range is a prefix of another, the shorter range is lexicographically less than the other.
If two ranges have equivalent elements and are of the same length, then the ranges are lexicographically equal.
An empty range is lexicographically less than any non-empty range.
Two empty ranges are lexicographically equal.

How do the ">" and "<" operators work for string comparisons?

In the C++ textbook I'm reading (Programming, Principles and Practice using C++ by Bjarne Stroustrup), there are numerous instances of code snippets in which strings are compared as follows:
if (str1 > str2) and then some code.
Could someone please explain to me how "bigger than" and "less than" operators work in conjunction with strings declared as follows:
#include <string>
.
.
.
string str1 = "foo";
string str2 = "bar";
I've tried searching on Stack Overflow and on others for this answer, but to no avail.
The strings are compared lexicographically . The string in which an character is lexicographically greater than the corresponding character in other string will be considered as the greater string. This is known as lexicographical comparison.
The lexicographic or lexicographical order (also known
as lexical order, dictionary order, alphabetical order or
lexicographic(al) product) is a generalization of the way words are
alphabetically ordered based on the alphabetical order of their
component letters.
You can use the .compare() method as well to compare two strings . It will return the following values -
0 : They compare equal
Less than 0 : Either the value of the first character that does not
match is lower in the compared string, or all compared characters
match but the compared string is shorter.
more than 0 : Either the value of the first character that does not
match is greater in the compared string, or all compared characters
match but the compared string is longer.
On the contrary, the relational operators (like >, <, ==) will return only boolean values true of false. In the expression str1 < str2 , str1 will be smaller than str2 if first mismatched character in str1 is smaller than the corresponding character in str2. If all characters match, str1 will be less than str2 only if its length is shorter.
Relational operators on strings estabilish so-called lexicographical order. It's the same ordering as used in the dictionaries.
Here's the algorithm: to determine if a is less than b, you need to find the smallest i so that a[i] != b[i], and if (unsigned char)a[i] < (unsigned char)b[i], then a < b, otherwise a > b.
If there is no such i, then a == b.
If a is a prefix of b, then a < b (this follows from the algorithm above, if you consider the extra \0 at the end of a string to be a part of the string).

What is C++ comparing when comparing two different strings?

Code below when I check if K or Y is greater, what method is used to compare two different strings? number of bits?
#include <iostream>
#include <string>
using namespace std;
int main() {
string y = "can't";
string k = "solve";
if(k > y){
cout << "k is bigger";
}else {
cout << "y is bigger";
}
return 0;
}
k is bigger
string compare is a lexigraphical comparison:
All comparisons are done via the compare() member function (which
itself is defined in terms of Traits::compare()):
Two strings are equal if both the size of lhs and rhs are equal and
each character in lhs has equivalent character in rhs at the same
position.
The ordering comparisons are done lexicographically -- the comparison
is performed by a function equivalent to std::lexicographical_compare.
And this is how lexigraphical comparison works:
A lexicographical comparison is the kind of comparison generally
used to sort words alphabetically in dictionaries; It involves
comparing sequentially the elements that have the same position in
both ranges against each other until one element is not equivalent to
the other.
These relational operators are overloaded in the header file string.
All the relational operators used for string operations can be found in the link below.
http://www.cplusplus.com/reference/string/string/operators/
Hope this clears your doubt.

Find All Palindrome Substrings in a String by Rearranging Characters

For fun and practice, I have tried to solve the following problem (using C++): Given a string, return all the palindromes that can be obtained by rearranging its characters.
I've come up with an algorithm that doesn't work completely. Sometimes, it finds all the palindromes, but other times it finds some but not all.
It works by swapping each adjacent pair of characters N times, where N is the length of the input string. Here is the code:
std::vector<std::string> palindromeGen(std::string charactersSet) {
std::vector<std::string> pals;
for (const auto &c : charactersSet) {
for (auto i = 0, j = 1; i < charactersSet.length() - 1; ++i, ++j) {
std::swap(charactersSet[i], charactersSet[j]);
if (isPalandrome(charactersSet)) {
if (std::find(pals.begin(), pals.end(), charactersSet) == pals.end()) {
// if palindrome is unique
pals.push_back(charactersSet);
}
}
}
}
return pals;
}
What's the fault in this algorithm? I'm mostly concerned about the functionality of the algorithm, rather than the efficiency. Although I'll appreciate tips about efficiency as well. Thanks.
This probably fits a bit better in Code Review but here goes:
Logic Error
You change charactersSet while iterating over it, meaning that your iterator breaks. You need to make a copy of characterSet, and iterate over that.
Things to Change
Since pals holds only unique values, it should be a std::set instead of a std::vector. This will simplify some things. Also, your isPalandrome method spells palindrome wrong!
Alternative Approach
Since palindromes can only take a certain form, consider sorting the input string first, so that you can have a list of characters with an even number of occurrences, and a list of characters with an odd number. You can only have one character with an odd number of occurrences (and this only works for an odd length input). This should let you discard a bunch of possibilities. Then you can work through the different possible combinations of one half of the palindrome (since you can build one half from the other).
Here is another implementation that leverages std::next_permutation:
#include <string>
#include <algorithm>
#include <set>
std::set<std::string> palindromeGen(std::string charactersSet)
{
std::set<std::string> pals;
std::sort(charactersSet.begin(), charactersSet.end());
do
{
// check if the string is the same backwards as forwards
if ( isPalindrome(charactersSet))
pals.insert(charactersSet);
} while (std::next_permutation(charactersSet.begin(), charactersSet.end()));
return pals;
}
We first sort the original string. This is required for std::next_permutation to work correctly. A call to the isPalindrome function with a permutation of the string is done in a loop. Then if the string is a palindrome, it's stored in the set. The subsequent call to std::next_permutation just rearranges the string.
Here is a Live Example. Granted, it uses a reversed copy of the string as the "isPalindrome" function (probably not efficient), but you should get the idea.

issue relational operator in vector c++

today I wrote this code
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector <int> a (4,100);
vector <int> b (1,100);
cout<<(b<a);
}
as the reference says this is true only if if the contents of the b are lexicographically less than the contents of a, false otherwise, but in the output I obtain true, someone can explain me.
http://en.cppreference.com/w/cpp/container/vector/operator_cmp
From http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare,
Lexicographical comparison is a operation with the following properties:
. Two ranges are compared element by element.
. The first mismatching element defines which range is lexicographically less or greater than the other.
. If one range is a prefix of another, the shorter range is lexicographically less than the other.
. If two ranges have equivalent elements and are of the same length, then the ranges are lexicographically equal.
. An empty range is lexicographically less than any non-empty range.
. Two empty ranges are lexicographically equal.
In your case, the third clause applies.
The rules for std::lexicographical_compare which is invoked to handle
a < b
say that if one range is a prefix of another, the shorter range is lexicographically less than the other.
Here the range of a refers to the elements from a.begin() up to but excluding a.end() - in other words all the elements in a
Similarly, the range of b refers to the elements from b.begin() up to but excluding b.end() - in other words all the elements in b
b (which holds a single int of value 100) IS a prefix of a (which holds 4 integers of value 100) so b (the shorter range) is considered less than a, hence b < a is true.
See http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare for further details.