Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
How can I derive all possible matches of a regular expression
For example:
((a,b,c)o(m,v)p,b)
The strings generated from above expression would be:
aomp
bomp
comp
aovp
bovp
covp
b
Your steps are pretty straight forward though implementing them may take a bit of work:
Create a recursive function which extracts the string between the first set of parenthesis it comes to: https://stackoverflow.com/a/28863720/2642059
In the function split this strings on ',' into a vector<string> and return it: https://stackoverflow.com/a/28880605/2642059
Before returning test if it is necessary to recurse because of a nested parenthesis, one string must be added to the return for each possible combination returned from recursed functions
EDIT:
Say my input string was "(bl(ah,eck,le),yap)"
The first function would extract the string: "bl(ah,eck,le),yap"
Before returning it would search for nested parenthesis, this would cause it to recurse:
The second function would extract the string: "ah,eck,le"
Before returning it would search for nested parenthesis and find none
It would return an vector<string>: ["ah","eck","le"]
The first function would now contain: "bl["ah","eck","le"],yap"
It would not find anymore parenthesis to extract, so it would go to expanding all internal combinations: "["blah","bleck","blle"],yap"
It could now split the string and return: ["blah","bleck","blle","yap"]
The return from your first function is your result.
EDIT:
Glad you solved it I wrote up a two state machine to solve it as well so I figured I could post it here for your comparison:
const char* extractParenthesis(const char* start, const char* finish){
int count = 0;
return find_if(start, finish, [&](char i){
if (i == '('){
count++;
}
else if (i == ')'){
count--;
}
return count <= 0; });
}
vector<string> split(const char* start, const char* finish){
const char delimiters[] = ",(";
const char* it;
vector<string> result;
do{
for (it = find_first_of(start, finish, begin(delimiters), end(delimiters));
it != finish && *it == '(';
it = find_first_of(extractParenthesis(it, finish) + 1, finish, begin(delimiters), end(delimiters)));
auto&& temp = interpolate(start, it);
result.insert(result.end(), temp.begin(), temp.end());
start = ++it;
} while (it <= finish);
return result;
}
vector<string> interpolate(const char* start, const char* finish){
vector<string> result{ 1, string{ start, find(start, finish, '(') } };
for (auto it = start + result[0].size();
it != finish;
it = find(++start, finish, '('),
for_each(result.begin(), result.end(), [&](string& i){ i += string{ start, it }; })){
start = extractParenthesis(it, finish);
auto temp = split(next(it), start);
const auto size = result.size();
result.resize(size * temp.size());
for (int i = result.size() - 1; i >= 0; --i){
result[i] = result[i % size] + temp[i / size];
}
}
return result;
}
Depending upon your compiler you'll need to forward declare these since they call each other. This will also crash fantastically if the input string is malformed. And it can't handle escaped control characters.
Anyway you can call it like this:
const char test[] = "((a,b,c)o(m,v)p,b)";
auto foo = interpolate(begin(test), end(test));
for (auto& i : foo){
cout << i << endl;
}
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last year.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Improve this question
I want to know if there is a lambda or a clean short format in order to find if a single string contains only numeric values e.g 0 - 9 and the full stop character e.g . only.
For example string "123.45" should pass and strings "12jd", "12.4f" etc should fail.
This would be the code for your check, the constexpr stuff makes the function evaluatable at compile time. And the static_assert checks the output at compile time. Basically doing a unit test at compile time.
string_view is a nice wrapper for string literals and makes the string literal more easy to pass into the function and allows the use of a range based for loop to loop over all the characters.
#include <cassert>
#include <string_view>
constexpr bool is_positive_number(const std::string_view number_string)
{
std::size_t number_of_points{ 0ul };
// loop over all characters in string
for (const auto character : number_string)
{
// a '.' is valid but there should only be one
if (character == '.')
{
number_of_points++;
if (number_of_points > 1) return false;
}
else
{
// if character is not a '.' then it must be betweern '0'-'9'
if ((character < '0') || (character > '9')) return false;
}
}
return true;
}
int main()
{
static_assert(is_positive_number("1"));
static_assert(is_positive_number("12"));
static_assert(is_positive_number("123"));
static_assert(is_positive_number("1."));
static_assert(is_positive_number("1.2"));
static_assert(is_positive_number("12.34"));
static_assert(is_positive_number("007"));
static_assert(!is_positive_number("12.3.4"));
static_assert(!is_positive_number("-123"));
static_assert(!is_positive_number("abc"));
//auto lambda = [](const char* number_string)
auto lambda = [](const std::string& number_string)
{
return is_positive_number(number_string);
};
auto is_ok = lambda("123");
assert(is_ok);
return 0;
}
Another way would be to use the open-source compile-time regex library:
#include <ctre.hpp>
constexpr bool is_positive_number(std::string_view const s) noexcept {
return static_cast<bool>(ctre::match<R"(\d+(?:\.\d+)?)">(s));
}
int main() {
static_assert(is_positive_number("1.2"));
static_assert(!is_positive_number("1..2"));
static_assert(!is_positive_number("1e2"));
}
See Online
This can be done with a straightforward scan of the text:
bool is_valid(const std::string& str) {
int dots = 0;
for (char c: str) {
if (c == '.')
++dots;
if (1 < dots || !std::isdigit(c))
return false;
}
return true;
}
Using std::regex produces a two-liner if you dont count the static pattern
#include <string>
#include <regex>
#include <cassert>
bool is_positive_number( const std::string& str ) {
static std::regex rx("^(\\+?)(0|([1-9][0-9]*))(\\.[0-9]*)?$"); // Getting the regex object
std::smatch match;
return std::regex_match(str,match,rx);
}
int main()
{
assert(is_positive_number("1"));
assert(is_positive_number("12"));
assert(is_positive_number("123"));
assert(is_positive_number("1."));
assert(is_positive_number("1.2"));
assert(is_positive_number("12.34"));
assert(is_positive_number("+12.34"));
assert(!is_positive_number("007"));
assert(!is_positive_number("123.23.23"));
assert(!is_positive_number("-123"));
assert(!is_positive_number("abc"));
return 0;
}
I don't think there is a built-in function that does exactly what you were looking for. There is std::stod that converts a string into a double and tells you how many characters were converted successfully. However, there are many non-conforming numbers that will work, such as -1, NAN, 10E+3.
One way you could do is first remove all numbers(0~9), then check against "" and ".":
constexpr bool is_num(std::string str)
{
std::erase_if(str, [](unsigned char c){ return std::isdigit(c);};
return str == "" || str == ".";
}
Note erase_if is from C++20, for pre-C++20, you would do:
constexpr bool is_num(std::string str)
{
str.erase(std::remove_if(str.begin(), str.end(),
[](unsigned char c){ return std::isdigit(c); }), str.end());
return str == "" || str == ".";
}
demo
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Hi i'm trying to count the words in a sentence that is input by the user and this is the code i've written
void Count_Words( )
{
int count=0;
for (i = 0; inserted_text[i] != '\0';i++)
{
if (inserted_text[i] == ' ')
count++;
}
cout << "Word Count: " << count + 1;
}
I need to write this using recursion but i can't figure out how.
Also i need to count the redundant words in the sentence using recursion how do i do that?
I can't use mapping i need to use basic logic to do this. Is there anyway i can do this only with basic logic?
I agree with Hatted Rooster (this is not a good fit for recursion). I guess it serves a teaching purpose. So here is another option.
countWords() returns the number of words for the given substring until its end. To calculate the words for substring 0..n, we can calculate the words for substring 1..n first. And if character 0 is a space, add 1 to that.
int countWords(const char* str)
{
if(*str == '\0')
return 1; // last word
return countWords(str + 1) // how many words are in the remaining substring?
+ (*str == ' ' ? 1 : 0); // count if the beginning of the current substring is a space
}
int main()
{
std::string input = "test test test";
std::cout << countWords(input.c_str()); // 3
}
It doesn't really make sense to use recursion here but anyway, this would be one way to do it:
void Count_Words(int& i, const std::string& inserted_text, int& count)
{
if (inserted_text[i] == '\0')
{
++count; // last word
return;
}
if (inserted_text[i] == ' ')
++count;
Count_Words(++i, inserted_text, count); //recurse
}
int main()
{
std::string input = "test test test";
int i = 0;
int count = 0;
Count_Words(i, input, count);
std::cout << count; // 3
}
The thing to take away from this code is that references are a powerful tool to achieve correct recursion as seen in the function parameters.
As the other answer stated, this is really not a problem that should be resolved using recursion. What if there are thousands of words? That would exhaust the stack memory at some point.
In any event, here is one way to do this recursively:
#include <sstream>
#include <string>
#include <iostream>
void Count_Words(std::istringstream& strm, int& count)
{
std::string word;
if ( strm >> word ) // if there is a word, then increment the count
{
++count;
Count_Words(strm, count); // go to next word recursively
}
}
int Count_Words(std::string inserted_text)
{
// This is the setup for the recursive calls
std::istringstream strm(inserted_text);
int count = 0;
// start the recursion
Count_Words(strm, count);
return count;
}
int main()
{
std::string test = "This has four words";
std::cout << Count_Words(test);
}
Output:
4
I am trying to compare two std::strings, and decide if string A is the same as string B, but with the insertion or deletion of a single character.
Otherwise it returns false.
For example: "start" and "strt" or "ad" and "add"
Currently:
if(((sizeA - sizeB) != 1)
&& ((sizeB - sizeA) != 1))
{
return false;
}
if(sizeA < sizeB)
{
for(int i = 0; i < sizeA; ++i)
{
if(stringA[i] != stringB[i])
{
if(stringA.substr(i)
== stringB.substr(i + 1))
{
return true;
}
else return false;
}
}
} //with another loop that runs only if stringA is larger than stringB
This works flawlessly, but gprof tells me that this function is being bogged down.
I tried converting the for loop to use iterators to access the chars, but this doubled my run time.
Ive narrowed it down to my use of std::string.substr( ) because it is constructing new strings each time stringA and stringB differ in size by 1.
When the first character differs, I need a more efficient way to check if I were to delete that character, would the two strings then be equal?
It seems, once it is known whether there is a one character difference the comparison can be done more effective with a single pass over the string: find the location of the difference, skip the character, and see if the tail is the same. To that end it is obviously necessary to know which one is the smaller string but that's trivial to determine:
bool oneCharDiff(std::string const& shorter, std::string const& longer) {
if (shorter.size() + 1u != longer.size() {
return false;
}
typedef std::string::const_iterator const_iterator;
std::pair<const_iterator, const_iterator> p
= std::mismatch(shorter.begin(), shorter.end(), longer.begin());
return std::equal(p.first, shorter.end(), p.second + 1);
}
bool atMostOneCharDiff(std::string const& s0, std::string const& s1) {
if (s0.size() < s1.size()) {
return oneCharDiff(s0, s1);
else if (s1.size() < s0.size()) {
return oneCharDiff(s1, s0);
}
else {
return s0 == s1;
}
}
Try:
if (stringA.compare(i, stringA.npos, stringB, i+1, stringB.npos) == 0) {
/* the strings are equal */
}
In this write-up, that's version (3) of std::basic_string::compare.
If your compiler supports it it may be worth checking out the new ISO/IEC TS 19568:xxxx Technical Specification string_view class.
It provides an immutable view of a string through references without copying the string itself so it promises to be much more efficient when dealing with substrings.
#include <experimental/string_view>
using std::experimental::string_view;
bool func(string_view svA, string_view svB)
{
// ... stuff
if(svA.size() < svB.size())
{
for(int i = 0; i < svA.size(); ++i)
{
if(svA[i] != svB[i])
{
if(svA.substr(i)
== svB.substr(i + 1))
{
return true;
}
else return false;
}
}
}
// ... stuff
return false;
}
As you can see it works pretty much like a drop-in replacement for std::string (or const char* etc...). Simply pass your normal std::string objects as arguments to the function and the string_view parameters will initialize from the passed in strings.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I was looking for replacing a character in a string with a character in another string comparing to another string.
Well, hard to describe this, a code would be better :
std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
std::string keyboard = "AZERTYUIOPQSDFGHJKLMWXCVBNazertyuiopqsdfghjklmwxcvbn";
std::string change(std::string str)
{
for (short i = 0; i < alphabet.length(); i++)
{
std::cout << str[i] << std::endl;
}
std::cout << str << std::endl;
system("PAUSE");
return str;
}
Well, I don't think it is understandable, so what I try to do is :
Find (maybe Find() ?) the letter in str and get the i-variable in alphabet.
With the i-variable want to get the pos and then get the letter in the keyboard string.
Hope you understand what I mean, and thank you.
I though about replace(), find() and swap(), but didn't work, I maybe did something wrong.
Thank you in advance !
EDIT : Well, I was sure you won't understand anything, imagine str = "Hello", I want to replace H per Y (alphabet = H -> keyboard = I)? (alphabet get the position of the H in the alphabet string, we memorise this position in i, and we keyboard[i]), this is what I want to do.
I propose
template <typename InputIterator,
typename BidirIterator,
typename ForwardIterator>
InputIterator substitute( InputIterator first, InputIterator last,
BidirIterator key_first, BidirIterator key_last,
ForwardIterator val_first )
{
for (; first != last; ++first)
{
auto&& ref = *first;
auto i = std::lower_bound( key_first, key_last, ref );
if (i == key_last || *i != ref)
return first;
ref = *std::next(val_first, std::distance(key_first, i));
}
return last;
}
This assumes that [key_first, key_last) is sorted and that val_first refers to a range that is at least as long as [key_first, key_last).
Demo.
The idea is that we iterate through all elements of a range using iterators whose type is to be determined - i.e. we can use both char const[]s and std::vector<char>s. We pick the current element and use a binary search to find that element within the key set. Then we use the offset to access the substitution counterpart in the value set, and assign that to our original element.
We use lower_bound to do the binary search. It doesn't itself constitute one, so we have to apply some checks to the return value to ensure the iterator refers to the correct value. If we couldn't find the key then the iterator to the first non-working element is returned. (That can be the past-the-end iterator.)
The avove is a general method that works for arbitrary key/value sets: For alphabetic shuffling there are (platform dependent) methods using lookup tables. Rustically this could look like this:
template <typename InputIterator>
void substitute( InputIterator first, InputIterator last,
char const* values )
{
char lookup[UCHAR_MAX+1];
for (int c = 0; c != sizeof lookup; ++c)
if (std::isupper(c))
lookup[c] = values[c - 'A'];
else if (std::islower(c))
lookup[c] = values[c - 'a' + 26];
else
lookup[c] = c;
// Further adjustments to the table can be made here
std::transform( first, last, first,
[&] (unsigned char c) {return lookup[c];} );
}
Demo. It depends on stuff that normal character sets should easily suffice. The table can also be created elsewhere and passed to transform via the unwrapped one-liner. This is especially efficient for large string transformations as no branching is necessary in the implicit loop in transform.
So, you want to replace every char in your string with a char from keyboard string using original char's position in alphabet?
I would consider using a map alphabet char to keyboard char. Then iterate through string and replace its characters.
#include <string>
#include <algorithm>
#include <map>
int main(int argc, char* argv[])
{
std::map<char, char> alphabetToKeyboard;
alphabetToKeyboard['A'] = 'A';
alphabetToKeyboard['B'] = 'Z';
alphabetToKeyboard['C'] = 'E';
std::string str = "ABC";
std::transform(str.begin(), str.end(), str.begin(), [&alphabetToKeyboard](char c) {
return alphabetToKeyboard[c];
});
return 0;
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Write a recursive function that reverses the input
Recently, I've been reading the book C++ For Everyone and I've been having trouble putting together a recursive function (Confusing to think about...)
The question was: Write a recursive function string reverse(string str) that returns the reverse of str
This is what I have so far:
string reverse(string str)
{
string word = "";
if (str.length() <= 1)
{
return str;
}
else
{
string str_copy = str;
int n = str_copy.length() - 1;
string last_letter = str_copy.substr(n, 1);
str_copy = str_copy.substr(0, n);
word += reverse(str_copy);
return last_letter;
}
return word;
}
My problems now is:
If I enter wolf, it returns f
If I change return last_letter to return word, I get w
If I change to return str_copy, I get wol
You need to return the combination of the the last character (last_letter) and the reversal of the rest of the string, but you don't do that in any of your attempts. You only ever return one part or the other.
string reverse(string str)
{
int len = str.length();
if (len <= 1)
{
return str;
}
else
{
return str.substr(len-1, 1) + reverse( str.substr(0, len-1) );
}
}
This would do the work:
Delete return last_letter;
Change `
word += reverse(str_copy);
to
word = last_letter+reverse(str_copy);
I'll leave the thinking to you!
Best.