3
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
int order[26];
struct lexcmp
{
    bool operator()(const string &s1,const string &s2)
    {
        int i=0;
        int j=min(s1.size(),s2.size());
        while(1)
        {
            if(order[s1[i]-'a']<order[s2[i]-'a'])
            return true;
            if(order[s1[i]-'a']>order[s2[i]-'a'])
            return false;
            if(i==j-1)
            return false;
            i++;
        }
    }
};
int main()
{
        string s;
        cin>>s;
        for(int i=0;i<s.size();i++)
        {
            order[s[i]-'a']=i;
        }
        set<string,lexcmp> store;
        int m;
        cin>>m;
        while(m--)
        {
            string q;
            cin>>q;
            store.insert(q);
        }
        for(auto i=store.begin();i!=store.end();i++)
        {
            cout<<*i<<endl;
        }
    }
    return 0;
}

  • Problem in making the Custom Functor The problem is, i have a new order of elements (instead of simple a-z). //Saved in order array
  • All i want is order the given strings on the based of new order.
  • for eg: Order is : bacdefghijklmnopqrstuvwxyz So if the strings are ss , aa , bb The new ordering will be bb,aa,ss.
  • The Code is working fine but it is giving me a problem while the strings are like "pas" "p" to be compared. p should come before pas but it is coming after.
  • What modifications should i do in the functor?
Crosk Cool
  • 664
  • 2
  • 12
  • 27
  • "*for eg: Order is : bacdefghijklmnopqrstuvwxyz So if the strings are ss , aa , bb The new ordering will be aa,bb,ss.*" Why would it not be `bb,aa,ss` given that `b` comes before `a`? – ildjarn Jul 14 '16 at 10:01
  • 1
    You have a potential undefined behavior if you compare same strings. You're missing `if (i == j) return 0;` before `i++` in your loop. – HolyBlackCat Jul 14 '16 at 10:13
  • Perhaps your `lexcmp` also need to handle the case where both strings are equal. – nos Jul 14 '16 at 10:13
  • @HolyBlackCat I actually had that comparison if(i==j-1)return true. But it wasn't suffice to solve the problem. – Crosk Cool Jul 14 '16 at 10:23

1 Answers1

1

Here's one approach:

#include <cassert>
#include <cstddef>
#include <cstdint>
#include <algorithm>
#include <numeric>
#include <array>
#include <string>
#include <locale>

struct lexcmp {
    lexcmp() { std::iota(order_.begin(), order_.end(), std::int_fast8_t{}); }
    explicit lexcmp(std::string const& order) {
        assert(order.size() == order_.size());

        for (std::size_t i{}; i != order_.size(); ++i) {
            char const order_letter = order[i];
            assert(std::isalpha(order_letter, std::locale::classic()));
            assert(std::islower(order_letter, std::locale::classic()));
            order_[i] = order_letter - 'a';
        }

        auto unique_order_letters = [this]{
            auto order = order_;
            std::sort(order.begin(), order.end());
            return order.end() - std::unique(order.begin(), order.end()) == 0;
        };
        assert(unique_order_letters());
    }

    bool operator ()(std::string const& a, std::string const& b) const {
        auto const a_len = a.size(), b_len = b.size();
        std::size_t i{};
        for (auto const len = std::min(a_len, b_len); i != len; ++i) {
            if (auto const diff = order_[a[i] - 'a'] - order_[b[i] - 'a']) {
                return diff < 0;
            }
        }
        return i == a_len && i != b_len;
    }

private:
    std::array<std::int_fast8_t, 26> order_;
};

Online Demo

ildjarn
  • 62,044
  • 9
  • 127
  • 211