well I was doing this problem from leetcode " https://leetcode.com/problems/valid-palindrome/ " and to remove the punctuations I used this
for (auto i:s)
{
if (ispunct(i))
{
s.erase(remove(s.begin(), s.end(), i), s.end());
continue;
}
}
but when it runs it leaves some punctuation characters in the string like this:
ip-> "Marge, let's "[went]." I await {news} telegram."
op-> "margelets[wentiawaitnewstelegram"
Modifying a string (or any other collection) while looping over it is a poor idea. Your iterator into the string is based on the state of the string at the beginning of your loop. Changing the state of the string inside the loop may lead to unexpected behavior of your iterator.
Rather you may want to create a new string without the offending characters.
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
std::string s1 = "Hello world!";
std::string s2;
std::copy_if(s1.begin(), s1.end(),
std::back_inserter(s2),
[](auto ch) { return !std::ispunct(ch); });
std::cout << s2 << std::endl;
return 0;
}
Related
I have a project and I want to ask for some things. How can I make a string with descending order using cin<<word;? I tried this from a website that I found but it doesn't work with cin. Here is the code:
void descOrder(string s)
{
sort(s.begin(), s.end(), greater<char>());
}
int main()
{
string s = "geeksforgeeks";
descOrder(s); // function call
return 0;
}
To be more clear I want to do this
Input: geek for geeks
Output ssrokkggfeeee
Also, how can I replace letters from a string using the alphabet, for instance, the Hello I want to be like this H to be I, e to be f, l to be m, o to be p, and if a word contains the letter z I want to replace with the letter a.
The final question I want to print from a string first the according and after the vowels
You are passing your std::string by value, hence desOrder() gets a copy from it and then sorts it and you get nothing.
Pass your std::string by reference to be able to change it not a copy from it.
#include <string>
#include <iostream>
#include <algorithm>
void descOrder(std::string & s)
{
std::sort(s.begin(), s.end(), std::greater<char>());
}
int main()
{
std::string s = "geeksforgeeks";
descOrder(s); // function call
std::cout << s;
return 0;
}
Plz, post one question per post and see this Why is "using namespace std;" considered bad practice?
There are two methods applicable:
1. Pass value by reference:
When you pass a variable by reference, it does manipulates the original variable's value:
#include <iostream>
#include <algorithm>
void descOrder(std::string & s) // just use an '&' sign here
{
sort(s.begin(), s.end(), std::greater<char>());
}
int main()
{
std::string s = "geeksforgeeks";
descOrder(s); // function call
std::cout << s << std::endl;
return 0;
}
2. Return value instead of passing by reference:
If you don't want to change the original value but want to store in another variable or directly print it, you may do something like:
#include <iostream>
#include <algorithm>
std::string descOrder(std::string s)
{
sort(s.begin(), s.end(), std::greater<char>());
return s;
}
int main()
{
std::string s = "geeksforgeeks";
std::string changedS = descOrder(s); // function call AND assigning to another variable
std::cout << changedS << std::endl;
// alternatively (uncomment)...
// std::cout << descOrder(s) << std::endl; // if you just want to print
return 0;
}
I want to remove a character ('#') from a string,
I tried to check if the string has '#' with the find function, which it does, then erase this with the erase function.
For some reason I get a run time error that says I have no memory.
Error: std::out_of_range at memory location 0x003BF3B4
#include <iostream>
#include <algorithm>
#include <string>
int main()
{
std::string str = "Hello World#";
if (str.find('#')) {
str.erase('#');
}
return 0;
}
The excepted output is: "Hello World"
Try something like this:
#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), '#'), str.end());
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string s = "Hello World#";
char c = '#';
/* Removing character c from s */
s.erase(std::remove(s.begin(), s.end(), c), s.end());
std::cout << "\nString after removing the character "
<< c << " : " << s;
}
If you want to delete all '#' from the string:
std::string str = "Hello World#";
std::size_t pos = str.find('#');
while(pos != std::string::npos)
{
str.erase(pos, 1); //<- edited here
pos = str.find('#');
}
cout << str;
I have a function that reads a file to find a certain word. The system I currently have however searched for a specific word and isn't case sensitive. I can't simply use .find("word" && "Word")
As far as I can tell, the easiest way to do this would be with a vector with both versions of the word inside for the function to look for both however I can't figure out how to pass the vector into the function.
Any help would be appreciated. Thanks
You may just call find for every possible word in your vector. But i would suggest to use only lowercase if possible
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
int main()
{
std::string str = "HeLlo WorLd";
std::vector<std::string> vec{ "HELLO","HeLlo","hEllO","WORLD","WorLd" };
std::for_each(vec.begin(), vec.end(), [&](const std::string& comp)
{
auto found = str.find(comp);
if (found != std::string::npos)
std::cout << "Found World " << comp << " in str at " << std::distance(str.begin(), str.begin() + found) << std::endl;
});
return 0;
}
In c++ you can pass the vector to a function as a reference or absolute value. To pass as the reference, You can follow this approach.
int fun(std::vector<std::string>& arr) {
int value = 0;
// your operation
return value;
}
int main() {
std::vector<std::string> arr;
// your logic
int value = fun(arr);
return 0;
}
I am attempting to iterate over a string to check for punctuation. I've tried to use ispunct() but am receiving an error that there is no matching fucntion for call to ispunct. Is there a better way to implement this?
for(std::string::iterator it = oneWord.begin(); it != oneWord.end(); it++)
{
if(ispunct(it))
{
}
}
Is there a better way to implement this?
Use std::any_of:
#include <algorithm>
#include <cctype>
#include <iostream>
int main()
{
std::string s = "Contains punctuation!!";
std::string s2 = "No puncuation";
std::cout << std::any_of(s.begin(), s.end(), ::ispunct) << '\n';
std::cout << std::any_of(s2.begin(), s2.end(), ::ispunct) << '\n';
}
Live Example
it is an iterator; it points to a character in a string. You have to dereference it to get the thing it points to.
if(ispunct(static_cast<unsigned char>(*it)))
So I have this code and it crashes xcode
void strrev(const std::string& str)
{
for(size_t i=str.length();i>=0;i--)
{
std::cout << str[i];
}
}
It works fine if I do i>0 but then the first character does not get printed
Any suggestions on what is wrong with i>=0 ?
Problem
i is of type size_t (it is an unsigned integral), so when i is zero and i-- is performed, its value wraps around, getting i the highest possible value it can store. This i is then used in the expression str[i] causing a crash.
Solution
You can separately handle the case for i equal to zero. Also, since indices start at zero, the highest possible index is str.length()-1.
It should be then:
for(size_t i=str.length()-1; i > 0; i--)
std::cout << str[i];
std::cout << str[0];
Recommended alternatives
Consider using reverse iterators instead to avoid having to deal with indices:
void strrev(const std::string& str)
{
for (auto rit = str.rbegin(); rit != str.rend(); ++rit)
std::cout << *rit;
}
Note that you can also use std::copy in combination with reverse iterators and a std::ostream_iterator object for std::cout:
#include <iostream>
#include <algorithm>
#include <string>
#include <iterator>
void strrev(const std::string& str)
{
std::copy(str.rbegin(), str.rend(),
std::ostream_iterator<std::string::value_type>{std::cout});
}
or directly use std::reverse_copy instead of std::copy and therefore no need for reverse iterators:
std::reverse_copy(str.begin(), str.end(),
std::ostream_iterator<std::string::value_type>{std::cout});
It's better to do this in an idiomatic, index-free way using std::reverse.
#include <algorithm>
#include <iostream>
#include <string>
int main() {
std::string str = "Hello World!";
std::reverse(str.begin(), str.end());
std::cout << str << "\n"; // !dlroW olleH
}
Since the strings in c++ are base zero -the first character in a string is str[0]- therefor the index of the last character in a c++ string is always str.length()-1 or str.size()-1
So it should be
void strrev(const std::string& str)
{
for(size_t i=str.length()-1;i>=0;i--)
{
std::cout << str[i];
}
}