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

  • Problem bei der Herstellung des Custom Functor Das Problem ist, habe ich eine neue Ordnung der Elemente (anstelle von einfachen a-z). // Gespeichert im Auftragarray
  • Alles, was ich will, ist, die gegebenen Zeichenketten auf der Grundlage der neuen Ordnung zu bestellen.
  • für zB: Bestellung ist: bacdefghijklmnopqrstuvwxyz Also, wenn die Saiten sind ss, aa, bb Die neue Reihenfolge wird bb, aa, ss sein.
  • Der Code funktioniert gut, aber es gibt mir ein Problem, während die Zeichenfolgen wie "pas" "p" verglichen werden sollen. p sollte vor pas kommen, aber es kommt nach.
  • Welche Änderungen soll ich im Funktor machen?
+0

„* für zB: Bestellen: bacdefghijklmnopqrstuvwxyz Also, wenn die Saiten ss, aa, bb Die neue Bestellung aa sein wird, bb , ss. * "Warum sollte es nicht sein?" bb, aa, ss, wenn "b" vor "a" steht? – ildjarn

+0

Tut mir leid, mein Schlechter. –

+1

Sie haben ein potenziell undefiniertes Verhalten, wenn Sie dieselben Zeichenfolgen vergleichen. Sie vermissen 'if (i == j) geben 0 zurück; vor 'i ++' in Ihrer Schleife. – HolyBlackCat

Antwort

1

Hier ist ein Ansatz:

#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