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

  • 問題在使自定義函子 的問題是,我有元件(而不是簡單的A-Z)的一個新的訂單。 //保存在訂單數組中
  • 我要的只是訂購基於新訂單的給定字符串。
  • 例如:命令是:bacdefghijklmnopqrstuvwxyz 所以如果字符串是ss,aa,bb 新的排序將是bb,aa,ss。
  • 該代碼工作正常,但它給我一個問題,而字符串像「pas」「p」進行比較。 p應該在pas之前來,但它會在之後。
  • 我應該在函子中做些什麼修改?
+0

「*作如:順序是:bacdefghijklmnopqrstuvwxyz因此,如果字符串SS,AA,BB的新的排序將是AA,BB ,ss。*「爲什麼它不是'bb,aa,ss',因爲'b'在'a'之前? – ildjarn

+0

對不起,我的壞。 –

+1

如果比較相同的字符串,則可能存在未定義的行爲。如果(i == j)在你的循環中返回0;''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