i want a program which reverse given string in the below format.
Suppose if I input string as = "This is a boy"
then i want output reverse sting as = "boya si ishT"
one more example
Input string = "if a"
Output String = "af i"
please help.
i have written below program but not working as expected.
char string[] = "This is a boy\0";
char reverse[100] = {0};
int start = 0;
int len = strlen(string)-1;
int space= 0;
bool flag = false;
int count = 0;
while(len >= 0)
{
if(string[len] == ' ' )
{
len--;
flag = true;
}
if(flag && (string[len-1]) == ' ')
{
reverse[start] = string[len];
reverse[++start] = ' ' ;
len--;
start++;
flag = false;
continue;
}
reverse[start] = string[len];
flag = false;
start++;
len--;
}
Since you have the C++ tag
#include <string>
#include <algorithm>
#include <iostream>
std::string str = "This is a boy";
std::reverse(str.begin(), str.end());
std::cout << str;
or
char str[] = "This is a boy";
std::reverse(str, str + strlen(str));
Related
I need help in figuring out the logic or code to when I want my string not to fall in the middle of another string. For example my given word is "Birthday!" and the other string to look for it is "Happy Birthday Scott". It's going to return a false value because it's missing an exclamation point. Here is the code that I've worked
int Words::matchWords(const char* string, const char* sentence, int wordNum){
int wordCount = words(sentence); // the words function counts the number of words in the sentence
int strLength = strlen(str);
int sentLength = strlen(sentence);
int i = 0;
char strTemp[100];
char sentenceTemp[100];
strcpy(strTemp, str);
strcpy(sentenceTemp, sentence);
if (wordNum > wordCount) {
return false;
}
char* temp;
for (i = 0; i < strLength; i++) {
strTemp[i] = tolower(str[i]);
}
for (i = 0; i < sentLength; i++) {
sentenceTemp[i] = tolower(str[i]);
}
temp = strstr(sentenceTemp, strTemp);
if (temp != NULL) {
return true;
if (strTemp[i] != sentenceTemp[i]) {
return false;
}
else
return true;
}
else
return false;
}
Here is a super simple program for you to look at.
All you have to do for this problem is create your strings using std::string, determine if they are inside the big string using find(), and lastly check if it was found using string::npos.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string bday = "Birthday!";
string str1 = "Happy Birthday Scott";
int found1 = str1.find(bday);
string str2 = "Scott, Happy Birthday!";
int found2 = str2.find(bday);
if (found1 == string::npos) //if Birthday! is NOT found!
{
cout << "str1: " << "FALSE!" << endl;
}
if (found2 != string::npos) //if Birthday! IS found!
{
cout << "str2: " << "TRUE!" << endl;
}
}
Note that for string::npos, you use == for something NOT being found and != for something that IS found.
I have the following strings:
std::string str1 = "1234567890";
std::string str2 = "B-XXXX_XXX_V-XX_X";
I want to loop through str2 and replace every occurrence of X with the subsequent value from str1, resulting in: B-1234_567_V-89_0.
I have a semblance of a solution below, but it's not very efficient (it worked at one point). In brief, I tried to loop through the characters in str2, and if the character equaled 'X', replace that character with an incrementing index from str1:
int ind = 0;
std::string pattern_char;
for (int i = 0; i < str2.size(); i++) {
pattern_char = str2[i];
if (pattern_char == "X") {
str2[i] = str1[x_ind];
x_ind++;
}
}
What is the most efficient way to perform this operation?
Your current implementation treats each individual unit of the string as a std::string rather than as a single char, which introduces some unnecessary overhead. Here's a rewrite that uses chars:
int x_ind = 0;
for (int i = 0; i < str2.size(); i++) {
if (str2[i] == 'X') { // Don't assign str2[i] to a char; use character literals
str2[i] = str1[x_ind];
x_ind++;
}
}
You can improve readability by using a range-based for loop, like this:
int x_ind = 0;
for (char& ch: str2) {
if (ch == 'X') {
ch = str1[x_ind];
x_ind++;
}
}
If by "not very efficient" you want to improve your current code, maybe the only thing to do is to rewrite your loop:
int idx = 0;
for (char& c : str2) {
if (c == 'X')
c = str1[idx++];
}
But if you want to write this by only using standard library, you can do the same thing by using std::transform():
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::string str1 = "1234567890";
std::string str2 = "B-XXXX_XXX_V-XX_X";
int i = 0;
std::transform(str2.begin(), str2.end(), str2.begin(),
[&str1, &i](const char& c) -> char {
return c == 'X' ? str1[i++] : c;
});
std::cout << str2 << std::endl;
}
Here's another solution:
auto i = str1.begin();
for (char& ch: str2) {
if (ch == 'X')
ch = *i++;
The only problem I see with your code is that you unnecessary use std::string pattern_char;:
#include <string>
#include <iostream>
#include <stdexcept>
auto replace_with_pattern(std::string& str, char ch_to_replace, const std::string& pattern)
{
auto pattern_it = pattern.begin();
for (char& ch : str)
{
if (ch == ch_to_replace)
{
if (pattern_it == pattern.end())
throw std::invalid_argument{"ran out of pattern"};
ch = *pattern_it;
++pattern_it;
}
}
}
int main()
{
std::string str1 = "1234567890";
std::string str2 = "B-XXXX_XXX_V-XX_X";
replace_with_pattern(str2, 'X', str1);
std::cout << str2 << std::endl;
}
Why is this program returning garbage values? I expect the output to be the word 'large', but the value is actually 'rat' - the last word.
#include <iostream>
#include <string>
using namespace std;
std::string LongestWord(std::string sen)
{
std::string s2, lW;
for (int i = 0; i < sen.size(); ++i) {
while (sen[i] != ' ') {
s2 += sen[i];
++i;
}
if (s2.size() > lW.size()) {
lW = ""; lW = s2;
}
s2 = "";
}
return lW;
}
int main(void)
{
cout << LongestWord("a cat ate the large rat") << endl;
return 0;
}
Your internal while loop will almost certainly run beyond the end of the given string argument (unless it has a space at the end). Change this internal loop to check for the size of that string, as follows:
while (i < sen.size() && sen[i] != ' ') {
s2 += sen[i];
++i;
}
I am having trouble figuring out the process to add a space in a string at capital letters in C++. If I have a string "HelloWorld", how do I convert that to "Hello World"?
I've tried using substrings and the isupper function but I can't get anything to work.
Edit: this is the code I have. I don't understand why in = newname is not valid code.
string breakStringAtCaps(string in) {
string newname[10];
int j = 0;
for (int i = 0; i < in.size(); i++) {
if (isupper(in[i]) && i != 0) {
newname[j] = " ";
j++;
}
newname[j] = in[i];
j++;
}
in = newname;
return in;
}
You can do it like this:
string breakStringAtCaps(const string& in)
{
string newname;
for(int i = 0; i < in.size(); i++)
{
if(isupper(in[i]) && i != 0)
newname += " ";
newname += in[i];
}
return newname;
}
You are thinking right in thinking substr, but you implementation is a bit off. If creating an new string containing the contents of the original and inserting a ' ' (space) before each upper-case letter (not including the first), you can seed the new string with the first character of the original using substr(0,1) and then use an auto ranged for loop and substr(1) to evaluate each character after the first.
The loop along with a check of isupper() is basically all you need, e.g.
#include <iostream>
#include <string>
#include <cctype>
int main (int argc, char **argv) {
std::string s = argc > 1 ? argv[1] : "HelloWorld",
snew = s.substr (0,1);
if (s.size() > 0)
for (auto& c : s.substr(1)) {
if (std::isupper (c))
snew += " ";
snew += c;
}
std::cout << snew << '\n';
}
(the program will use "HelloWorld" by default if no string is given as an argument on the command line, otherwise the string given on the command line is used)
Example Use/Output
$ ./bin/spacebeforeupper
Hello World
Or with a string given as an argument:
$ ./bin/spacebeforeupper MyDogHasFleas
My Dog Has Fleas
You can iterate through the strin characters, check if it is a cap and insert a ' ' before if it is one:
It should look like:
for(int i=0; i < str.length(); i++)
{
if (str[i]>='A' && str[i]<='Z')
{
if (i != 0)
cout << " ";
cout << str[i];
}
else
{
cout << str[i];
}
}
I just give a implementation, maybe not the best solution:
#include <string>
#include <ctype.h>
void breakStringAtCaps(std::string& in) {
std::string::const_iterator it = in.begin();
while(it != in.end()) {
if(it != in.begin() && isupper(*it)) {
in.insert(it, ' ');
it += 2;
}
else
++it;
}
}
//
#include <iostream>
int main(int argc, char** argv) {
std::string str("HelloWorld;");
breakStringAtCaps(str);
std::cout << str.c_str() << std::endl;
return 0;
}
and in your code,
string newname[10];
here 'newname' is a string array's name. you should not assign the name of array to a string instance.
and newname[i] means the i-th string of the array, not the i-th char of a string named 'newname' as you desired.
I have this function sentanceParse with a string input which returns a list. The input might be something like "Hello my name is Anton. What's your name?" and then the return value would be a list containing "Hello my name is Anton" and "What's your name?". However, this is not what happens. It seems as if the whitespaces in the sentences are treated like a separator and therefore the return is rather "Hello", "my", "name" etc instead of what I expected.
How would you propose I solve this?
As I am not a 100% sure the problem does not lie within my code, I will add that to the post as well:
Main:
list<string> mylist = sentanceParse(textCipher);
list<string>::iterator it;
for(it = mylist.begin(); it != mylist.end(); it++){
textCipher = *it;
cout << textCipher << endl; //This prints out the words separately instead of the entire sentances.
sentanceParse:
list<string> sentanceParse(string strParse){
list<string> strList;
int len = strParse.length();
int pos = 0;
int count = 0;
for(int i = 0; i < len; i++){
if(strParse.at(i) == '.' || strParse.at(i) == '!' || strParse.at(i) == '?'){
if(i < strParse.length() - 1){
while(i < strParse.length() - 1 && (strParse.at(i+1) == '.' || strParse.at(i+1) == '!' || strParse.at(i+1) == '?')){
if(strParse.at(i+1) == '?'){
strParse.replace(i, 1, "?");
}
strParse.erase(i+1, 1);
len -= 1;
}
}
char strTemp[2000];
int lenTemp = strParse.copy(strTemp, i - pos + 1, pos);
strTemp[lenTemp] = '\0';
std::string strAdd(strTemp);
strList.push_back(strAdd);
pos = i + 1;
count ++;
}
}
if(count == 0){
strList.push_back(strParse);
}
return strList;
}
Your implementation of sentence parse is wrong, here is a simpler correct solution.
std::list<std::string> sentence_parse(const std::string &str){
std::string temp;
std::list<std::string> t;
for(int x=0; x<str.size();++x){
if(str[x]=='.'||str[x]=='!'||str[x]=='?'){
if(temp!="")t.push_back(temp);//Handle special case of input with
//multiple punctuation Ex. Hi!!!!
temp="";
}else temp+=str[x];
}
return t;
}
EDIT:
Here is a full example program using this function. Type some sentences in your console, press enter and it will spit the sentences out with a newline separating them instead of punctuation.
#include <iostream>
#include <string>
#include <list>
std::list<std::string> sentence_parse(const std::string &str){
std::string temp;
std::list<std::string> t;
for(int x=0; x<str.size();++x){
if(str[x]=='.'||str[x]=='!'||str[x]=='?'){
if(temp!="")t.push_back(temp);//Handle special case of input with
//multiple punctuation Ex. Hi!!!!
temp="";
}else temp+=str[x];
}
return t;
}
int main (int argc, const char * argv[])
{
std::string s;
while (std::getline(std::cin,s)) {
std::list<std::string> t= sentence_parse(s);
std::list<std::string>::iterator x=t.begin();
while (x!=t.end()) {
std::cout<<*x<<"\n";
++x;
}
}
return 0;
}
// This function should be easy to adapt to any basic libary
// this is in Windows MFC
// pass in a string, a char and a stringarray
// returns an array of strings using char as the separator
void tokenizeString(CString theString, TCHAR theToken, CStringArray *theParameters)
{
CString temp = "";
int i = 0;
for(i = 0; i < theString.GetLength(); i++ )
{
if (theString.GetAt(i) != theToken)
{
temp += theString.GetAt(i);
}
else
{
theParameters->Add(temp);
temp = "";
}
if(i == theString.GetLength()-1)
theParameters->Add(temp);
}
}