I have almost completed the coding to solve simple linear equation set. Just seem to missing something in the recursive call with Maps causing issue.
Here is the problem statement to solve, example:
X = Y + 2
Y = Z + R + 1
R = 2 + 3
Z = 1
Given: LHS would be just variable names. RHS would have only variables, unsigned int and '+' operator. Solve for all unknowns.
Solution that I get with my code:
X = 2
Y = 1
R = 5
Z = 1
My code :
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <fstream>
#include <set>
#include <regex>
using namespace std;
map<string, string> mymap;
// Method to Parse a given expression based on given arg delimiter
// ret: vector of parsed expression
vector<string> parse_expr(string n, char *delims)
{
vector<string> v;
string cleanline;
char* char_line = (char*)n.c_str(); // Non-const cast required.
char* token = NULL;
char* context = NULL;
vector<string>::iterator it;
token = strtok_s(char_line, delims, &context);
while (token != NULL)
{
cleanline += token;
cleanline += ' ';
v.push_back(token);
token = strtok_s(NULL, delims, &context);
}
return v;
}
//Method to find sum for a given vector
//retype: string
//ret: sum of given vector
string find_VctrSum(string key, vector<string> v)
{
int sum = 0;
string val;
vector<string>::iterator i;
for (i = v.begin(); i != v.end(); i++)
{
val = *i;
//cout << "val is :" << val << endl;
sum += stoi(val);
}
return to_string(sum);
}
//Method to check if arg is integer or string
// ret: True if int
bool isNumber(string x) {
regex e("^-?\\d+");
if (regex_match(x, e)) return true;
else return false;
}
//Recursive call to evaluate the set of expressions
string evaluate_eq(string key)
{
string expr, var;
vector<string> items;
vector<string>::iterator i;
auto temp = mymap.find(key);
if (temp != mymap.end()) // check temp is pointing to underneath element of a map
{
//fetch lhs
var = temp->first;
//fetch rhs
expr = temp->second;
}
// remove whitespaces
expr.erase(remove_if(expr.begin(), expr.end(), isspace), expr.end());
//Parse RHS by '+' sign
items = parse_expr(expr, "+");
for (i = items.begin(); i != items.end(); i++)
{
//cout << (*i) << endl;
if (isNumber(*i) == true)
{
//pass- do nothiing
}
else
{
//recursive call to evaluate unknown
string c = evaluate_eq(*i);
//now update the map and Find Sum vector
mymap[key] = c;
*i = c;
}
}
//find sum
return find_VctrSum(key, items);
}
//main to parse input from text file and evaluate
int main()
{
string line;
ifstream myfile("equation.txt");
vector<string> v;
if (myfile.is_open())
{
while (getline(myfile, line))
{
v.push_back(line);
}
myfile.close();
}
else cout << "Unable to open file";
//Create a map with key:variable and value: expression to solve
for (int i = 0; i < v.size(); i++)
{
vector<string> token;
token = parse_expr(v[i], "=");
mymap.insert(pair<string, string>(token[0], token[1]));
}
cout << "Equation sets given:" << endl;
for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); ++it)
{
std::cout << it->first << " => " << it->second << '\n';
}
for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); it++)
{
//Also update the map
mymap[it->first] = evaluate_eq(it->first);
}
cout << "Equation sets solved:" << endl;
for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); ++it)
{
std::cout << it->first << " => " << it->second << '\n';
}
char ch;
cin >> ch;
}
Logic is to call recursively for any unknown (string) if found while resolving a given expression and update the map with values. On debugging, I could see that my recursive call fails at below, but I see "mymap" is being updated. Not sure why.
if (temp != mymap.end())
Any help in identifying the issue or any logical lapse would be much appreciated.
Thanks
After fixing couple of logic, my code works correctly.
In main()
While, creating the input map create by striping whitespace
//Create a map with key:variable and value: expression to solve
for (int i = 0; i < v.size(); i++)
{
vector<string> token;
token = parse_expr(v[i], "=");
//Strip whitespaces
token[0].erase(remove_if(token[0].begin(), token[0].end(), isspace), token[0].end());
token[1].erase(remove_if(token[1].begin(), token[1].end(), isspace), token[1].end());
mymap.insert(pair<string, string>(token[0], token[1]));
}
This eliminate my issue of finding key in the map -
if (temp != mymap.end())
Updated my find_VctrSum to update the map here, unlike my earlier attempt to update in evaluate_eq().
//Method to find sum for a given vector
//retype: string
//ret: sum of given vector
string find_VctrSum(string key, vector<string> v)
{
int sum = 0;
string val;
vector<string>::iterator i;
for (i = v.begin(); i != v.end(); i++)
{
val = *i;
sum += stoi(val);
}
//Update the Map
mymap[key] = to_string(sum);
return to_string(sum);
}
Here is the complete working code -
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <fstream>
#include <set>
#include <regex>
using namespace std;
map<string, string> mymap;
// Method to Parse a given expression based on given arg delimiter
// ret: vector of parsed expression
vector<string> parse_expr(string n, char *delims)
{
vector<string> v;
string cleanline;
char* char_line = (char*)n.c_str(); // Non-const cast required.
char* token = NULL;
char* context = NULL;
vector<string>::iterator it;
token = strtok_s(char_line, delims, &context);
while (token != NULL)
{
cleanline += token;
cleanline += ' ';
v.push_back(token);
token = strtok_s(NULL, delims, &context);
}
return v;
}
//Method to find sum for a given vector
//retype: string
//ret: sum of given vector
string find_VctrSum(string key, vector<string> v)
{
int sum = 0;
string val;
vector<string>::iterator i;
for (i = v.begin(); i != v.end(); i++)
{
val = *i;
sum += stoi(val);
}
//Update the Map
mymap[key] = to_string(sum);
return to_string(sum);
}
//Method to check if arg is integer or string
// ret: True if int
bool isNumber(string x) {
regex e("^-?\\d+");
if (regex_match(x, e)) return true;
else return false;
}
//Recursive call to evaluate the set of expressions
string evaluate_eq(string key)
{
string expr, var;
vector<string> items;
vector<string>::iterator i;
string currentkey = key;
auto temp = mymap.find(key);
if (temp != mymap.end()) // check temp is pointing to underneath element of a map
{
//fetch lhs
var = key;
//fetch rhs
expr = temp->second;
}
// remove whitespaces
expr.erase(remove_if(expr.begin(), expr.end(), isspace), expr.end());
//Parse RHS by '+' sign
items = parse_expr(expr, "+");
for (i = items.begin(); i != items.end(); i++)
{
if (isNumber(*i) == true)
{
//pass- do nothiing
}
else
{
//recursive call to evaluate unknown
string c = evaluate_eq(*i);
//update the temp vector
*i = c;
}
}
//find sum
return find_VctrSum(key, items);
}
//main to parse input from text file and evaluate
int main()
{
string line;
ifstream myfile("equation.txt");
vector<string> v;
if (myfile.is_open())
{
while (getline(myfile, line))
{
v.push_back(line);
}
myfile.close();
}
else cout << "Unable to open file";
//Create a map with key:variable and value: expression to solve
for (int i = 0; i < v.size(); i++)
{
vector<string> token;
token = parse_expr(v[i], "=");
//Strip whitespaces
token[0].erase(remove_if(token[0].begin(), token[0].end(), isspace), token[0].end());
token[1].erase(remove_if(token[1].begin(), token[1].end(), isspace), token[1].end());
mymap.insert(pair<string, string>(token[0], token[1]));
}
cout << "Equation sets given:" << endl;
for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); ++it)
{
std::cout << it->first << " => " << it->second << '\n';
}
for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); it++)
{
//Also update the map
mymap[it->first] = evaluate_eq(it->first);
}
cout << "Equation sets solved:" << endl;
for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); ++it)
{
std::cout << it->first << " => " << it->second << '\n';
}
char ch;
cin >> ch;
}
Related
How do I take a text file from the command line that opens and reads it, and then count the top words in that file but also removes any special characters. I have this code done here and used maps but it isn't counting every word. For instance "hello." is one word and also "$#%hello<>?/". I have this file from the song shake it off that's supposed to read shake 78 times but I only counted 26 in this code.
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <vector>
using namespace std;
string ask(const string& msg) {
string ans;
cout << msg;
getline(cin, ans);
return ans;
}
int main() {
ifstream fin( ask("Enter file name: ").c_str() ) ;
if (fin.fail()) {
cerr << "ERROR"; // this is if the file fails to open
return 1;
}
map<string, int> wordCount;
string entity;
while (fin >> entity) {
vector<string> words;
for (int i = 0, a = 0; i < entity.length(); i++) {
char& c = entity[i];
if (c < 'A' || (c > 'Z' && c < 'a') || c > 'z') {
string word = entity.substr(a, i - a);
a = i + 1;
if (word.length() > 0)
words.push_back(word);
}
}
for (auto & word : words)
wordCount[word]++;
}
fin.close();
vector<string> topWords;
const size_t MAX_WORDS = 10;
for ( auto iter = wordCount.begin(); iter != wordCount.end(); iter ++ ) {
int som = 0, lim = topWords.size();
while (som < lim) {
int i = ( som + lim ) / 2;
int count = wordCount[topWords[i]];
if ( iter -> second > count)
lim = i;
else if ( iter -> second < count )
som = i + 1;
else
som = lim = i;
}
if (som < MAX_WORDS ) {
topWords.insert( topWords.begin() + som, iter -> first );
if ( topWords.size() > MAX_WORDS )
topWords.pop_back();
}
}
for (auto & topWord : topWords)
cout << "(" << wordCount[topWord] << ")\t" << topWord << endl;
return 0;
}
One last thing if yall can probably help me on is how would I also write a code that takes a number from the command line alongside the filename and with that number, display the number of top words corresponding with that number passed in the command line, I would assume there is a parse args involved maybe.
Thank you again!
https://s3.amazonaws.com/mimirplatform.production/files/48a9fa64-cddc-4e45-817f-3e16bd7772c2/shake_it_off.txt
!hi!
#hi#
#hi#
$hi$
%hi%
^hi^
&hi&
*hi*
(hi(
)hi)
_hi_
-hi-
+hi+
=hi=
~hi~
`hi`
:hi:
;hi;
'hi'
"hi"
<hi<
>hi>
/hi/
?hi?
{hi{
}hi}
[hi[
]hi]
|hi|
\hi\
bob bob bob bob bob bob bob !###$$%#&#^*()#*#)_++(#<><#:":bob###$$%#&#^*()#*#)_++(#<><#:":
!###$$%#&#^*()#*#)_++(#<><#:":bob###$$%#&#^*()#*#)_++(#<><#:": !###$$%#&#^*()#*#)_++(#<><#:":bob###$$%#&#^*()#*#)_++(#<><#:":
!###$$%#&#^*()#*#)_++(#<><#:":bob###$$%#&#^*()#*#)_++(#<><#:": !###$$%#&#^*()#*#)_++(#<><#:":bob###$$%#&#^*()#*#)_++(#<><#:
this is the special character test
Your original code is somewhat hard to refine, I have followed your description to get a program that uses STL.
Combine erase with remove_if to remove unwanted chars
Use set to resort by counts
If you have some experience with Boost, it's a use case with multimap or bimap, which can make the code even more cleaner.
#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
using namespace std;
string ask(const string& msg) {
string ans;
cout << msg;
getline(cin, ans);
return ans;
}
int main() {
// ifstream fin(ask("Enter file name: ").c_str());
ifstream fin("shake_it_off.txt");
if (fin.fail()) {
cerr << "ERROR"; // this is if the file fails to open
return 1;
}
map<string, size_t> wordCount;
string entity;
while (fin >> entity) {
entity.erase(std::remove_if(entity.begin(), entity.end(),
[](char ch) { return !isalpha(ch); }),
entity.end());
wordCount[entity] += 1;
}
auto cmp = [](const std::pair<std::string, size_t>& lhs,
const std::pair<std::string, size_t>& rhs) {
return lhs.second > rhs.second;
};
std::multiset<std::pair<std::string, size_t>, decltype(cmp)> top(
wordCount.begin(), wordCount.end(), cmp);
auto it = top.begin();
const size_t MAX_WORDS = 10;
for (size_t i = 0; i < MAX_WORDS && it != top.end(); ++i, ++it) {
cout << "(" << it->first << ")\t" << it->second << endl;
}
return 0;
}
the code has to print the huffman code for the characters in the string but it is giving wrong code for some characters (mostly for the chacters that get code 1 at the end
#include<iostream>
#include<string>
#include<map>
#include<queue>
using namespace std;
struct compare {
bool operator()(pair<char, int> l, pair<char, int> r) {
return r.second > l.second;
}
};
map<char, int> frequencies(string str) {
map<char, int> result;
for (int i = 0; i < str.length(); i++) {
if (result.find(str[i]) != result.end())
result[str[i]]++;
else
result[str[i]] = 1;
}
return result;
}
void print(const map<char, int> a) {
for (map<char, int>::const_iterator it = a.begin(); it != a.end(); it++) {
cout << (it->first) << " " << (it->second) << endl;
}
}
void prints(const map<char, string> a) {
for (map<char, string>::const_iterator it = a.begin(); it != a.end(); it++) {
cout << (it->first) << " " << (it->second) << endl;
}
}
map<char, string> huffman(map<char, int> a) {
priority_queue < pair < char, int >, vector < pair < char, int > >, compare > mappednodes;
pair<char, int> root;
pair<char, int> left, right;
string s = "";
map<char, string> result;
for (map<char, int>::iterator itr = a.begin(); itr != a.end(); itr++) {
mappednodes.push(pair<char, int>(itr->first, itr->second));
}
while (mappednodes.size() != 1) {
left = mappednodes.top();
mappednodes.pop();
right = mappednodes.top();
mappednodes.pop();
root = make_pair('#', left.second + right.second);
mappednodes.push(root);
if (left.first != '#') {
s = "0" + s;
result[left.first] = s;
}
if (right.first != '#') {
s = "1" + s;
result[right.first] = s;
}
}
return result;
}
int main() {
string str;
cout << "enter the string ";
getline(cin, str);
cout << endl;
map<char, int> freq = frequencies(str);
print(freq);
cout << endl;
map<char, string> codes = huffman(freq);
prints(codes);
}
for example for string sasi
it must give
s 0
i 10
a 11
but its giving
s 0
i 10
a 110
https://www.geeksforgeeks.org/huffman-coding-greedy-algo-3/
used this as basis but not getting anything
The problem is that you just keep adding characters ("bits") to s in the loop.
So I have a little problem, I want to achieve this in C++, but I don't know how to do it:
Given is a string containing random numbers, symbols, and letters:
std::string = "1653gbdtsr362g2v3f3t52bv^hdtvsbjj;hdfuue,9^1dkkns";
Now I'm trying to find all ^ characters, and if those are followed by a number between 0 and 9, delete the ^ and the number, so:
"^1ghhu^7dndn^g"
becomes:
"ghhudndn^g"
I know how to find and replace/erase chars from a string, but I don't know how to check if it's followed by a number in a not hard coded way. Any help is appreciated.
std::string s = "^1ghhu^7dndn^g";
for (int i = 0; i < s.length() - 1; ++i)
{
if (s[i] == '^' && std::isdigit(s[i + 1]))
{
s.erase(i, 2);
--i;
}
}
This needs these includes:
#include <string>
#include <cctype>
I would do it this way:
#include <iostream>
#include <string>
#include <utility>
#include <iterator>
template<class Iter, class OutIter>
OutIter remove_escaped_numbers(Iter first, Iter last, OutIter out) {
for ( ; first != last ; )
{
auto c = *first++;
if (c == '^' && first != last)
{
c = *first++;
if (std::isdigit(c))
continue;
else {
*out++ = '^';
*out++ = c;
}
}
else {
*out++ = c;
}
}
return out;
}
int main()
{
using namespace std::literals;
auto input = "^1ghhu^7dndn^g"s;
auto output = std::string{};
remove_escaped_numbers(input.begin(), input.end(), std::back_inserter(output));
std::cout << output << std::endl;
}
or this way:
#include <iostream>
#include <regex>
int main()
{
using namespace std::literals;
auto input = "^1ghhu^7dndn^g"s;
static const auto repl = std::regex { R"___(\^\d)___" };
auto output = std::regex_replace(input, repl, "");
std::cout << output << std::endl;
}
A solution using std::stringstream, and returning the input string cleared of caret-digit's.
#include <iostream>
#include <sstream>
#include <cctype>
int t404()
{
std::stringstream ss;
std::string inStr("1653gbdtsr362g2v3f3t52bv^hdtvsbjj;hdfuue,9^1dkkns");
for (size_t i = 0; i<inStr.size(); ++i)
{
if(('^' == inStr[i]) && isdigit(inStr[i+1]))
{
i += 1; // skip over caret followed by single digit
}
else
{
ss << inStr[i];
}
}
std::cout << inStr << std::endl; // compare input
std::cout << ss.str() << std::endl; // to results
return 0;
}
Output:
1653gbdtsr362g2v3f3t52bv^hdtvsbjj;hdfuue,9^1dkkns
1653gbdtsr362g2v3f3t52bv^hdtvsbjj;hdfuue,9dkkns
you can simply loop over the string and copy it while skipping the undesired chars. Here is a possible function to do it:
std::string filterString (std::string& s) {
std::string result = "";
std::string::iterator it = s.begin();
char c;
while (it != s.end()) {
if (*it == '^' && it != s.end() && (it + 1) != s.end()) {
c = *(it + 1);
if(c >= '0' && c <= '9') {
it += 2;
continue;
}
}
result.push_back(*it);
++ it;
}
return result;
}
A robust solution would be to use the regex library that C++11 brings in.
std::string input ("1653gbdtsr362g2v3f3t52bv^hdtvsbjj;hdfuue,9^1dkkns");
std::regex rx ("[\\^][\\d]{1}"); // "[\^][\d]{1}"
std::cout << std::regex_replace(input,rx,"woot");
>> 1653gbdtsr362g2v3f3t52bv^hdtvsbjj;hdfuue,9wootdkkns
This locates a "^" character ([\^]) followed by 1 ({1}) digit ([\d]) and replaces all occurances with "woot".
Hope this code can solve your problem:
#include <iostream>
#include <string>
int main()
{
std::string str = "^1ghhu^7dndn^g";
std::string::iterator first, last;
for ( std::string::iterator it=str.begin(); it!=str.end(); ++it)
{
if(*it == '^')
{
first = it;
it++;
while(isdigit(*it))
{
it++;
}
last = it - 1;
if(first != last)
{
if((last + 1) != str.end())
{
str.erase(first, last + 1);
}
else
{
str.erase(first, str.end());
break;
}
}
}
}
std::cout<< str << std::endl;
return 0;
}
The output:
$ ./erase
ghhudndn^g
How can I split a string on multiple multi-character delimiters?
I want a function like vector<string> split_string(string input, vector<string> delims)
For example, split_string("foo+bar := baz",{"+"," ",":="}) = {"foo","+","bar"," "," ",":="," ","baz"}
My cut at the same. I chose to go with divide and conquer. It is not fast. It is not efficient. But it is simple.
Unfortunately it didn't work in this case because we are preserving the delimiters in the output. Dividing allowed later delimiters to split previously found delimiters.
Eg:
Source :=foo+bar . :=baz+quaax:= C++
Delims [+][ ][:=][:]
Result [:][=][foo][+][bar][ ][ ][.][ ][ ][ ][:][=][baz][+][quaax][:][=][ ][ ][C][+][+]
Yuck.
Finally settled on a similar approach to jafar's and added it to my support library to try out in a job I'm working on to replace the divide and conquer approach because it does look to be faster. Wouldn't have bothered posting this, but Jafar's is a bit over complicated for my tastes. Haven't done any profiling so his may be faster.
#include <iostream>
#include <vector>
// easy vector output
template<class TYPE>
std::ostream & operator<<(std::ostream & out,
const std::vector<TYPE> & in)
{
for (const TYPE &val: in)
{
out << "["<< val << "]";
}
return out;
}
// find the first of many string delimiters
size_t multifind(size_t start,
const std::string & source,
const std::vector<std::string> &delims,
size_t & delfound)
{
size_t lowest = std::string::npos;
for (size_t i = 0; i < delims.size(); i++)
{
size_t pos = source.find(delims[i], start);
if (pos == start)
{
lowest = pos;
delfound = i;
break;
}
else if (pos < lowest)
{
lowest = pos;
delfound = i;
}
}
return lowest;
}
// do the grunt work
std::vector<std::string> splitString(const std::string &source,
const std::vector<std::string> &delims)
{
std::vector<std::string> tokens;
size_t current = 0;
size_t delfound;
size_t next = multifind(current,
source,
delims,
delfound);
while(next != std::string::npos)
{
if (current < next)
{
tokens.push_back(source.substr(current, next - current));
}
tokens.push_back(delims[delfound]);
current = next + delims[delfound].length();
next = multifind(current,
source,
delims,
delfound);
}
if (current < source.length())
{
tokens.push_back(source.substr(current, std::string::npos));
}
return tokens;
}
void test(const std::string &source,
const std::vector<std::string> &delims)
{
std::cout << "Source " << source << std::endl;
std::cout << "Delims " << delims << std::endl;
std::cout << "Result " << splitString(source, delims) << std::endl << std::endl;
}
int main()
{
test(":=foo+bar . :=baz+quaax:= C++", { " ",":=","+" });
test(":=foo+bar . :=baz+quaax:= C++", { ":=","+"," " });
test(":=foo+bar . :=baz+quaax:= C++", { "+"," ",":=" });
test(":=foo+bar . :=baz+quaax:= C++", { "+"," ",":=",":" });
test(":=foo+bar . :=baz+quaax:= C++", { ":"," ",":=","+" });
test("foo+bar . :=baz+quaax:= C++lalala", { "+"," ",":=",":" });
}
Try this
#include <iostream>
#include <string>
#include <vector>
#include <map>
std::vector<std::string> splitString(std::string input, std::vector<std::string> delimeters);
std::string findFirstOf(std::string input, std::vector<std::string> del);
int main()
{
std::vector<std::string> words = splitString(":=foo+bar :=baz+quaax", { " ",":=","+" });
for (std::string str : words)
std::cout << str << ",";
std::cout << std::endl;
system("pause");
}
std::vector<std::string> splitString(std::string input, std::vector<std::string> delimeters)
{
std::vector<std::string> result;
size_t pos = 0;
std::string token;
std::string delimeter = findFirstOf(input, delimeters);
while(delimeter != "")
{
if ((pos = input.find(delimeter)) != std::string::npos)
{
token = input.substr(0, pos);
result.push_back(token);
result.push_back(delimeter);
input.erase(0, pos + delimeter.length());
}
delimeter = findFirstOf(input, delimeters);
}
result.push_back(input);
return result;
}
//find the first delimeter in the string
std::string findFirstOf(std::string input, std::vector<std::string> del)
{
//get a map of delimeter and position of delimeter
size_t pos;
std::map<std::string, size_t> m;
for (int i = 0; i < del.size(); i++)
{
pos = input.find(del[i]);
if (pos != std::string::npos)
m[del[i]] = pos;
}
//find the smallest position of all delimeters i.e, find the smallest value in the map
if (m.size() == 0)
return "";
size_t v = m.begin()->second;
std::string k = m.begin()->first;
for (auto it = m.begin(); it != m.end(); it++)
{
if (it->second < v)
{
v = it->second;
k = it->first;
}
}
return k;
}
output: ,:=,foo,+,bar, ,,:=,baz,+,quaax,.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I tokenize a string in C++?
Splitting a string in C++
Is there any python.split(",") like method in C++ please.
Got the following code from some where .. might help
#define MAIN 1
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class splitstring : public string {
vector<string> flds;
public:
splitstring(char *s) : string(s) { };
vector<string>& split(char delim, int rep=0);
};
vector<string>& splitstring::split(char delim, int rep) {
if (!flds.empty()) flds.clear();
string work = data();
string buf = "";
int i = 0;
while (i < work.length()) {
if (work[i] != delim)
buf += work[i];
else if (rep == 1) {
flds.push_back(buf);
buf = "";
} else if (buf.length() > 0) {
flds.push_back(buf);
buf = "";
}
i++;
}
if (!buf.empty())
flds.push_back(buf);
return flds;
}
#ifdef MAIN
main()
{
splitstring s("Humpty Dumpty sat on a wall. Humpty Dumpty had a great fall");
cout << s << endl;
vector<string> flds = s.split(' ');
for (int k = 0; k < flds.size(); k++)
cout << k << " => " << flds[k] << endl;
cout << endl << "with repeated delimiters:" << endl;
vector<string> flds2 = s.split(' ', 1);
for (int k = 0; k < flds2.size(); k++)
cout << k << " => " << flds2[k] << endl;
}
#endif
In boost:
vector<string> results;
boost::split(results, line, boost::is_any_of("#"));
In STL:
template <typename E, typename C>
size_t split(std::basic_string<E> const& s, C &container,
E const delimiter, bool keepBlankFields = true) {
size_t n = 0;
std::basic_string<E>::const_iterator it = s.begin(), end = s.end(), first;
for (first = it; it != end; ++it) {
if (delimiter == *it) {
if (keepBlankFields || first != it) {
container.push_back(std::basic_string<E > (first, it));
++n;
first = it + 1;
} else ++first;
}
}
if (keepBlankFields || first != it) {
container.push_back(std::basic_string<E > (first, it));
++n;
}
return n;
}