Sorting a string using STL - c++

I am trying to sort the characters of a string using C++ STL and came up with this code.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
int main()
{
using namespace std;
vector<string>::iterator it;
string arr[] = {"jajajaj"};
vector<string> v(arr, arr+2);
sort(v.begin(), v.end());
for (it=v.begin(); it<v.end(); it++) {
cout << *it;
}
return 0;
}
But unfortunately its not sorting properly when the array contains single element. How to do it using STL.
Please help.

You can sort the string using std::string class.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
string str = "jajajaj";
sort(str.begin(), str.end());
cout << str;
return 0;
}
Hope this might be helpful.

If you need a string, use a std::string :
(I used a for-range loop to make the code cleaner)
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
string s = {"jajajaj"};
sort(s.begin(), s.end());
for (auto c : s)
cout << c;
return 0;
}
Outputs:
aaajjjj
Note:
Your current code is not working because, as commented, you create a vector of size 2 out of an array of size 1, which has undefined behavior.

You seem to be confusing a std::string with an array of chars.
int main()
{
using namespace std;
string arr = "jajajaj";
vector<char> v(arr.begin(), arr.end());
sort(v.begin(), v.end());
vector<char>::iterator it;
for (it=v.begin(); it<v.end(); ++it) {
cout << *it;
}
return 0;
}
I haven't tested that, but it should work....
UPDATE:
Alternately, we could just sort the string's character directly: (Thanks guys!)
int main()
{
using namespace std;
string arr = "jajajaj";
sort(arr.begin(), arr.end());
cout << arr;
return 0;
}

You can use sort() function. sort() exists in algorithm header file
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
string str = "sharlock";
sort(str.begin(), str.end());
cout<<str<<endl;
return 0;
}
Output:
achklors

In order to sort a string, just input string from the user and use the sort() in STL for it.
#include<bits/stdc++.h>
using namespace std;
int main()
{
string arr;
cin >>arr;
sort(arr.begin(), arr.end());
cout <<arr;
}
See the sample image below for the output with input string as "Michael".

Related

How to remove consonants from a string? [closed]

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 4 years ago.
Improve this question
Here is my code:
#include <iostream>
#include <string>
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
while(n--)
{
string str;
char a[] = {'a','e','i','o','u','A','E','I','O','U'};
getline(cin, str);
for(int i=0 ;i<str.length(); i++)
{
for(int j=0; j<10; j++)
{
if(str[i]==a[j])
{
cout << str[i];
}
}
}
cout << "\n";
}
return 0;
}
Test cases are :
HmlMqPhBfaVokhR
wdTSFuI
IvfHOSNv
I am not removing anything but I am printing only vowels. But, some test cases didn't pass. Maybe this code doesn't work on multiple test cases.
Try this for proper console in :
int main()
{
int n;
std::cin >> n;
std::cin.ignore(); // fix
/* remaining code */
return 0;
}
> To find the vowels in a string
On way of finding the vowels in a string is using a std::binary_search each character of the given string in a vowel table.
Make a sorted array of char s of all vowels(i.e. vowels array).
For each char of the input string, std::binary_search in the
vowels array.
If std::binary_search returns true(meaning the char is an vowel), print the char of the string.
Following is the example code! (See live online)
#include <iostream>
#include <string>
#include <algorithm> // std::for_each, std::binary_search, std::sort
#include <array> // std::array
int main()
{
std::array<char, 10> a{ 'a','e','i','o','u','A','E','I','O','U' };
std::sort(a.begin(), a.end()); // need sorted array for std::binary_search
const std::string str{ "HmlMqPhBfaVokhR wdTSFuI IvfHOSNv" };
std::for_each(str.cbegin(), str.cend(), [&](const char str_char)
{
if (std::binary_search(a.cbegin(), a.cend(), str_char))
std::cout << str_char << " ";
});
return 0;
}
Output:
a o u I I O
> To remove the vowels from a string
Use erase-remove idiom as follows(till c++17†).
Make a sorted array of char s of all vowels(i.e. vowels array).
Using std::remove_if, collect the iterators pointing to the characters, which are vowels. A lambda function can be used as the predicate for std::remove_if, where the std::binary_search is used to check the char in the string exists in the vowels array.
Using std::string::erase, erase all the collected characters(i.e. vowels) from the string.
Following is an example code! (See live online)
#include <iostream>
#include <string>
#include <algorithm> // std::sort, std::binary_search, std::remove_if
#include <array> // std::array
int main()
{
std::array<char, 10> a{ 'a','e','i','o','u','A','E','I','O','U' };
std::sort(a.begin(), a.end()); // need sorted array for std::binary_search
std::string str{ "Hello World" };
// lambda(predicate) to check the `char` in the string exist in vowels array
const auto predicate = [&a](const char str_char) -> bool {
return std::binary_search(a.cbegin(), a.cend(), str_char);
};
// collect the vowels
const auto vowelsToRemove = std::remove_if(str.begin(), str.end(), predicate);
// erase the collected vowels using std::string::erase
str.erase(vowelsToRemove, str.end());
std::cout << str << "\n";
return 0;
}
Output:
Hll Wrld
† Since c++20, one can use std::erase_if for this, which would be less error prone than the the above one. (See online live using GCC 9.2)
#include <iostream>
#include <string> // std::string, std::erase_if
#include <array> // std::array
int main()
{
std::array<char, 10> a{ 'a','e','i','o','u','A','E','I','O','U' };
std::sort(a.begin(), a.end()); // need sorted array for std::binary_search
std::string str{ "Hello World" };
// lambda(predicate) to check the `char` in the string exist in vowels array
const auto predicate = [&a](const char str_char) -> bool {
return std::binary_search(a.cbegin(), a.cend(), str_char);
};
std::erase_if(str, predicate); // simply erase
std::cout << str << "\n";
return 0;
}
> To remove the consonants from a string
To remove the consonants from the given string, in the above predicate negate the result of std::binary_search. (See live online)
const auto predicate = [&a](const char str_char) -> bool {
return !std::binary_search(a.cbegin(), a.cend(), str_char);
// ^^ --> negate the return
};
As side notes,
Avoid the #include<bits/stdc++.h> Read more: Why should I not #include <bits/stdc++.h>?
Do not practice with using namespace std; Read more: Why is "using namespace std;" considered bad practice?
Apart from the std::getline problem already answered:
for(int i=0 ;i<str.length(); i++)
{
for(int j=0; j<10; j++)
{
if(str[i] == a[j])
{
// this is the one you do NOT want to print...
// cout<<str[i];
// skip instead:
goto SKIP;
}
}
std::cout << str[i]; // output the one NOT skipped...
SKIP: (void)0;
}
OK, don't want to start any discussion about usage of goto, there are many ways to avoid it, e. g. by packing the inner for loop into a separate (inline) function. You can have it easier, though, as there already exists such a function; code gets even easier with a range-based for loop:
for(auto c : str)
{
if(!strchr("aeiouAEIOU", c))
{
std::cout << c;
}
}
strchr (from cstring) returns a pointer to the first character in the string equal to the reference character - or nullptr if not found...
To really remove the vowels from the string in a modern C++ way, consider this:
str.erase(std::remove_if(
str.begin(), str.end(),
[](char c) { return strchr("aeiouAEIOU", c) != nullptr; }
), str.end());
Your code probably should looks like (please see comments inline):
#include <iostream>
#include <string>
using namespace std;
int main() {
string vowels = "aeiouAEIOU";
int n;
cin>>n; // assume this stands for line count
while(n-- >= 0)
{
string str, result;
getline(cin, str);
for(int i=0 ;i<str.length(); i++)
{
if (vowels.find(str[i]) != std::string::npos)
result += str[i]; // add character to result if it is not consonant
}
cout<<result<<"\n"; // print result
}
return 0;
}

storing extracted characters in a vector of strings

I should reasonably be able to store chars in a std::vector of strings, if the conversion is considered.
Here is the try:
vector<string> f (vector<string> input)
{
vector<string> output;
for (int i=0; i<input.size(); i++) // vector iteration
{
for (int j=0;j<input[i].size(); j++) // string iteration
{
output.push_back(string(input[i].at(j))); // access to characters
}
}
return output;
}
input[i] is a string, and input[i].at(j) is a char; thus, I've converted it to string before pushing to vector<string>.
I'm wondering what's wrong with this approach. Especially, the compiler's error is undecipherable to me:
invalid conversion from '__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type {aka char}' to 'const char*' [-fpermissive]
Edit:
f must work as follows.
Suppose there are 3 strings in the input vector: {abcd,efdr,loab}; then, the output shall extract all atormic characters like: {abcdefdrloab}
To correct your error change
output.push_back(string(&input[i].at(j)));
from
output.push_back(string(input[i].at(j)));
Basically
**for (int i=0; i<input.size(); i++) \\vector iteration**
This is a wrong way of iteration .For containers iterators should be used for iterating
Below copies string from one vector (Use of iterator and stl you can use copy_if or lambda)
#include <iostream>
#include <iterator>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
vector<string> f (vector<string> input)
{
vector<string> output;
copy(input.begin(),input.end(),back_inserter(output));
return output;
}
int main()
{
vector<string> h{"hello"},x;
x=f(h);
copy(x.begin(),x.end(),ostream_iterator<string>(cout," "));
}
Output
hello Program ended with exit code: 0
But to answer you question and fix of your Code
Below is the modified code
#include <iostream>
#include <iterator>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
vector<string> f (vector<string> input)
{
vector<string> output;
for (int i=0; i<input.size(); i++)
{
for (int j=0;j<input[i].size(); j++)
{
output.push_back(string(&input[i].at(j)));
}
}
return output;
}
vector<string> fi (vector<string> input)
{
vector<string> output;
copy(input.begin(),input.end(),back_inserter(output));
return output;
}
int main()
{
vector<string> h{"hello"},x,y;
x=fi(h);
y=f(h);
copy(x.begin(),x.end(),ostream_iterator<string>(cout," "));
copy(y.begin(),y.end(),ostream_iterator<string>(cout," "));
}
Output
hello hello ello llo lo o Program ended with exit code: 0
Solution after the edit
#include <iostream>
#include <iterator>
#include<vector>
#include<string>
#include<algorithm>
#include <numeric>
using namespace std;
template<typename T, typename... Args>
void push_back_vec(std::vector<T>& v, Args&&... args)
{
(v.push_back(args), ...);
}
int main()
{
vector<string>x;
push_back_vec(x, "abc", "cds", "ma");
string a = accumulate(x.begin(), x.end(), string(""));
cout<<a;
}
Output
abccdsmaProgram ended with exit code: 0
More easier format
#include <iostream>
#include <iterator>
#include<vector>
#include<string>
#include<algorithm>
#include <numeric>
using namespace std;
int main()
{
vector<string>x{"abc", "cds", "ma"},a;
a.push_back(accumulate(x.begin(), x.end(), string("")));
copy(a.begin(),a.end(),ostream_iterator<string>(cout," "));
}
try this string(1, input[i].at(j))

Segmentation fault in reversing string program

I am trying to reverse a string. Can someone explain me why this is giving me segmentation fault?
#include <iostream>
#include <string>
using namespace std;
int main(){
string str,rstr;
int len=str.length(),i=0;
cin>>str;
while(str[i]!='\0'){
rstr[--len]=str[i++];
}
rstr[str.length()]='\0';
cout<<rstr;
return 0;
}
P.S.: Need to reverse it without using library functions.
If you want to go the way you are doing it, for practice purposes, try this changes and start from there
#include <iostream>
#include <string>
using namespace std;
int main(){
string str,rstr;
cin>>str; // --- Moved this line up
rstr = str; // --- Added this line
int len=str.length(),i=0;
while(str[i]!='\0'){
rstr[--len]=str[i++];
}
rstr[str.length()]='\0';
cout<<rstr;
return 0;
}
Or just use reverse iterator
std::string s = "Hello";
std::string r(s.rbegin(), s.rend());
str is nothing but a declared string here:
int len=str.length(),i=0;
So you can't do str.length()
Do something like:
#include <iostream>
#include <string>
using namespace std;
int main(){
string str,rstr;
int len,i=0;
cin>>str;
len = str.length();
while(str[i]!='\0'){
rstr[i++]=str[--len];
}
rstr[str.length()]='\0';
cout<<rstr;
return 0;
}

Putting String array in parameter, then comparing the elements to literal strings error?

Let's say I have an array
string test = {"test1, "test2"}
I have my function
void testing(string test){
for(int i = 0; i < 2; i++){
if(test[i] == "test1"){
cout << "success" << endl;
}
}
}
But when I compile this, I get an error...why is that?
Is there a different approach?
Your test variable should be declared as an array type
string test[] = {"test1", "test2"};
You also need to change the function signature from
void testing(string test)
to
void testing(string* test){
the code you wrote is not going to compile because of wrong declaration of string array.
replace
string test = {"test1, "test2"};
with
string test[]={"test1, "test2"};
The following code uses the array in place without function
#include <iostream>
#include <string>
using namespace std;
string test[]={"test1, "test2"};
for(auto& item:test)
{
cout<<item<<endl;
}
I think the best way to get this working with function is to use vector
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void testing(const vector<string>& strings)
{
for (auto& item : strings)
{
cout << item << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<string> strings = { "str1", "str2", "str3" };
testing(strings);
cin.get();
return 0;
}

c++ what is the fastest way of storing comma separated int in std::vector

I have a comma separated integers and I want to store them in std::vector<int>. Currently I am manually doing it. Is there any built-in function which did the above functionality?
Edit:
I was in hurry and forget to put full details
Actually i have string (to be exact Unicode string) containing CSvs e.g. "1,2,3,4,5"
Now i want to store them in std::vector<int> so in above case my vector would have five elements pushed into it. Currently i am doing this by manual but its slow as well as there is lot of mess with that code
It's probably not be the most efficient way, but here's a way to do it using the TR1 regex functionality (I also use C++0x lambda syntax in this sample, but obviously it could also be done without that):
#include <iostream>
#include <algorithm>
#include <vector>
#include <regex>
#include <iterator>
#include <cstdlib>
std::vector<int> GetList(const std::wstring &input)
{
std::vector<int> result;
std::wsregex_iterator::regex_type rex(L"(\\d+)(,|$)");
std::wsregex_iterator it(input.begin(), input.end(), rex);
std::transform(it, std::wsregex_iterator(), std::back_inserter(result),
[] (const std::wsregex_iterator::value_type &m)
{ return std::wcstol(m[1].str().c_str(), nullptr, 10); });
return result;
}
You can do this using purely in STL for simplicity (easy to reading, no complex libs needed), which will be fast for coding, but not the fastest in terms of execution speed (though you can probably tweak it a little, like pre-reserving space in the vector:
std::vector<int> GetValues(std::wstring s, wchar_t delim)
{
std::vector<int> v;
std::wstring i;
std::wstringstream ss(s);
while(std::getline(ss,i,delim))
{
std::wstringstream c(i);
int x;
c >> x;
v.push_back(x);
}
return v;
}
(no forwarding(&&) or atoi to keep the code portable).
Sadly, the STL doesn't allow you to split a string on a separator. You can use boost to do it though: (requires a recent C++ compiler such as MSVC 2010 or GCC 4.5)
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
int main(int argc, char** argv)
{
string input = "1,2,3,4";
vector<string> strs;
boost::split(strs, input, boost::is_any_of(","));
vector<int> result;
transform(
strs.begin(), strs.end(), back_inserter(result),
[](const string& s) -> int { return boost::lexical_cast<int>(s); }
);
for (auto i = result.begin(); i != result.end(); ++i)
cout << *i << endl;
}
The quick and dirty option is to use the C string library strtok() function, and atoi():
void Split(char * string, std::vector<int>& intVec)
{
char * pNext = strtok(string, ",");
while (pNext != NULL)
{
intVec.push_back(atoi(pNext));
pNext = strtok(NULL, ",");
}
}
Insert your own input data validation as required.
See:
http://www.cplusplus.com/reference/clibrary/cstring/strtok/
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
As well as the wide string versions:
http://msdn.microsoft.com/en-us/library/2c8d19sb%28v=vs.71%29.aspx
http://msdn.microsoft.com/en-us/library/aa273408%28v=vs.60%29.aspx
EDIT:
Note that strtok() will modify your original string, so pass a copy if need be.
Try this:
It will read any type (that can be read with >>) separated by any char (that you choose).
Note: After the object is read there should can only be space between the object and the separator. Thus for things like ObjectSepReader<std::string, ','> it will read a word list separated by ','.
This makes it simple to use our standard algorithms:
#include <vector>
#include <sstream>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
std::stringstream data("1,2,3,4,5,6,7,8,9");
std::vector<int> vdata;
// Read the data from a stream
std::copy(std::istream_iterator<ObjectSepReader<int, ','> >(data),
std::istream_iterator<ObjectSepReader<int, ','> >(),
std::back_inserter(vdata)
);
// Copy data to output for testing
std::copy(vdata.begin(), vdata.end(), std::ostream_iterator<int>(std::cout," "));
}
The secret class to make it work.
template<typename T,char S>
struct ObjectSepReader
{
T value;
operator T const&() const {return value;}
};
template<typename T,char S>
std::istream& operator>>(std::istream& stream, ObjectSepReader<T,S>& data)
{
char terminator;
std::string line;
std::getline(stream, line, S);
std::stringstream linestream(line + ':');
if (!(linestream >> data.value >> terminator) || (linestream.tellg() != line.size()+1) || (terminator != ':'))
{ stream.setstate(std::ios::badbit);
}
return stream;
}
Personally I'd make a structure and have the vector contain instances of the struct.
Like so:
struct ExampleStruct
{
int a;
int b;
int c;
};
vector<ExampleStruct> structVec;
How about this?
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
struct PickIntFunc
{
PickIntFunc(std::vector<int>& vecInt): _vecInt(vecInt),_pBegin(0){}
char operator () (const char& aChar)
{
if(aChar == ',' || aChar == 0)
{
_vecInt.push_back(atoi(std::string(_pBegin,&aChar).c_str()));
_pBegin = 0;
}
else
{
if(_pBegin == 0)
{
_pBegin = &aChar;
}
}
return aChar;
}
const char* _pBegin;
std::vector<int>& _vecInt;
};
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<int> vecInt;
char intStr[] = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20";
std::for_each(intStr,intStr+sizeof(intStr),PickIntFunc(vecInt));
// Now test it
std::for_each(vecInt.begin(),vecInt.end(), [] (int i) { std::cout << i << std::endl;});
return 0;
}