/*************************************************************************
    > File Name: CharFilter.h
    > Author: wangzhicheng
    > Created Time: 2017-01-13
    > Statement: input a string such as 12###12,34,,,@@12@
                 if you give a blank char to substitute for # , and @
                 output 12 12 34 12
 ************************************************************************/
#ifndef CHAT_FILTER_H
#define CHAT_FILTER_H
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <vector>
#include <string>
#include <bitset>
#include <algorithm>
namespace charfilter
{
using namespace std;
static const int ASCIILEN = 256;
class CharFilter
{
private:
    char m_ReplacedChar;
//    vector<int>m_vecHashHit;    // 0 -- this position does not contain the filter character
    bitset<ASCIILEN>m_vecHashHit;    // 0 -- this position does not contain the filter character
public:
    /*
     * @brief construct m_vecHashHit
     * */
    CharFilter(const vector<char>&, char ch);
    /*
     * @brief filter the string
     * */
    void Filter(string &);
};
}

#endif


/*************************************************************************
    > File Name: CharFilter.cpp
    > Author: wangzhicheng
    > Created Time: 2017-01-13
    > Statement: input a string such as 12###12,34,,,@@12@
                 if you give a blank char to substitute for # , and @
                 output 12 12 34 12
 ************************************************************************/
#include "CharFilter.h"
namespace charfilter
{
/*
 * @brief construct m_vecHashHit
 * @filterchars include the characters which should be filtered
 * @ch the substitued char such as blank character
 * */
CharFilter::CharFilter(const vector<char>&filterchars, char ch)
{
    int i;
    int size = filterchars.size();
//    m_vecHashHit.resize(ASCIILEN);
    // init the m_vecHashHit
    for(i = 0;i < size;i++)
    {
        int index = filterchars[i];
        if(index >= 0 && index < ASCIILEN) m_vecHashHit[index] = 1;
    }
    m_ReplacedChar = ch;
}
/*
 * @brief filter the string
 * */
void CharFilter::Filter(string &str)
{
    // for_each the string
    for_each(str.begin(), str.end(), [this](char &ch)
            {
            if(ch >= 0 && ch < ASCIILEN && this->m_vecHashHit[ch])
            {
                ch = this->m_ReplacedChar;
            }
            });
    // cope with the repeated replaced character
    string::iterator it = unique(str.begin(), str.end(), [this](char ch0, char ch1)
            {
            return (this->m_ReplacedChar == ch0) && (this->m_ReplacedChar == ch1);
            });
    str.erase(it, str.end());
}
}


/*************************************************************************
    > File Name: main.cpp
    > Author: wangzhicheng     >
    > Created Time: Thu 12 Jan 2017 10:17:12 PM AWST
 ************************************************************************/

#include <iostream>
#include "CharFilter.h"
using namespace charfilter;
int main()
{
    vector<char>chs;
    chs.push_back('#');
    chs.push_back('@');
    chs.push_back(',');
    CharFilter cf(chs, ' ');
    string str;
    getline(cin, str);
    cout << "before filter str = " << str << endl;
    cf.Filter(str);
    cout << "after filter str = " << str << endl;

    return 0;
}

CC=g++
all:
    $(CC) -std=c++11 -g -o TestFilterChar CharFilter.h CharFilter.cpp main.cpp