huffman coding using stl and without nodes c++ - c++

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.

Related

I got the error 'variable has incomplete type 'void'', and I can't find what's wrong

I had to count the words of a vector and put it in a map that counts the words. Then the function showFrequencies has to show/print the map.
map<string, int>CountWords(vector<string> words) {
map<string, int> count;
for(auto i = words.begin(); i != words.end(); i++) {
count[*i]++;
}
return count;
}
void showFrequencies(CountWords(vector<string> name)) {
for (map<string, int>::const_iterator it = count.begin(); it !=
count.end(); ++it) {
cout << it->first << "\t" << it->second;}
}
int main(){
vector<string> words = {"hello", "you", "hello", "me", "chipolata", "you"};
showFrequencies(CountWords(words));
return 0;
}
void showFrequencies(CountWords(vector<string> name)) {
should be
void showFrequencies(const map<string, int>& name) {

Solve linear equation with Maps

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;
}

how to access vector of map of ( int and vector of strings )

how do i access map of int and vectors of string in the passed_vector function.
I just want to print them in that function.
#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;
typedef vector< map< int, vector<string> > > vmis;
typedef map< int, vector<string> > mis;
typedef vector<string> vstr;
void passing_vector(const vmis &meetings);
//return size of vector
template< typename A > size_t n_elements( const A& a )
{
return sizeof a / sizeof a[ 0 ];
}
int main()
{
vmis meeting_info;
mis meeting_members;
vstr sw_vec;
vstr sys_vec;
string sw_team[] = {"Ricky", "John", "David"};
string sys_team[] = {"Simmon", "Brad", "Schmidt", "Fizio"};
sw_vec.insert(sw_vec.begin(), sw_team, sw_team + n_elements(sw_team) );
sys_vec.insert(sys_vec.begin(), sys_team, sys_team + n_elements(sys_team) );
meeting_members.insert(make_pair(520, sw_vec));
meeting_members.insert(make_pair(440, sys_vec));
meeting_info.push_back(meeting_members);
passing_vector(meeting_info);
return 0;
}
void passing_vector(const vmis &meetings)
{
vmis::iterator itvmis = meetings.begin();
//how do i access map of int and vectors of string.
//I just want to print them.
}
I know how to print them in main function.
vmis::iterator itvims = meeting_info.begin();
for( int i = 0; i < meeting_info.size(); i++ )
{
mis::iterator itm = meeting_members.begin();
for(itm; itm != meeting_members.end(); itm++ )
{
cout << itm->first << " : ";
vstr::iterator it = itm->second.begin();
for(it; it != itm->second.end(); it++)
cout << *it << " ";
cout << endl;
}
}
desired output
440 : Simmon Brad Schmidt Fizio
520 : Ricky John David
if there is a better way of doing this suggestions are always welcome.
The easiest aproach is to use auto, also since your meetings is const, you need to use const_iterator:
void passing_vector(const vmis &meetings)
{
vmis::const_iterator itvims = meetings.begin();
//how do i access map of int and vectors of string.
//I just want to print them.
for (;itvims != meetings.end(); ++itvims)
{
const auto& map_item = *itvims;
for (const auto& map_it : map_item)
{
int map_key = map_it.first;
const auto& str_vec = map_it.second;
for (const auto& str : str_vec)
{
std::cout << map_key << " - " << str << "\n";
}
}
}
}
[edit]
c++98 version:
void passing_vector(const vmis &meetings)
{
vmis::const_iterator itvims = meetings.begin();
//how do i access map of int and vectors of string.
//I just want to print them.
for (;itvims != meetings.end(); ++itvims)
{
const mis& map_item = *itvims;
for (mis::const_iterator map_it = map_item.begin(); map_it != map_item.end(); ++map_it)
{
int map_key = map_it->first;
const vstr& str_vec = map_it->second;
for (vstr::const_iterator sitr = str_vec.begin(); sitr != str_vec.end(); ++sitr)
{
std::cout << map_key << " - " << *sitr << "\n";
}
}
}
}

Combination of lists by type algorithm

I'm attempting to create an algorithm in C++ which will give me all of the possible combinations of a set of list items (input in a map format). I want to avoid duplicates and make sure to cover all possible combinations. To simplify the example, here's what the input may look like:
map<string, vector<string> > sandwichMap;
sandwichMap["bread"].push_back("wheat");
sandwichMap["bread"].push_back("white");
sandwichMap["meat"].push_back("ham");
sandwichMap["meat"].push_back("turkey");
sandwichMap["meat"].push_back("roastbeef");
sandwichMap["veggie"].push_back("lettuce");
sandwichMap["sauce"].push_back("mustard");
I'd feed this map into the algorithm, and it should spit out a vector with all of the possible combinations (using one of each key type):
wheat+ham+lettuce+mustard
wheat+turkey+lettuce+mustard
wheat+roastbeef+lettuce+mustard
white+ham+lettuce+mustard
white+turkey+lettuce+mustard
white+roastbeef+lettuce+mustard
It needs to work for any map of string vectors. So far I've tried and gotten close, but I end up with duplicate combinations and missed combinations:
sandwichList getCombinations(sandwichMap sMap)
{
locList retList;
int totalCombos = 1;
for (sandwichMapIt i = sMap.begin(); i != sMap.end(); ++i)
{
totalCombos *= i->second.size();
}
retList.resize(totalCombos);
int locCount;
for (sandwichMapIt a = sMap.begin(); a != sMap.end(); ++a)
{
locCount = 0;
for (locListIt l = a->second.begin(); l != a->second.end(); ++l)
{
for (unsigned int i = 0; i < totalCombos / a->second.size(); ++i)
{
retList[i + a->second.size() * locCount] += *l;
}
locCount++;
}
}
return retList;
}
Any help would be greatly appreciated!
Updated code:
#include <vector>
#include <map>
#include <list>
#include <iostream>
typedef std::vector<std::string> strVec;
typedef std::list<std::string> strList;
typedef std::map<std::string, strVec> sandwichMap;
int main()
{
sandwichMap sMap;
sMap["bread"].push_back("wheat");
sMap["bread"].push_back("white");
sMap["meat"].push_back("ham");
sMap["meat"].push_back("turkey");
sMap["meat"].push_back("roastbeef");
sMap["veggie"].push_back("lettuce");
sMap["sauce"].push_back("mustard");
strList finalSandwichList;
for (sandwichMap::iterator i = sMap.begin(); i != sMap.end(); ++i)
{
strList tmpSandwich;
for (strVec::iterator j = i->second.begin(); j != i->second.end(); ++j)
{
if (finalSandwichList.empty())
{
tmpSandwich.push_back(*j);
}
else
{
for (strList::iterator k = finalSandwichList.begin(); k != finalSandwichList.end(); ++k)
tmpSandwich.push_back(*k + "+" + *j);
}
}
tmpSandwich.swap(finalSandwichList);
}
for (strList::iterator i = finalSandwichList.begin(); i != finalSandwichList.end(); ++i)
{
std::cout << *i << std::endl;
}
return 0;
}
//solution
std::list<std::string> result;
for(auto i=sandwichMap.begin(); i!=sandwichMap.end(); ++i) {
std::list<std::string> new_result;
for(auto j=i->second.begin(); j!=i->second.end(); ++j) {
if(result.empty())
new_result.push_back(*j);
else
for(auto k=result.begin(); k!=result.end(); ++k)
new_result.push_back(*k + "+" + *j);
}
new_result.swap(result);
}
This should work :
#include<iostream>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
map<string, vector<string>> sMap;
vector<string> add;
int sett[200], countt;
void solve(map<string, vector<string>>::iterator itt, int ct, vector<string> addd){
vector<string> tmp = itt->second;
if(ct == countt){
for(int j=0;j<addd.size();j++){
cout<<addd[j]<<" ";
}
cout<<endl;
return;
}
itt++;
for(int i=0;i<tmp.size();i++){
//cout<<tmp[i]<<" ";
addd.push_back(tmp[i]);
solve(itt, ct+1, addd);
vector<string>::iterator tempIt = addd.end();
addd.erase(tempIt--);
}
}
int main(){
sMap["bre"].push_back("wh");
sMap["bre"].push_back("whi");
sMap["me"].push_back("ham");
sMap["me"].push_back("tur");
sMap["me"].push_back("rr");
sMap["veg"].push_back("let");
sMap["sau"].push_back("mus");
countt = sMap.size();
solve(sMap.begin(), 0, add);
return 0;
}
I have used backtracking to evaluate every possible combination.
Note : it is in c++11 you might need to change some part of the code for lower version of c++
link to output : http://ideone.com/Ou2411
The code is kinda long because of the helper methods, but it does the job:
#include <vector>
#include <string>
#include <map>
#include <iostream>
using namespace std;
template <class T>
vector<T> Head(const vector<T> &v) {
return vector<T>(v.begin(), v.begin() + 1);
}
template <class T>
vector<T> Tail(const vector<T> &v) {
auto first = v.begin() + 1;
auto last = v.end();
return vector<T>(first, last);
}
template <class T>
vector<T> Concat(const vector<T> &v1, const vector<T> &v2) {
vector<T> result = v1;
result.insert(result.end(), v2.begin(), v2.end());
return result;
}
vector<vector<string>> CombineVectorWithScalar(const vector<vector<string>> &v, const string &scalar) {
vector<vector<string>> result = v;
for (unsigned i = 0; i < v.size(); i++) {
result[i].push_back(scalar);
}
return result;
}
vector<vector<string>> CombineVectorWithVector(const vector<vector<string>> &v1, const vector<string> &v2) {
if (v2.empty()) {
return vector<vector<string>>();
}
else {
auto headCombination = CombineVectorWithScalar(v1, v2.front());
auto tailCombination = CombineVectorWithVector(v1, Tail(v2));
return Concat(headCombination, tailCombination);
}
}
vector<string> GetKeys(const map<string, vector<string>> &mp) {
vector<string> keys;
for (auto it = mp.begin(); it != mp.end(); ++it) {
keys.push_back(it->first);
}
return keys;
}
vector<vector<string>> CombineMapValues(const map<string, vector<string>> &mp) {
vector<string> keys = GetKeys(mp);
vector<vector<string>> result;
auto &firstVector = mp.begin()->second;
for (auto it = firstVector.begin(); it != firstVector.end(); ++it) {
vector<string> oneElementList;
oneElementList.push_back(*it);
result.push_back(oneElementList);
}
vector<string> restOfTheKeys = Tail(keys);
for (auto it = restOfTheKeys.begin(); it != restOfTheKeys.end(); ++it) {
auto &currentVector = mp.find(*it)->second;
result = CombineVectorWithVector(result, currentVector);
}
return result;
}
void PrintCombinations(const vector<vector<string>> & allCombinations) {
for (auto it = allCombinations.begin(); it != allCombinations.end(); ++it) {
auto currentCombination = *it;
for (auto itInner = currentCombination.begin(); itInner != currentCombination.end(); ++itInner) {
cout << *itInner << " ";
}
cout << endl;
}
}
int main() {
map<string, vector<string> > sandwichMap;
sandwichMap["bread"].push_back("wheat");
sandwichMap["bread"].push_back("white");
sandwichMap["meat"].push_back("ham");
sandwichMap["meat"].push_back("turkey");
sandwichMap["meat"].push_back("roastbeef");
sandwichMap["veggie"].push_back("lettuce");
sandwichMap["sauce"].push_back("mustard");
auto allCombinations = CombineMapValues(sandwichMap);
PrintCombinations(allCombinations);
return 0;
}
void generate_all(std::map<std::string,std::vector<std::string>>::iterator start,
std::vector<std::string::iterator> accomulator,
std::map<std::string,std::vector<std::string>>& sMap){
for (auto it=start; it!=sMap.end(); ++it){
for (auto jt=it->second.begin(); jt!=it->second.end(); jt++){
generate_all(start+1,accomulator.pus_back[jt],sMap);
}
}
if (accomulator.size() == sMap.size()){
// print accomulator
}
}
Call with generate_all(sMap.begin(),aVector,sMap);
If the map is too big to go recursively, you can always generate an equivalent iterative code.
This solution is not recursive. Basically what it does is the following:
Compute how many combinations are actually possible
Know that for each key in the map, you're going to have to add nrCombinations/nrItemsInKey of them in total.
You can see it as a tree growing, branching more and more the more keys you have visited.
If you keep track of how many there are, how spaced they are and where they start you can automatically fill all combinations.
Code
#include <vector>
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, std::vector<std::string> > sandwichMap;
sandwichMap["bread"].push_back("wheat");
sandwichMap["bread"].push_back("white");
sandwichMap["meat"].push_back("ham");
sandwichMap["meat"].push_back("turkey");
sandwichMap["meat"].push_back("roastbeef");
sandwichMap["veggie"].push_back("lettuce");
sandwichMap["sauce"].push_back("mustard");
sandwichMap["sauce"].push_back("mayo");
// Compute just how many combinations there are
int combinationNr = 1;
for ( auto it : sandwichMap ) {
combinationNr *= it.second.size();
}
std::vector<std::vector<std::string>> solutions(combinationNr);
// We start with empty lists, thus we only have one cluster
int clusters = 1, clusterSize = combinationNr;
for ( auto category : sandwichMap ) {
int startIndex = 0;
int itemsNr = category.second.size();
int itemsPerCluster = clusterSize / itemsNr;
for ( auto item : category.second ) {
for ( int c = 0; c < clusters; ++c ) {
for ( int i = 0; i < itemsPerCluster; ++i ) {
// We sequentially fill each cluster with this item.
// Each fill starts offset by the quantity of items
// already added in the cluster.
solutions[startIndex+i+c*clusterSize].push_back(item);
}
}
startIndex += itemsPerCluster;
}
clusters *= itemsNr;
clusterSize = combinationNr / clusters;
}
for ( auto list : solutions ) {
for ( auto element : list ) {
std::cout << element << ", ";
}
std::cout << "\n";
}
return 0;
}

Python C++: is the any python.split() like method in c++? [duplicate]

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;
}