2016-07-14 2 views
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; 
} 

  • Проблема в том, что делает пользовательский Functor Проблема заключается в том, что у меня есть новый порядок элементов (вместо простого а-г). // Сохранено в порядке массива
  • Все, что я хочу, - это упорядочить заданные строки на основе нового порядка.
  • , например: Заказ: bacdefghijklmnopqrstuvwxyz Итак, если строки ss, aa, bb Новый заказ будет bb, aa, ss.
  • Код работает нормально, но это дает мне проблему, в то время как строки похожи на «pas» «p» для сравнения. p должен прийти до того, как он появится, но он наступит после.
  • Какие изменения следует делать в функторе?
+0

«* для например: Заказ: bacdefghijklmnopqrstuvwxyz Так что, если строки сс, аа, бб Нового упорядочения будут аа, бб , ss. * «Почему бы не быть« bb, aa, ss », учитывая, что' b' предшествует 'a'? – ildjarn

+0

Извините, мне плохо. –

+1

У вас есть потенциальное неопределенное поведение, если вы сравниваете одинаковые строки. Вам не хватает 'if (i == j) return 0;' before 'i ++' в вашем цикле. – HolyBlackCat

ответ

1

Вот один подход:

#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