How to pass substring by reference?

I call a function recursively that passes as an argument a substring that always starts from the beginning of the current line to the position. If I used C, I could pass a pointer to the first position of the string, and then the required length. However, I would like to achieve the same result using the string class. Is it possible? If I use const , is the compiler smart enough to do the optimization myself? Even better, is there a way to check if the compiler really makes a copy of the argument or passes a link?

My question was motivated by writing the following code that passes tests on the Alphacode problem on poj as soon as someone uses atoi instead of atof .

 #include <iostream> #include <algorithm> #include <map> #include <vector> #include <string> using namespace std; map<string, int> cache; bool valid_character_number(string a) { return 0 < stoi(a.substr(a.size() - 2, 2)) && stoi(a.substr(a.size() - 2, 2)) <= 26; } bool zero_last_digit(string a) { return a[a.size() - 1] == '0'; } bool zero_before_last_digit(string a) { return a[a.size() - 2] == '0'; } int decodings(string a) { if (a.size() == 0) return 1; if (a.size() == 1) { if (zero_last_digit(a)) return 0; else return 1; } if (cache.find(a) != cache.end()) return cache[a]; if (zero_last_digit(a) && valid_character_number(a)) return cache[a] = decodings(a.substr(0, a.size() - 2)); else if (valid_character_number(a) && !zero_before_last_digit(a)) return cache[a] = decodings(a.substr(0, a.size() - 1)) + decodings(a.substr(0, a.size() - 2)); else return cache[a] = decodings(a.substr(0, a.size() - 1)); } int main() { string input; while (true) { cin >> input; if (input.size() == 1 && stoi(input) == 0) return 0; cout << decodings(input) << endl; } return 0; } 
+6
source share
2 answers

You cannot use std::string for this purpose, but you can easily create your own class that contains a pair of iterators (start and end) to another line or C-style char * and size. With C ++ 11 (since you checked it), you can even create User Defined Literal syntax to create strings of your new type.

+6
source

You can use your own wrapper class, like this one:

 struct RefString { RefString(const std::string & s, int i, int l) : s(s), i(i), l(l) {} const char & operator [] (int x) const { return s[i+x]; } size_t length() const { return l; } bool operator < (const RefString & s2) const { return s.compare(i, l, s2.s, s2.i, s2.l) < 0; } private: const std::string & s; int i; int l; }; std::ostream & operator << (std::ostream &stream, const RefString & ms) { for (int i = 0; i < ms.length(); i++) stream << ms[i]; return stream; } 

And use it like this, for example, to create a set unique substrings:

 std::string s = "hello"; std::set<RefString> st; for (int i = 0; i < s.length(); i++) for (int j = i; j < s.length(); j++) st.insert(RefString(s, i, j-i+1)); 
+2
source

All Articles