#include <iostream>
using namespace std;
void palindrome(char *s){
if (s[1] == 0)
{
return;
}
cout << s[0];
palindrome(++s);
cout << s[0];
}
int main(){
char s[30]="foobar";
palindrome(s);
cout << endl;
}
I have to create a recursive function that turns any cstring into a palindrome. This is a homework question and the only code I can modify is inside the palindrome function. This code almost works. The problem is it returns "foobaraboo" and leaves off the last letter. Any tips to point me in the right direction? I've played around with the code for quite a while and can't seem to figure out how to change it so the last character of the palindrome shows up.
You have two bugs in your logic. The first one:
if (s[1] == 0)
{
return;
}
This should be:
if (*s == 0)
{
return;
}
if your entire input is the string "x", your expected result is the palindrom "xx", but this bug will result in an empty string getting printed.
You also have a more fundamental bug:
cout << s[0];
palindrome(++s);
cout << s[0];
Your intent here is to print the current character, recursively print the rest of the palindrome string, and then re-print the same character.
But because of the ++s, you're printing the wrong character, the second time around.
This should be:
cout << s[0];
palindrome(s+1);
cout << s[0];
EDIT: a question has been raised whether you want the last character printed twice. If not, then this should be:
cout << s[0];
if (s[1])
{
palindrome(s+1);
cout << s[0];
}
Here you are
#include <iostream>
void palindrome( const char *s )
{
if ( s[0] )
{
std::cout << s[0];
if ( s[1] )
{
palindrome( s + 1 );
std::cout << s[0];
}
}
}
int main()
{
const char *s = "foobar";
palindrome( s );
std::cout << std::endl;
}
The program output is
foobaraboof
Related
#include <iostream>
#include <string>
using namespace std;
void ReverseString(string &S, int size)
{
static int start = 0;
if (start == size - 1 || start == size)
{
return;
}
else
{
swap(S[start++], S[size - 1]);
ReverseString(S, size - 1);
}
}
int main()
{
cout << "enter a string to reverse" << endl;
string s;
getline(cin, s);
cout << "Before Reversing" << endl;
cout << s << endl;
ReverseString(s, s.size());
cout << "After Reversing" << endl;
cout << s << endl;
return 0;
}
I am trying to nail recursions as much as i can,and i was trying to reverse a string using recursion
i didn't know how to do it at first,tried many different ways to do it,but i saw code samples on string reversing,but none of it made sense to me,so i made my own one,but not quite sure of it,i'm just asking for opinion,is it clean and functional??
Thank You
Using a function local static variable in a recursive function is a bad idea. Recursive functions should get all their state as input arguments.
Here's a simplified version that divides the logic into two functions.
void ReverseString(string &S, int start, int end)
{
if ( start < end )
{
swap(S[start], S[end - 1]);
ReverseString(S, start+1, end - 1);
}
}
void ReverseString(string &S)
{
ReverseString(S, 0, S.size());
}
Most of the time, higher level functions would only call the second function. The first function can be called from a higher level function if there is a need to reverse only a subset of a string.
Here's a sample program
#include <iostream>
#include <string>
using namespace std;
void ReverseString(string &S, int start, int end)
{
if ( start < end )
{
swap(S[start], S[end - 1]);
ReverseString(S, start+1, end - 1);
}
}
void ReverseString(string &S)
{
ReverseString(S, 0, S.size());
}
int main()
{
string s = "The string to reverse" ;
cout << "Before Reversing" << endl;
cout << s << endl;
ReverseString(s);
cout << "After Reversing" << endl;
cout << s << endl;
ReverseString(s, 0, 7);
cout << "After Reversing a subset" << endl;
cout << s << endl;
return 0;
}
and its output
Before Reversing
The string to reverse
After Reversing
esrever ot gnirts ehT
After Reversing a subset
reverse ot gnirts ehT
See it working at https://ideone.com/9nMlsP.
is it ... functional??
If by "functional" you mean "does it work", then you tell me.
If you mean "functional" as in "functional" programming style, then no it isn't. In functional style, you don't modify arguments in place, but instead return a new value. Also relying on global state (i.e. static objects) is very anti-functional.
Here is an example:
std::string
ReverseString(std::string_view sv)
{
if (sv.empty())
return "";
std::string_view x = sv.substr(0, 1)
std::string_view xs = sv.substr(1);
return ReverseString(xs) + x;
}
// usage
s = ReverseString(s);
In future, if Pattern matching was introduced to the language, then it could potentially be written like this:
std::string
ReverseString(std::string_view sv)
{
inspect(sv) {
"": return "";
[x:xs]: return ReverseString(xs) + x;
}
}
However, the current proposal does not suggest introducing support for matching ranges like this, so this is highly theoretical.
Local static variables are dangerous. Since their state will remain between function calls. In my approach i used slen as the length of a string and the currentIndex as the last swapped index on the string. Since it is enough to swap till the middle of the string, finish case is when (currentIndex == slen/2).
I also added some test cases as an example.(even length, odd length, zero case and palindrome)
#include <iostream>
#include <string>
using namespace std;
void ReverseString(string &S, int currentIndex, int slen)
{
if (slen / 2 == currentIndex) return;
swap(S[currentIndex], S[slen - 1 - currentIndex]);
currentIndex++;
ReverseString(S, currentIndex, slen);
}
void testReverseString() {
string s = "";
ReverseString(s, 0, s.length());
assert(s == "");
s = "ahmet";
ReverseString(s, 0, s.length());
assert(s == "temha");
s = "ahaha";
ReverseString(s, 0, s.length());
assert(s == "ahaha");
s = "haha";
ReverseString(s, 0, s.length());
assert(s == "ahah");
}
int main()
{
testReverseString();
return 0;
}
Your function with a static variable can be called only once because after its recursive calls the static variable start will not be equal to 0 as it is required. So the function is not "functional".
Here is a demonstrative program that shows how the function can be written with using a static variable and without using a static variable.
#include <iostream>
#include <string>
#include <utility>
void ReverseString1( std::string &s )
{
static std::string::size_type i = 0;
if ( not ( s.size() - 2 * i < 2 ) )
{
std::swap( s[i], s[s.size() - i - 1] );
++i;
ReverseString1( s );
--i;
}
}
void ReverseString2( std::string &s, std::string::size_type pos = 0 )
{
if ( not ( s.size() - 2 * pos < 2 ) )
{
std::swap( s[pos], s[s.size() - pos - 1] );
ReverseString2( s, pos + 1 );
}
}
int main()
{
std::string s( "Hello World!" );
std::cout << s << '\n';
ReverseString1( s );
std::cout << s << '\n';
ReverseString2( s );
std::cout << s << '\n';
return 0;
}
The program output is
Hello World!
!dlroW olleH
Hello World!
Anyone can reverse a string one char at a time, but much cooler is to reverse each third of the string and swap the outer thirds. This cuts stack depth as well as sowing confusion amongst the competition. Note that max stack depth of recursion per character is N, whereas this is cube root of N.
#include <iostream>
#include <string>
using namespace std;
void ReverseRegion(string &s, int start, int sz)
{
// regions < 2 need no action
if (sz == 2) {
char tmp = s[start];
s[start] = s[start+1];
s[start+1] = tmp;
} else if (sz > 2) {
int s3 = sz/3;
ReverseRegion(s, start, s3);
string tmp = s.substr(0,start) + s.substr(start+sz-s3,s3) + s.substr(start+s3, sz-2*s3) + s.substr(start,s3) + s.substr(start+sz);
// cout << "do: " << tmp << "\n";
s = tmp;
ReverseRegion(s, start+s3, sz-2*s3);
ReverseRegion(s, start, s3);
}
}
void ReverseString(string &S)
{
ReverseRegion(S, 0, S.size());
}
int main()
{
cout << "enter a string to reverse" << endl;
string s;
getline(cin, s);
cout << "Before Reversing" << endl;
cout << s << endl;
ReverseString(s);
cout << "After Reversing" << endl;
cout << s << endl;
return 0;
}
I am trying to use pointers to recursively lowercase all capital letters
using the C++ programming language. Below is the code snippet:
// Example program
#include <iostream>
#include <string>
using namespace std;
void all_lower(char* input) {
if ( *input ) {
cout << input << endl;
return;
}
if ( *input >= 'A' && *input <= 'Z') {
*input += 32; // convert capital letter to lowercase
}
cout << *input << endl;
all_lower(++input); // simply move to next char in array
}
int main() {
char test[] = "Test";
all_lower(test);
return 0;
}
The output ends up being:
"Test"
even though I tried to increase the ASCII code value of the element by 32.
You are exiting the function on the first non-null character detected, which is 'T', and then you output the entire array before exiting, so you are seeing the original unmodified input. You are not recursing through the array at all. You need to recurse through the array until you reach the null terminator.
You need to change this:
if ( *input ) {
cout << input << endl;
return;
}
To this instead:
if ( *input == 0 ) {
return;
}
Then the function will work as expected.
That being said, I suggest you remove the cout statements from the function, and do a single cout in main() after the function has exited. This will speed up the function, and prove that the content of the test[] array is actually being modified:
#include <iostream>
using namespace std;
void all_lower(char* input)
{
if ( *input == 0 ) {
return;
}
if ( *input >= 'A' && *input <= 'Z') {
*input += 32; // convert capital letter to lowercase
}
all_lower(++input); // simply move to next char in array
}
int main()
{
char test[] = "TEST";
cout << "Before: " << test << endl;
all_lower(test);
cout << "After: " << test << endl;
return 0;
}
Live Demo
And, since you are using C++, consider removing all_lower() altogether and use the STL std::transform() algorithm instead:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
char test[] = "TEST";
cout << "Before: " << test << endl;
transform(test, test+4, test, [](char ch){ return tolower(ch); });
cout << "After: " << test << endl;
return 0;
}
Live Demo
Something short and easy:
#include <iostream>
#include <string>
using namespace std;
void all_lower(const char* input) {
if (!*input) {
std::cout << std::endl;
return;
}
std::cout << (char)(std::isalpha(*input) ? tolower(*input) : *input);
all_lower(++input); // simply move to next char in array
}
int main() {
all_lower("Test");
return 0;
}
I'm stuck on a particular problem. I'm trying to take a string, and reverse the character cases in the string.
For Example: "HaVinG FuN" should flip to "hAvINg fUn."
I think it has something to do with my loop or my If/Else statements. What am I missing? All capitalized characters come out capitalized still. All lower case characters also come out capitalized as well... My other two functions are behaving correctly, but not my reverseFunct function... FYI I've omitted the other functions to try to cut-down on clutter and focus on my problem.
#include "stdafx.h"
#include <string>
#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;
// Function Prototypes
void upperFunct(char *);
void lowerFunct(char *);
void reverseFunct(char *);
int main()
{
cout << "Enter a string: " << endl;
char ltrs [300];
cin.getline(ltrs, 300);
char *ptr = nullptr;
ptr = ltrs;
upperFunct(ptr);
lowerFunct(ptr);
reverseFunct(ptr);
return 0;
}
//----------------------------------//
void upperFunct(char *ltrptr)
{
int count = 0;
while (ltrptr[count] != '\0')
{
ltrptr[count] = toupper(ltrptr[count]);
count++;
}
{
cout << "---> toupper function: " << ltrptr << endl;
}
}
//------------------------------------//
void lowerFunct(char *ltrptr)
{
int count = 0;
while (ltrptr[count] != '\0')
{
ltrptr[count] = tolower(ltrptr[count]);
count++;
}
cout << "---> tolower function: " << ltrptr << endl;
}
//------------------------------------//
void reverseFunct(char *ltrptr) // <-----NOT REVERSING CHARACTERS
{
int count = 0;
while (ltrptr[count] != '\0')
{
if (isupper(ltrptr[count]))
{
ltrptr[count] = tolower(ltrptr[count]);
}
else
{
ltrptr[count] = toupper(ltrptr[count]);
}
count++;
}
cout << "---> reverse function: " << ltrptr << endl;
}
Your check for lowercase letters reads as
else if (islower(ltrptr[count]));
Notice the extra semicolon.
This semicolon terminates the if statement, and thus the succeeding conversion to uppercase is not a then-clause to this if statement but rather is executed unconditionally on every character.
Change like this
// Function Prototypes "HaVinG FuN" should flip to "hAvINg fUn."
void reverseFunct(char *);
int main()
{
//cout << "Enter a string: " << endl;
char ltrs[300] = "HaVinG FuN";
//cin.getline(ltrs, 300);
char *ptr = nullptr;
ptr = ltrs;
reverseFunct(ptr);
ptr = nullptr;
return 0;
}
void reverseFunct(char *ltrptr) // <-----NOT REVERSING CHARACTERS
{
int count = 0;
while (ltrptr[count] != '\0')
{
if (isupper(ltrptr[count]))
{
ltrptr[count] = tolower(ltrptr[count]);
}
else
{
ltrptr[count] = toupper(ltrptr[count]);
}
count++;
}
cout << "---> reverse function: " << ltrptr << endl;
}
You're writing C code. Here's a C++ way to do it:
#include <string>
#include <algorithm>
char reverse_case_char(char c) {
const auto uc = static_cast<unsigned char>(c); // Sic.
return ::isupper(uc)? ::tolower(uc): ::toupper(uc);
}
void reverse_case(std::string& str) {
std::transform(str.begin(), str.end(), str.begin(), reverse_case_char);
}
#include <cassert>
int main()
{
std::string fun = "HaVinG FuN";
reverse_case(fun);
assert(fun == "hAvINg fUn");
return 0;
}
Others have already pointed out the mistake in your code so no need to repeat that. Instead this answer will give some alternative ways of implementing the task.
Your code is more C-style than C++ style. C++ has a number of functions/features that will allow you to write this in much shorter forms.
char ltrs[300] = "HaVinG FuN";
for (auto& ch : ltrs) ch = islower(ch) ? toupper(ch) : tolower(ch);
std::cout << ltrs << std::endl;
or
char ltrs[300] = "HaVinG FuN";
std::for_each(ltrs, ltrs + strlen(ltrs), [](char& ch)
{ ch = islower(ch) ? toupper(ch) : tolower(ch); });
std::cout << ltrs << std::endl;
or using the std::string
std::string str("HaVinG FuN");
for (auto& ch : str) ch = islower(ch) ? toupper(ch) : tolower(ch);
std::cout << str << std::endl;
Using these C++ functions/features makes the program shorter, easier to understand and the risk of bugs is lower.
Thanks for the help!!! I ended up figuring out my answer, while being able to maintain my less-than elegant code that is fitting with my class. Bipll ended up giving me what I was after, something to think about in terms that my original array was being modified each time.
I realize that my solution is sloppy and not appropriate for a work environment, but it is in-line with my homework assignment, as our teacher is encouraging us to learn C++ from the ground-up, not getting too much direct answers from places like SO. So I'm glad I learned a bit from here, as well as an indirect way to help me see my issues.
I ended up making a copy of my original array, and just passing that copy to my last reversing function. I was able to use the original array for the first 2 functions because the 1st function capitalized each character in the array, while the 2nd made them all lowercase. The 3rd function, the reverse, therefore had to have access to the original array, but in the 3rd order. The easiest way for a noob like me, given where I am in the class, was to make a copy of the 1st array and use that for the 3rd function.
//Snippet of code I needed
int main()
{
int index = 0;
cout << "Enter a string: " << endl;
const int Size = 300;
char ltrs[Size];
cin.getline(ltrs, Size);
char arrayCopy[Size];
char *ptr = nullptr;
char *ptr2 = nullptr;
ptr = ltrs;
//Copy of ltrs Array
//----------------------------------//
while (ptr[index] != '\0') //
{ //
arrayCopy[index] = ptr[index]; //
index++; //
} //
arrayCopy[index] = '\0'; //
//
ptr2 = arrayCopy; //
//----------------------------------//
return 0;
}
// Function to Reverse
void reverseFunct(char *ltrptr)
{
int count = 0;
while (ltrptr[count] != '\0')
{
if (isupper(ltrptr[count]))
{
ltrptr[count] = tolower(ltrptr[count]);
}
else
{
ltrptr[count] = toupper(ltrptr[count]);
}
count++;
}
cout << "---> reverse function: " << ltrptr << endl;
}
I'm struggling with this C++ compiler error to get my regex_match() function to work. The code:
#include <iostream>
#include <string>
#include <regex>
using namespace std;
struct Person {
Person(string name, int age)
: n{name}, a{age}
{
regex r("^([!:*&%##^\\[\\]\"\'])+"); // :*[]"'&^%##!
for(char test : n) {
cout << "Character: " << test;
if(regex_match(test, r)) {
cout << endl << "Error: wrong character!" << endl;
}
}
}
string n;
int a;
};
int main() {
Person Goofy("Goofy",11);
return 0;
}
I want to check if n contains at least one of the characters I wrote in the regex r().
Btw, for people learning regex I've found the great website: https://regex101.com.
Any sugestions? Thx!!
test is a character. There's no overload of std::regex_match for a character.
I'm not sure if you want to check every character against the list of characters or just the first one. If it's them all, you can use std::any_of:
char const constexpr m[] = R"(:*[]"'&^%##!)";
for(char test : n) {
if(any_of(begin(m), end(m), [test](char c){ return c == test; })) {
cout << endl << "Error: wrong character!" << endl;
}
}
Based on the additional comments I think I understand what you wanted: check if the string n contained any of the "illegal" characters. For this task std::regex_search is better suited:
regex r{R"([:*\[\]"'&^%##!])"};
if(regex_search(n, r)){
cout << endl << "Error: wrong character!" << endl;
}
I want to make a recursive function that determines if a string's characters all consist of alphabets or not. I just can't figure it out. Here's what I've done so far but it doesn't work properly.
bool isAlphabetic(string s){
const char *c = s.c_str();
if ((!isalpha(c[0]))||(!isalpha(c[s.size()])))
{
return false;
}
else if (isalpha(c[0]))
{
isAlphabetic(c+1);
return true;
}
}
can anyone suggest a correct way?
Leaving aside the many partial strings you'll create (consider passing in just the string and a starting index instead), the isalpha(c[s.size()]) check will always fail, since that's the \0 at the end of the string. You're also ignoring the result of the recursive calls.
bool isAlphabetic(string s){
if (s.size() < 1)
return true; // empty string contains no non-alphas
const char *c = s.c_str();
if (!isalpha(c[0]))
{
return false; // found a non-alpha, we're done.
}
else
{
return isAlphabetic(c+1); // good so far, try the rest of the string
}
}
Building on Paul's answer, here is a fixed implementation that won't copy any portion of the string. It accomplishes this by passing a reference to the string object and an index to the character to check; recursion simply adds 1 to this index to check the next character, and so on until the end of the string is found.
I have removed your call to c_str() since it isn't needed. string can be directly indexed.
bool isAlphabetic(string const & s, int startIndex = 0) {
// Terminating case: End of string reached. This means success.
if (startIndex == s.size()) {
return true;
}
// Failure case: Found a non-alphabetic character.
if (!isalpha(s[startIndex])) {
return false;
}
// Recursive case: This character is alphabetic, so check the rest of the string.
return isAlphabetic(s, startIndex + 1);
}
Note that the empty string is considered alphabetic by this function. You can change this by changing return true to return !s.empty().
Here a working example:
#include <iostream>
#include <string>
using namespace std;
bool isAlphabetic(string s)
{
if( s.empty() )
{
return false;
}
cout << "checking: " << s[0] << endl;
if( isalpha(s[0]) )
{
return true;
}
return isAlphabetic(&s[0]+1);
}
int main()
{
string word0 = "test";
if( isAlphabetic(word0) )
{
cout << word0 << " is alphabetic" << endl;
}
else
{
cout << word0 << " is NOT alphabetic" << endl;
}
string word1 = "1234";
if( isAlphabetic(word1) )
{
cout << word1 << " is alphabetic" << endl;
}
else
{
cout << word1 << " is NOT alphabetic" << endl;
}
string word2 = "1234w";
if( isAlphabetic(word2) )
{
cout << word2 << " is alphabetic" << endl;
}
else
{
cout << word2 << " is NOT alphabetic" << endl;
}
return 0;
}