1

I am moving from Python to C++ and I am not well versed with the latter.

I have a string s, which contains exactly one character "a" and one character "b" while the other characters are redundant. I want to know whether "a" occurs first or "b" does. In Python, I would do it something like this

s = "??a????b"
if s.find("a") < s.find("b"):
    print("a")
else:
    print("b")

Also, for C++, I tried this:

#include<bits/stdc++.h>

using namespace as std;

int main(){

    string s;
    cin >> s;
    bool isTrue = 1;
    for(int i =0; i < s.size(); i++){

        if(s[i] == "a"){break;}
        else if(s[i] == "b"){isTrue = 0; break;}

    }
    cout << (isTrue ? "a" : "b") << endl;

}

But it gives an error pointing to the comparison between s[i] and "a" saying integer cannot be compared with a pointer. Kindly explain what is happenning.

I searched for find() function in c++ but things got out of bounds for me very soon. So kindly try explaining me using as less jargon and advanced libraries as possible how to solve the problem and what was wrong in my code.

P.S.: I am learning competitive programming so please don't be shocked to see that include<bits/stdc++.h> up there.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
gabrupro
  • 39
  • 4
  • In C++, a string is a sequence of characters, and a single character and a one-character string are not the same thing. The former is spelled `'a'` and the latter `"b"`. – molbdnilo Jan 19 '21 at 08:09
  • 4
    Unrelated, but helpful reading: [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) and [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) Put them together and you can get into big trouble in a very short amount of time. – user4581301 Jan 19 '21 at 08:10
  • 1
    Even if you're learning "_competitive programming_" you shouldn't be using ``. Learn how to use the proper headers and you'll be a competitor in the real world instead. – Ted Lyngmo Jan 19 '21 at 08:22

7 Answers7

4

You can use the std::string.find() member function with a single char argument – the version (4) overload shown here.

#include <iostream> // NEVER use the <bits/stdc++.h> header file!
#include <string>
using std::cout;    // Also not best practice to use "using namespace std"
using std::cin;
using std::endl;
using std::string;

int main()
{
    string s;
    cin >> s;
    bool isTrue = s.find('a') < s.find('b');
    cout << (isTrue ? "a" : "b") << endl;
    return 0;
}

Also, you can use the following 'shorter' form for multiple using statements, if you are using the C++17 (or later) Standard:

using std::cout, std::cin, std::endl;
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
3

The comparator should be s[i] == 'a' - single quotes. The double quotes denote a string:

"a" - string (= array of chars)
'a' - char

In expression like s[i] == "a" the char s[i] is compared to the C-string "a" (which is of type const char[2] and contains {'a', '\0'}) and this is an error, because comparing single characters to array of characters is not defined.

std::string also has a find method which searches for substring, so you could do something like:

if (s.find("a") < s.find("b")) ...

If 'a' or 'b' are not present then find would return strind::npos and would need to be checked first, for example:

auto pos_a = s.find("a");
auto pos_b = s.find("b");

if (pos_a != string::npos && pos_b != string::npos)
  return pos_a < pos_b;
else 
  throw std::runtime_error("a or b not present");
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
StPiere
  • 4,113
  • 15
  • 24
  • 1
    Not important here, but `"a"` is a constant array of characters. A bit of a nasty surprise when it does become important, so forewarned is forearmed. – user4581301 Jan 19 '21 at 08:12
  • 1
    of course. probably throwing would make more sense, but it depends on requirements. updated. – StPiere Jan 19 '21 at 08:35
2

You could use the find method of std::string:

(more up2date reference) https://en.cppreference.com/w/cpp/string/basic_string/find

or

http://www.cplusplus.com/reference/string/string/find/

size_t posa = s.find('a');
size_t posb = s.find('b');

if (posa == string::npos)
{
    cout << "a not found" << endl;
}
else if (posb == string::npos)
{
    cout << "b not found" << endl;
}
else if (posa < posb)
{
    cout << "a is before b" << endl;
}
INS
  • 10,594
  • 7
  • 58
  • 89
1

basically string is like array of character, so if you want to compare a particular index character of string, you can only compare it to character type, for representing character type use like

char ch = 'a'; //character
string s = "many" //array of characters , i.e 'm', 'a', 'n', 'y'

so if you want to compare a particular index value of string then you compare like this

if(s[0] == 'a') {
    //your logic here
}
mss
  • 1,423
  • 2
  • 9
  • 18
1

Seems like the logic of your Python version is clean enough, so you can get a first cut by just fixing the syntax, but keeping the logic the same:

std::string s = "??a????b";
if (s.find('a') < s.find('b'))
    std::cout << "a";
else
    std::cout << "b";

From there, a lot depends on the sort of situation in which you're using this code. If you're really sure the input will always be "good" (will contain both an a and a b, in this case), that may be perfectly good, finished code.

On the other hand, C++ tends to be used in larger, longer-lived projects than Python. Especially if you're trying to learn C++ with the idea of using it professionally, you may want to start putting a bit more effort into checking inputs than you're accustomed to doing in Python. Hard to guess about that though.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0
#include <iostream>
#include <string>

int main() {
    std::string str = "";
    std::cin >> str;
    bool found = false;

    for (auto s : str) {
        if (s == 'a') {
            std::cout << 'a' << "\n";
            found = true;
            break;
        }

        if (s == 'b') {
            std::cout << 'b' << "\n";
            found = true;
            break;
        }
    }
    !found && std::cout << "Not found!" << "\n";
}

Range-based for loop
auto
std::string
iostream

steven7mwesigwa
  • 5,701
  • 3
  • 20
  • 34
0

You can use s.find('a') < s.find('b') just like in python, but consider a case where the string is very large and a is found early in the string and b is somewhere at the end. That test would still have to scan the whole string to find that b.

Another option is to use the standard algorithm std::find_first_of which scans your string and returns as soon as either a or b is found and it's therefore cheaper in terms of CPU cycles. Also, the name of the function makes it clear to everyone reading the code what you are doing.

#include <algorithm>
#include <iostream>
#include <string>

int main() {
    std::string str = "??a????b";      // your input string
    std::string letters_to_find("ab"); // the letters

    // get an iterator to the first "a" or "b"
    auto it = std::find_first_of(str.begin(), str.end(),
                                 letters_to_find.begin(), letters_to_find.end());

    if(it != str.end())            // safety check if neither "a" nor "b" is found
        std::cout << *it << '\n';  // print "a" or "b"
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108