position comparing two strings

258 views Asked by At

I need to I calculate the difference between 2 text strings based on the position of each character in each string. I need to come up with the removed and the inserted text from one string to the next. So for example comparing 'Caty' vs. 'Bat ' should indicate that 'C' in position 1 was removed, 'y' in position 4 was removed and 'B' was inserted at position 1 and 2 spaces were inserted at position 4.

I tried the following, however the sequences are not ordered and visual C++ indicates so in a popup dialog with iterator debugging enabled. I could sort them prior to applying the set difference operations, however that would not be what I am looking for. Ideally I would like to do this with simple std::strings vs. vectors of chars but I suspect that I may have to stick to either vectors of chars or std::vector>

std::vector<char> cat = {'C', 'a', 't', 'y'};
std::vector<char> bat = {'B', 'a', 't', ' ', ' '};
std::vector<char> removed;
std::set_difference(
    bat.begin(), bat.end(),
    cat.begin(), cat.end(),
    std::back_inserter(removed));
std::cout << removed << std::endl;
std::vector<char> inserted;
std::set_difference(
    bat.begin(), bat.end(),
    cat.begin(), cat.end(),
    std::back_inserter(inserted));
std::cout << inserted << std::endl;

Next I tried this - which worked - however it forces me to use sets which seems like overkill - there must be a simpler way to do something similar with strings.

std::set<std::pair<int, char>> cat = {{0, 'C'}, {1, 'a'}, {2, 't'}, {3, 'y'}};
std::set<std::pair<int, char>> bat = {{0, 'B'}, {1, 'a'}, {2, 't'}, {3, ' '}, {4, ' '}};
std::set<std::pair<int, char>> removed;
std::set_difference(
    cat.begin(), cat.end(),
    bat.begin(), bat.end(),
    std::inserter(removed, removed.end()));
//std::cout << removed << std::endl;
std::set<std::pair<int, char>> inserted;
std::set_difference(
    bat.begin(), bat.end(),
    cat.begin(), cat.end(),
    std::inserter(inserted, inserted.end()));
//std::cout << inserted << std::endl;
1

There are 1 answers

0
Biggy Smith On

this may be of use:

std::vector<std::pair<unsigned,char>> string_diff(const std::string& stra,const std::string& strb) {
    unsigned p = 1;
    std::vector<std::pair<unsigned,char>> ret;
    std::for_each(stra.begin(), stra.end(),[&](const char l) {
        if(strb.find(l) == std::string::npos) {
            ret.push_back(std::make_pair(p,l));
        }
        p++;
    });

    return ret;
}

std::string cat = "caty";
std::string bat = "bat  ";

auto removed = string_diff(cat,bat);
print(removed );

auto inserted = string_diff(bat,cat);
print(inserted);