📄 gstring.cpp
字号:
// test character string manipulation library and string list#define WANT_STREAM#define WANT_MATH#include "include.h"#include "str.h"#include "gstring.h"// ************************ Generalised String functions **********************PlusGString GString::operator+(const GString& g) { return PlusGString(this, &g); }GTGString GString::operator>(const GString& g) { return GTGString(this, &g); }GTGString2 GTGString::operator>(const GString& g) { return GTGString2(this, &g); }GTGString2 GTGString2::operator>(const GString& g) { return GTGString2(this, &g); }LTGString GString::operator<(const GString& g) { return LTGString(this, &g); }AndGString GString::operator&(const GString& g) { return AndGString(this, &g); }OrGString GString::operator|(const GString& g) { return OrGString(this, &g); }XorGString GString::operator^(const GString& g) { return XorGString(this, &g); }NotGString GString::operator~() { return NotGString(this); }bool ExplicitString::Matches(const String& s){ Tracer TR("ExplicitString::Matches"); return S == s;}bool AndGString::Matches(const String& s){ Tracer TR("AndGString::Matches"); return ((GString*&)G1)->Matches(s) && ((GString*&)G2)->Matches(s);}bool OrGString::Matches(const String& s){ Tracer TR("OrGString::Matches"); if (((GString*&)G1)->Matches(s)) { which = 1; return true; } if (((GString*&)G2)->Matches(s)) { which = 2; return true; } return false;}bool XorGString::Matches(const String& s){ Tracer TR("XorGString::Matches"); bool b1 = ((GString*&)G1)->Matches(s); bool b2 = ((GString*&)G2)->Matches(s); if (b1 && !b2) { which = 1; return true; } if (!b1 && b2) { which = 2; return true; } return false;}bool PlusGString::Matches(const String& s){ Tracer TR("PlusGString::Matches"); unsigned int n = s.size(); unsigned int n1 = G1->FixedLength(); unsigned int n2 = G2->FixedLength(); // if either of strings is of fixed length no iteration is necessary if (n1 != String::npos) { if (n1 > n) return false; split = n1; return ((GString*&)G1)->Matches(s.substr(0,n1)) && ((GString*&)G2)->Matches(s.substr(n1,n-n1)); } if (n2 != String::npos) { if (n2 > n) return false; split = n - n2; return ((GString*&)G1)->Matches(s.substr(0,n-n2)) && ((GString*&)G2)->Matches(s.substr(n-n2,n2)); } // divide s into a first part to match G1 and a second part to match G2 // iterate over division points if (G1->ShortLong() <= 0 && G2->ShortLong() >= 0) { for (unsigned int i = 0; i <= n; i++) if ( ((GString*&)G1)->Matches(s.substr(0,i)) && ((GString*&)G2)->Matches(s.substr(i,n-i)) ) { split = i; return true; } return false; } else { for (int i = n; i >= 0; i--) if ( ((GString*&)G1)->Matches(s.substr(0,i)) && ((GString*&)G2)->Matches(s.substr(i,n-i)) ) { split = i; return true; } return false; }}bool GTGString::Matches(const String& s){ Tracer TR("GTGString::Matches"); unsigned int n = s.size(); unsigned int n1 = G1->FixedLength(); unsigned int n2 = G2->FixedLength(); // if first of strings is of fixed length no iteration is necessary if (n1 != String::npos) { if (n1 > n) return false; split = n1; return ((GString*&)G1)->Matches(s.substr(0,n1)) && ((GString*&)G2)->Matches(s.substr(n1,n-n1)); } if (n2 != String::npos) { if ( !(((GString*&)G1)->Matches(s.substr(0,n-n2)) && ((GString*&)G2)->Matches(s.substr(n-n2,n2))) ) return false; } // divide s into a first part to match G1 and a second part to match G2 // iterate over division points if (G1->ShortLong() <= 0) { int m = (n2 != String::npos) ? n-n2 : n; for (int i = 0; i <= m; i++) if ( ((GString*&)G1)->Matches(s.substr(0,i)) ) { if ( ((GString*&)G2)->Matches(s.substr(i,n-i)) ) { split = i; return true; } return false; } return false; } else { int m = (n2 != String::npos) ? n-n2 : 0; for (int i = n; i >= m; i--) if ( ((GString*&)G1)->Matches(s.substr(0,i)) ) { if ( ((GString*&)G2)->Matches(s.substr(i,n-i)) ) { split = i; return true; } return false; } return false; }}// we are starting the match at location ix and we allow some of the// string to be left overbool GTGString::Matches_i(const String& s, unsigned int& ix){ Tracer TR("GTGString::Matches_i"); unsigned int n = s.size(); unsigned int n1 = G1->FixedLength(); unsigned int n2 = G2->FixedLength(); // first string if (n1 != String::npos) // G1 of fixed length { if (n1 > n-ix) return false; if ( !((GString*&)G1)->Matches(s.substr(ix,n1)) ) return false; split = n1; ix += n1; } else if (G1->ShortLong() <= 0) { int m = (n2 != String::npos) ? n-ix-n2 : n-ix; bool found = false; for (int i = 0; i <= m; i++) if ( ((GString*&)G1)->Matches(s.substr(ix,i)) ) { found = true; split = i; ix += i; break; } if (!found) return false; } else { int m = (n2 != String::npos) ? n-ix-n2 : ix; bool found = false; for (int i = n; i >= m; i--) if ( ((GString*&)G1)->Matches(s.substr(ix,i)) ) { found = true; split = i; ix += i; break; } if (!found) return false; } // now do second string if (n2 != String::npos) // G2 of fixed length { if (n2 > n-ix) return false; if ( !((GString*&)G2)->Matches(s.substr(ix,n2)) ) return false; ix += n2; } else if (G2->ShortLong() <= 0) { int m = n-ix; bool found = false; for (int i = 0; i <= m; i++) if ( ((GString*&)G2)->Matches(s.substr(ix,i)) ) { found = true; ix += i; break; } if (!found) return false; } else { int m = ix; bool found = false; for (int i = n; i >= m; i--) if ( ((GString*&)G2)->Matches(s.substr(ix,i)) ) { found = true; ix += i; break; } if (!found) return false; } return true;}bool GTGString2::Matches(const String& s){ Tracer TR("GTGString2::Matches"); unsigned int ix = 0; unsigned int n = s.size(); // first string unsigned int i = ix; if ( !((GString*&)G1)->Matches_i(s.substr(i,n-i), ix) ) return false; split = ix - i; // now do second string return ((GString*&)G2)->Matches(s.substr(ix,n-ix));}bool GTGString2::Matches_i(const String& s, unsigned int& ix){ Tracer TR("GTGString2::Matches_i"); unsigned int n = s.size(); unsigned int n2 = G2->FixedLength(); // first string int i = ix; if ( !((GString*&)G1)->Matches_i(s.substr(i,n-i), ix) ) return false; split = ix - i; // now do second string if (n2 != String::npos) // G2 of fixed length { if (n2 > n-ix) return false; if ( !((GString*&)G2)->Matches(s.substr(ix,n2)) ) return false; ix += n2; } else if (G2->ShortLong() <= 0) { int m = n-ix; bool found = false; for (int i = 0; i <= m; i++) if ( ((GString*&)G2)->Matches(s.substr(ix,i)) ) { found = true; ix += i; break; } if (!found) return false; } else { int m = ix; bool found = false; for (int i = n; i >= m; i--) if ( ((GString*&)G2)->Matches(s.substr(ix,i)) ) { found = true; ix += i; break; } if (!found) return false; } return true;}bool LTGString::Matches(const String& s){ Tracer TR("LTGString::Matches"); unsigned int n = s.size(); unsigned int n1 = G1->FixedLength(); unsigned int n2 = G2->FixedLength(); // if second of strings is of fixed length no iteration is necessary if (n2 != String::npos) { if (n2 > n) return false; split = n - n2; return ((GString*&)G1)->Matches(s.substr(0,n-n2)) && ((GString*&)G2)->Matches(s.substr(n-n2,n2)); } if (n1 != String::npos) { if ( !(((GString*&)G1)->Matches(s.substr(0,n1)) && ((GString*&)G2)->Matches(s.substr(n1,n-n1))) ) return false; } // divide s into a first part to match G1 and a second part to match G2 // iterate over division points if (G2->ShortLong() >= 0) { int m = (n1 != String::npos) ? n1 : n; for (int i = 0; i <= m; i++) if ( ((GString*&)G2)->Matches(s.substr(i,n-i)) ) { if ( ((GString*&)G1)->Matches(s.substr(0,i)) ) { split = i; return true; } return false; } return false; } else { int m = (n1 != String::npos) ? n1 : 0; for (int i = n; i >= m; i--) if ( ((GString*&)G2)->Matches(s.substr(i,n-i)) ) { if ( ((GString*&)G1)->Matches(s.substr(0,i)) ) { split = i; return true; } return false; } return false; }}bool NotGString::Matches(const String& s) { return ! ((GString*&)G)->Matches(s); }bool AnyString::Matches(const String& s) { S = s; return true; }bool FixedLengthString::Matches(const String& s){ if (s.size() == N) { S = s; return true; } else { S = ""; return false; }}bool Dots::Matches(const String&) { return true; }bool FixedLengthDots::Matches(const String& s){ return (s.size() == N);}bool WhiteSpace::Matches(const String& s){ if (s.size() == 0) return false; return s.find_first_not_of(" \t\r\n") == String::npos;}bool OptionalWhiteSpace::Matches(const String& s){ if (s.size() == 0) return true; return s.find_first_not_of(" \t\r\n") == String::npos;}void GString::Collect(const String& s, StringList& SL) { SL.push_back(s); }void AndGString::Collect(const String& s, StringList& SL){ Tracer TR("AndGString::Collect"); ((GString*&)G1)->Collect(s, SL); ((GString*&)G2)->Collect(s, SL);}void OrGString::Collect(const String& s, StringList& SL){ Tracer TR("OrGString::Collect"); if (which == 1) { SL.push_back("1"); ((GString*&)G1)->Collect(s, SL); } else if (which == 2) { SL.push_back("2"); ((GString*&)G2)->Collect(s, SL); }}void XorGString::Collect(const String& s, StringList& SL){ Tracer TR("XorGString::Collect"); if (which == 1) { SL.push_back("1"); ((GString*&)G1)->Collect(s, SL); } else if (which == 2) { SL.push_back("2"); ((GString*&)G2)->Collect(s, SL); }}void PlusGString::Collect(const String& s, StringList& SL){ Tracer TR("PlusGString::Collect"); ((GString*&)G1)->Collect(s.substr(0,split), SL); ((GString*&)G2)->Collect(s.substr(split,s.size()-split), SL);}void GString::Translate(String& s, StringList& SL) { s += SL.pop_front(); }void ExplicitString::Translate(String& s, StringList& SL) { s += S; SL.pop_front(); }void AndGString::Translate(String& s, StringList& SL) { ((GString*&)G1)->Translate(s, SL); ((GString*&)G2)->Translate(s, SL); }void OrGString::Translate(String& s, StringList& SL){ String w = SL.pop_front(); if (w == "1") ((GString*&)G1)->Translate(s, SL); else if (w == "2") ((GString*&)G2)->Translate(s, SL);}void XorGString::Translate(String& s, StringList& SL){ String w = SL.pop_front(); if (w == "1") ((GString*&)G1)->Translate(s, SL); else if (w == "2") ((GString*&)G2)->Translate(s, SL);}void PlusGString::Translate(String& s, StringList& SL) { ((GString*&)G1)->Translate(s, SL); ((GString*&)G2)->Translate(s, SL); }void NotGString::Translate(String&, StringList& SL) { SL.pop_front(); }void AnyString::Translate(String& s, StringList& SL) { s += S; SL.pop_front(); }int PairGString::ShortLong() const{ if (G1->ShortLong() == G2->ShortLong()) return G1->ShortLong(); if (G1->ShortLong() <= 0 && G2->ShortLong() <= 0) return -1; if (G1->ShortLong() >= 0 && G2->ShortLong() >= 0) return 1; return 0;}unsigned int AndGString::FixedLength() const{ if (G1->FixedLength() == G2->FixedLength()) return G1->FixedLength(); if (G1->FixedLength() == String::npos) return G2->FixedLength(); if (G2->FixedLength() == String::npos) return G1->FixedLength(); return String::npos;}unsigned int OrGString::FixedLength() const{ if (G1->FixedLength() == G2->FixedLength()) return G1->FixedLength(); else return String::npos;}unsigned int XorGString::FixedLength() const{ if (G1->FixedLength() == G2->FixedLength()) return G1->FixedLength(); else return String::npos;}unsigned int PlusGString::FixedLength() const{ if (G1->FixedLength() != String::npos && G2->FixedLength() != String::npos) return G1->FixedLength() + G2->FixedLength(); else return String::npos;}// globals - declarationsInitialGString GS;Dots DOTS;LongestDots LDOTS;ShortestDots SDOTS;FixedLengthDots DOT(1); // single characterWhiteSpace WS;OptionalWhiteSpace OWS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -