Inputer.cpp
上传用户:bingyunhe
上传日期:2013-07-06
资源大小:723k
文件大小:35k
源码类别:

词法分析

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. //#include "..ChineseInputer.h"
  3. #include "Inputer.h"
  4. #include "StreamUtils.h"
  5. namespace Chinese
  6. {
  7. //===============================================================================
  8. //
  9. //  笔顺类
  10. //
  11. //===============================================================================
  12. /**
  13. * 横
  14. */
  15. Word StrokesOrder::s_Heng(_T("一"));
  16. /**
  17. * 竖
  18. */
  19. Word StrokesOrder::s_Shu(_T("丨"));
  20. /**
  21. * 撇
  22. */
  23. Word StrokesOrder::s_Pie(_T("丿"));
  24. /**
  25. * 捺
  26. */
  27. Word StrokesOrder::s_Na(_T("丶"));
  28. /**
  29. * 折
  30. */
  31. Word StrokesOrder::s_Zhe(_T("乙"));
  32. /**
  33. * 横
  34. */
  35. TCHAR StrokesOrder::s_cHeng = TCHAR('1');
  36. /**
  37. * 竖
  38. */
  39. TCHAR StrokesOrder::s_cShu = TCHAR('2');;
  40. /**
  41. * 撇
  42. */
  43. TCHAR StrokesOrder::s_cPie = TCHAR('3');
  44. /**
  45. * 捺
  46. */
  47. TCHAR StrokesOrder::s_cNa = TCHAR('4');
  48. /**
  49. * 折
  50. */
  51. TCHAR StrokesOrder::s_cZhe = TCHAR('5');
  52. /*
  53. * 构造函数
  54. */
  55. StrokesOrder::StrokesOrder( const TCHAR* szOrders )
  56. {
  57. VERIFY( Set( szOrders ) );
  58. }
  59. /*
  60. * 初始化
  61. */
  62. BOOL StrokesOrder::Set( const TCHAR* szOrders )
  63. {
  64. ASSERT( szOrders );
  65. m_DigitStroks = _T("");
  66. int len = _tcslen(szOrders);
  67. // 如果是空字符, 返回真
  68. if ( len <= 0 )
  69. return TRUE;
  70. if ( szOrders[0] < 0 ) // 笔顺方式
  71. {
  72. ASSERT( len % 2 == 0 );
  73. TCHAR *szDigitOrder = new TCHAR[len/2+1];
  74. for ( int i=0; i<len; i+=2 )
  75. {
  76. Word dwCur(szOrders[i], szOrders[i+1]);
  77. TCHAR cCur;
  78. if ( dwCur == s_Heng )
  79. cCur = TCHAR('1');
  80. else if ( dwCur == s_Shu )
  81. cCur = TCHAR('2');
  82. else if ( dwCur == s_Pie )
  83. cCur = TCHAR('3');
  84. else if ( dwCur == s_Na )
  85. cCur = TCHAR('4');
  86. else if ( dwCur == s_Zhe )
  87. cCur = TCHAR('5');
  88. else
  89. ASSERT( FALSE );
  90. szDigitOrder[i/2] = cCur;
  91. }
  92. szDigitOrder[len/2] = TCHAR('');
  93. m_DigitStroks = szDigitOrder;
  94. delete [] szDigitOrder;
  95. }
  96. else // 数字方式
  97. m_DigitStroks = szOrders;
  98. return TRUE;
  99. }
  100. /*
  101. * 以笔画得方式返回
  102. */
  103. CString StrokesOrder::GetAsStroks() const
  104. {
  105. int nLength = GetLength();
  106. if ( nLength <= 0 )
  107. return CString(_T(""));
  108. // 转换
  109. CString strStroks(TCHAR(''), nLength*2+1);
  110. for ( int i=0; i<nLength; i++ )
  111. {
  112. TCHAR cLow, cHigh;
  113. switch ( m_DigitStroks[i] )
  114. {
  115. case TCHAR('1') :
  116. cLow = s_Heng.GetLow();
  117. cHigh = s_Heng.GetHigh();
  118. break;
  119. case TCHAR('2') :
  120. cLow = s_Shu.GetLow();
  121. cHigh = s_Shu.GetHigh();
  122. break;
  123. case TCHAR('3') :
  124. cLow = s_Pie.GetLow();
  125. cHigh = s_Pie.GetHigh();
  126. break;
  127. case TCHAR('4') :
  128. cLow = s_Na.GetLow();
  129. cHigh = s_Na.GetHigh();
  130. break;
  131. case TCHAR('5') :
  132. cLow = s_Zhe.GetLow();
  133. cHigh = s_Zhe.GetHigh();
  134. break;
  135. default :
  136. ASSERT( FALSE );
  137. break;
  138. }
  139. // set the current stroks
  140. strStroks.SetAt( i*2, cLow );
  141. strStroks.SetAt( i*2+1, cHigh );
  142. } // end of all stroks
  143. return  strStroks;
  144. }
  145. //=============================================================================
  146. //
  147. // 拼音组
  148. //
  149. //=============================================================================
  150. const CString& SpellGroup::operator []( int i )
  151. {
  152. ASSERT( i>= 0 && i<GetCount() );
  153. int idx = 0;
  154. for ( StringList::iterator it=m_vSpell.begin(); 
  155.   it!=m_vSpell.end() && idx<i;
  156.   it++ )  ;
  157.   
  158.   return *it;
  159. }
  160. void SpellGroup::AddGroup( const TCHAR* szSpell )
  161. {
  162. CString strSpell = szSpell;
  163. if ( strSpell == _T("") ) return;
  164. int iCur = 0;
  165. int iNext = -1;
  166. while ( TRUE )
  167. {
  168. iNext=strSpell.Find(TCHAR(':'), iNext+1 );
  169. if ( iNext == -1 )
  170. {
  171. Add( strSpell.Mid( iCur, strSpell.GetLength()-iCur)  );
  172. break;
  173. }
  174. Add( strSpell.Mid( iCur, iNext-iCur) );
  175. iCur = iNext+1;
  176. }
  177. }
  178. CString SpellGroup::GetAsString() const
  179. {
  180. CString str;
  181. BOOL bFirst = TRUE;
  182. const_iterator it;
  183. for ( it=begin(); it!=end(); it++ )
  184. {
  185. if ( bFirst )
  186. bFirst = FALSE;
  187. else
  188. str += _T(":");
  189. str += *it;
  190. }
  191. return str;
  192. }
  193. SpellGroup::operator CString() const
  194. {
  195. return GetAsString();
  196. }
  197. void SpellGroup::Add( const TCHAR* szSpell )
  198. {
  199. if ( !HaveSpell(szSpell) )
  200. m_vSpell.push_back( szSpell );
  201. }
  202. void SpellGroup::Remove( const TCHAR* szSpell )
  203. {
  204. StringList::iterator it = find( m_vSpell.begin(), m_vSpell.end(), szSpell );
  205. if ( it != m_vSpell.end() )
  206. m_vSpell.erase (it);
  207. }
  208. void SpellGroup::RemoveAll()
  209. {
  210. m_vSpell.clear();
  211. }
  212. //==========================================================================================
  213. //
  214. // 输入法
  215. //
  216. //==========================================================================================
  217. BOOL ChineseInputer::QueryWords ( WordEnumerator& enumer, Sorter* pSorter )
  218. {
  219. /**************************************************************************************
  220. *  过滤顺序
  221. * 1. 笔画数
  222. * 2. 部首
  223. * 3.  笔顺
  224. * 4.  拼音
  225. *
  226. **************************************************************************************/
  227. Inputer* pInputer = GetInputer();
  228. ASSERT( pInputer );
  229. QueryBroker qBroker;
  230. if ( pInputer->GetSpell() != _T("") )
  231. {
  232. qBroker.AddFilter( new SpellFilter(pInputer->GetSpell()), TRUE );
  233. // 如果是拼音则需要加入拼音前缀
  234. if ( pSorter )
  235. {
  236. if ( *pSorter == *GetSpellSort() )
  237. static_cast<SpellSort*>(pSorter)->SetPrefix( pInputer->GetSpell() );
  238. /*
  239. if ( *pSorter == *GetCompositeSort() )
  240. static_cast<CompositeSort*>(pSorter)->SetPrefix( pInputer->GetSpell() );
  241. */
  242. }// CompisitSort
  243. }
  244. if ( pInputer->GetStrokesOrder() != _T("") )
  245. qBroker.AddFilter( 
  246. new StrokesOrderFilter( 
  247. StrokesOrder(pInputer->GetStrokesOrder() ) ), TRUE );
  248. if ( pInputer->GetStrokes() != _T("") )
  249. qBroker.AddFilter( new StrokesFilter(pInputer->GetStrokes()), TRUE );
  250. if ( pInputer->GetBS() != _T("") )
  251. qBroker.AddFilter( new BSFilter(pInputer->GetBS()), TRUE );
  252. if ( !qBroker.QueryWords( enumer ) )
  253. return FALSE;
  254. //  排序
  255. if ( pSorter )
  256. pSorter->Sort( enumer );
  257. return TRUE;
  258. }
  259. /**
  260. * 构造函数
  261. */
  262. ChineseInputer::ChineseInputer() 
  263. {
  264. }
  265. /**
  266. * 拼音输入码分隔符
  267. */
  268. const TCHAR ChineseInputer::Inputer::s_cSpellLeft = TCHAR('{');
  269. const TCHAR ChineseInputer::Inputer::s_cSpellRight = TCHAR('}');
  270. /**
  271. * 部首输入码分隔符
  272. */
  273. const TCHAR ChineseInputer::Inputer::s_cBSLeft = TCHAR('(');
  274. const TCHAR ChineseInputer::Inputer::s_cBSRight = TCHAR(')');
  275. /**
  276. * 笔画输入码分隔符
  277. */
  278. const TCHAR ChineseInputer::Inputer::s_cStrokesLeft = TCHAR('<');
  279. const TCHAR ChineseInputer::Inputer::s_cStrokesRight = TCHAR('>');
  280. /**
  281. * 笔顺输入码分隔符
  282. */
  283. const TCHAR ChineseInputer::Inputer::s_cStrokesOrderLeft = TCHAR('[');
  284. const TCHAR ChineseInputer::Inputer::s_cStrokesOrderRight = TCHAR(']');
  285. TCHAR ChineseInputer::Inputer::s_cDividTable[4][2] =
  286. {
  287. { s_cSpellLeft, s_cSpellRight },
  288. { s_cBSLeft, s_cBSRight },
  289. { s_cStrokesLeft, s_cStrokesRight },
  290. { s_cStrokesOrderLeft, s_cStrokesOrderRight }
  291. };
  292. /**
  293. * 空排序器
  294. */
  295. ChineseInputer::NullSort*    ChineseInputer::GetNullSort()
  296. {
  297. static NullSort s_NullSort;
  298. return &s_NullSort;
  299. }
  300. /*
  301. * 拼音排序器
  302. */
  303. ChineseInputer::SpellSort* ChineseInputer::GetSpellSort()
  304. {
  305. static SpellSort s_SpellSort;
  306. return &s_SpellSort;
  307. }
  308. /*
  309. * 笔画排序器
  310. */
  311. ChineseInputer::StrokesSort* ChineseInputer::GetStrokesSort()
  312. {
  313. static StrokesSort s_StrokesSort;
  314. return &s_StrokesSort;
  315. }
  316. /*
  317. * 部首排序器
  318. */
  319. ChineseInputer::BSSort* ChineseInputer::GetBSSort()
  320. {
  321. static BSSort s_BSSort;
  322. return &s_BSSort;
  323. }
  324. /*
  325. * 笔顺排序器
  326. */
  327. ChineseInputer::StrokesOrderSort* ChineseInputer::GetStrokesOrderSort()
  328. {
  329. static StrokesOrderSort s_StrokesOrderSort;
  330. return &s_StrokesOrderSort;
  331. }
  332. ChineseInputer::CompositeSort* ChineseInputer::GetCompositeSort()
  333. {
  334. static CompositeSort sorter;
  335. return &sorter;
  336. }
  337. /*
  338. * 获得输入器
  339. */
  340. ChineseInputer::Inputer* ChineseInputer::GetInputer()
  341. {
  342. return &m_Inputer ;
  343. }
  344. /*
  345. * 输入器构造函数
  346. */
  347. ChineseInputer::Inputer::Inputer() : m_uMode( Input_Spell )
  348. {
  349. Reset();
  350. }
  351. /*
  352. * 设置当前模式
  353. */
  354. void ChineseInputer::Inputer::SetMode( int uMode )
  355. {
  356. ASSERT( uMode >= Input_Spell && uMode <= Input_StrokesOrder );
  357. m_strInputs += s_cDividTable[m_uMode][end];
  358. m_uMode = uMode;
  359. m_strInputs += s_cDividTable[m_uMode][begin];
  360. }
  361. int ChineseInputer::Inputer::GetMode() const
  362. {
  363. return m_uMode;
  364. }
  365. CString ChineseInputer::Inputer::GetInputs() const
  366. {
  367. return _T("");
  368. }
  369. void ChineseInputer::Inputer::Put( TCHAR c )
  370. {
  371. m_strInputs += c;
  372. }
  373. void ChineseInputer::Inputer::Put( const TCHAR* szChars )
  374. {
  375. m_strInputs += szChars;
  376. }
  377. void ChineseInputer::Inputer::Reset()
  378. {
  379. m_strInputs = s_cDividTable[m_uMode][begin];
  380. }
  381. CString ChineseInputer::Inputer::GetUnparse( ) const
  382. {
  383. CString strTemp = m_strInputs;
  384. strTemp += s_cDividTable[m_uMode][end];
  385. return strTemp;
  386. }
  387. CString ChineseInputer::Inputer::GetSpell() const
  388. {
  389. return InputParser(GetUnparse() ).GetSpell();
  390. }
  391. CString ChineseInputer::Inputer::GetBS() const
  392. {
  393. return InputParser( GetUnparse() ).GetBS();
  394. }
  395. CString ChineseInputer::Inputer::GetStrokesOrder() const 
  396. {
  397. return InputParser( GetUnparse() ).GetStrokesOrder();
  398. }
  399. CString ChineseInputer::Inputer::GetStrokes() const
  400. {
  401. return InputParser( GetUnparse() ).GetStrokes();
  402. }
  403. ChineseInputer::Inputer::InputParser::InputParser( const CString& str ) :
  404. m_strForParse(str)
  405. {
  406. VERIFY( Parse( m_strForParse ) );
  407. }
  408. /**
  409. * 提取字符串
  410. */
  411. CString PickPhrase( const CString& str, TCHAR cEnd, int& index )
  412. {
  413. int nStart = index;
  414. while ( str[index] && str[index] != cEnd ) index++;
  415. ASSERT( str[index] );
  416. CString strCur = str.Mid( nStart+1, index- nStart -1 );
  417. index++;
  418. return strCur;
  419. }
  420. BOOL ChineseInputer::Inputer::InputParser::Parse( const CString& str )
  421. {
  422. int index = 0;
  423. int nLength = str.GetLength();
  424. while ( index < nLength )
  425. {
  426. switch ( str[index] )
  427. {
  428. case Inputer::s_cBSLeft :
  429. {
  430. m_strBS += PickPhrase( str, Inputer::s_cBSRight, index ); /*strCur*/;
  431. }
  432. break;
  433. case Inputer::s_cSpellLeft :
  434. {
  435. m_strSpell += PickPhrase( str, Inputer::s_cSpellRight, index );
  436. }
  437. break;
  438. case Inputer::s_cStrokesLeft :
  439. {
  440. m_strStrokes = PickPhrase( str, Inputer::s_cStrokesRight, index );
  441. }
  442. break;
  443. case Inputer::s_cStrokesOrderLeft :
  444. {
  445. m_strStrokesOrder += PickPhrase( str, Inputer::s_cStrokesOrderRight, index );
  446. }
  447. break;
  448. default :
  449. return FALSE;
  450. }
  451. }
  452. return TRUE;
  453. }
  454. //===================================================================================
  455. //
  456. // 查询过滤器
  457. //
  458. //===================================================================================
  459. /*
  460. * 构造函数
  461. */
  462. ChineseInputer::SpellFilter::SpellFilter( const TCHAR* szSpell ) : QueryFilter(szSpell)
  463. {
  464. }
  465. /*
  466. * 查询
  467. */
  468. BOOL ChineseInputer::SpellFilter::QueryWords( WordEnumerator& enumer )
  469. {
  470. return ChineseDictionary::GetSpellQuery()->QueryWords( GetFilter(), enumer );
  471. }
  472. /*
  473. * 验证字是否满足要求
  474. */
  475. BOOL ChineseInputer::SpellFilter::Pass( Word wd ) 
  476. {
  477. SpellGroup sg = GetComment(wd).GetSpellGroup( );
  478. SpellGroup::const_iterator it;
  479. for ( it=sg.begin(); it!=sg.end(); it++ )
  480. {
  481. if ( SpellContainTester::Contain( *it, GetFilter() ) )
  482. return TRUE;
  483. }
  484. return FALSE;
  485. }
  486. ChineseInputer::BSFilter::BSFilter( const TCHAR* szBS ) : QueryFilter(szBS)
  487. {
  488. }
  489. BOOL ChineseInputer::BSFilter::QueryWords( WordEnumerator& enumer )
  490. {
  491. return ChineseDictionary::GetBSQuery()->QueryWords( GetFilter(), enumer );
  492. }
  493. BOOL ChineseInputer::BSFilter::Pass( Word wd )
  494. {
  495. return GetComment(wd).GetBS() == GetFilter();
  496. }
  497. ChineseInputer::StrokesFilter::StrokesFilter( const TCHAR* szStrokes ) 
  498. : QueryFilter(szStrokes)
  499. {
  500. m_nStrokes = _ttoi(szStrokes);
  501. }
  502. BOOL ChineseInputer::StrokesFilter::QueryWords( WordEnumerator& enumer )
  503. {
  504. return ChineseDictionary::GetStrokesQuery()->QueryWords( GetFilter(), enumer );
  505. }
  506. BOOL ChineseInputer::StrokesFilter::Pass( Word wd )
  507. {
  508. return GetComment(wd).GetStrokes() == GetStrokes();
  509. }
  510. ChineseInputer::StrokesOrderFilter::StrokesOrderFilter( const StrokesOrder& sodr ) 
  511. : QueryFilter(sodr.GetAsDigits())
  512. {
  513. }
  514. BOOL ChineseInputer::StrokesOrderFilter::QueryWords( WordEnumerator& enumer )
  515. {
  516. return ChineseDictionary::GetStrokesOrderQuery()->QueryWords( GetFilter(), enumer );
  517. }
  518. BOOL ChineseInputer::StrokesOrderFilter::Pass( Word wd )
  519. {
  520. return StrokesOrderContainTester::Contain( 
  521. GetComment(wd).GetStrokesOrder().GetAsDigits(),
  522. GetFilter() );
  523. }
  524. ChineseInputer::QueryBroker::~QueryBroker()
  525. {
  526. for ( unsigned int i=0; i<m_vFilters.size(); i++ )
  527. {
  528. if ( m_vDeletes[i] )
  529. delete m_vFilters[i];
  530. }
  531. }
  532. /*
  533. * QueryBroker
  534. */
  535. void ChineseInputer::QueryBroker::AddFilter( QueryFilter* pFilter, BOOL bAutoDel )
  536. {
  537. m_vFilters.push_back(pFilter);
  538. m_vDeletes.push_back( bAutoDel );
  539. }
  540. BOOL ChineseInputer::QueryBroker::QueryWords( WordEnumerator& enumer )
  541. {
  542. if ( m_vFilters.size() < 1 ) 
  543. return TRUE;
  544. // 只有一个过滤器
  545. if ( m_vFilters.size() == 1 )
  546. return m_vFilters[0]->QueryWords(enumer);
  547. // 多个过滤器
  548. WordEnumerator wdWhole;
  549. if ( !m_vFilters[0]->QueryWords(wdWhole) )
  550. return FALSE;
  551. WordEnumerator::iterator it;
  552. for ( it=wdWhole.begin(); it!=wdWhole.end(); it++ )
  553. {
  554. for ( unsigned int i=1; i<m_vFilters.size(); i++ )
  555. {
  556. if ( !m_vFilters[i]->Pass(*it) )
  557. break;
  558. }
  559. if ( i>=m_vFilters.size())
  560. enumer.push_back( *it );
  561. }
  562. return TRUE;
  563. }
  564. //==================================================================================
  565. // 排序器
  566. //==================================================================================
  567. struct LessBase
  568. {
  569. const ChineseDictionary::WordComment& GetComment( Word wd ) const
  570. {
  571. return ChineseDictionary::Get(wd).GetComment( );
  572. }
  573. };
  574. /**
  575. * 拼音比较器
  576. */
  577. struct SpellLess2 : public LessBase, public SpellLess
  578. {
  579. protected :
  580. /**
  581. * 拼音前缀
  582. */
  583. CString m_strPrefix;
  584. /**
  585. * 获得拼音
  586. */
  587. const CString& GetSpell( Word wd ) const
  588. {
  589. const SpellGroup& sg = GetComment(wd).GetSpellGroup();
  590. SpellGroup::const_iterator it;
  591. for ( it=sg.begin(); it!=sg.end(); it++ )
  592. {
  593. const CString& strSpell = *it;
  594. if ( SpellContainTester::Contain(strSpell, m_strPrefix) )
  595. return strSpell;
  596. }
  597. return m_strPrefix;
  598. }
  599. public :
  600. SpellLess2( const TCHAR* strPrefix=_T("") ) : m_strPrefix(strPrefix)
  601. {
  602. }
  603. BOOL operator()( const Word& wd1,
  604. const Word& wd2 ) const
  605. {
  606. // 缺省按照第一个拼音排序
  607. return SpellLess::operator()( GetSpell(wd1),  GetSpell(wd2) );
  608. }
  609. };
  610. /**
  611. * 笔画比较器
  612. */
  613. struct StrokesLess2 : public LessBase, public StrokesLess
  614. {
  615. BOOL operator()( const Word& wd1,
  616. const Word& wd2 ) const
  617. {
  618. return StrokesLess::operator()( GetComment(wd1).GetStrokes(),
  619. GetComment(wd2).GetStrokes() );
  620. };
  621. /**
  622. * 笔顺比较器
  623. */
  624. struct StrokesOrderLess2 : public LessBase, public StrokesOrderLess
  625. {
  626. BOOL operator()( const Word& wd1,
  627. const Word& wd2 ) const
  628. {
  629. // 缺省按照第一个拼音排序
  630. return StrokesOrderLess::operator()( 
  631. GetComment(wd1).GetStrokesOrder().GetAsDigits(), 
  632. GetComment(wd2).GetStrokesOrder().GetAsDigits() );
  633. }
  634. };
  635. /**
  636. * 部首比较器
  637. */
  638. struct BSLess2 : public LessBase, public BSLess
  639. {
  640. BOOL operator()( const Word& wd1,
  641. const Word& wd2 )
  642. {
  643. return BSLess::operator()( GetComment(wd1).GetBS(), 
  644. GetComment(wd2).GetBS() );
  645. };
  646. struct CompositeLess : //public LessBase,
  647. public BSLess,
  648. public StrokesOrderLess,
  649. public SpellLess2,
  650. public StrokesLess
  651. {
  652. typedef vector<int> Modes;
  653. CompositeLess(const Modes& vModes ) : m_vModes(vModes) 
  654. {
  655. };
  656. BOOL operator()( const Word& wd1,
  657. const Word& wd2 )
  658. {
  659. Modes::iterator it;
  660. for ( it=m_vModes.begin(); it!=m_vModes.end(); it++ )
  661. {
  662. switch ( *it )
  663. {
  664. case ChineseInputer::Sorter::OrderBySpell :
  665. {
  666. if ( SpellLess::operator()( GetSpell(wd1),
  667.       GetSpell(wd2) ) )
  668. return TRUE;
  669. return FALSE;
  670. }
  671. break;
  672. case ChineseInputer::Sorter::OrderByBS :
  673. {
  674. if ( BSLess::operator()( GetComment(wd1).GetBS(),
  675. GetComment(wd2).GetBS() ) )
  676. return TRUE;
  677. }
  678. break;
  679. case ChineseInputer::Sorter::OrderByStrokes :
  680. {
  681. if ( StrokesLess::operator()( GetComment(wd1).GetStrokes(),
  682.      GetComment(wd2).GetStrokes() ) )
  683. return TRUE;
  684. }
  685. break;
  686. case ChineseInputer::Sorter::OrderByStrokesOrder :
  687. {
  688. if ( StrokesOrderLess::operator()( GetComment(wd1).GetStrokesOrder(),
  689.   GetComment(wd2).GetStrokesOrder() ) )
  690. return TRUE;
  691. }
  692. break;
  693. default :
  694. break;
  695. }
  696. }
  697. return FALSE;
  698. }
  699. protected :
  700. Modes m_vModes;
  701. };
  702. /*
  703. * 按照拼音排序
  704. */
  705. void ChineseInputer::SpellSort::Sort( WordEnumerator& enumer )
  706. {
  707. enumer.sort( SpellLess2( GetPrefix( ) ) );
  708. }
  709. void ChineseInputer::BSSort::Sort( WordEnumerator& enumer )
  710. {
  711. enumer.sort( BSLess2() );
  712. }
  713. void ChineseInputer::StrokesSort::Sort( WordEnumerator& enumer )
  714. {
  715. enumer.sort( StrokesLess2() );
  716. }
  717. void ChineseInputer::StrokesOrderSort::Sort( WordEnumerator& enumer )
  718. {
  719. enumer.sort( StrokesOrderLess2() );
  720. }
  721. /**
  722. * 复合排序器
  723. */
  724. void ChineseInputer::CompositeSort::AddMode( int uMode )
  725. {
  726. if ( find( m_vModes.begin(), m_vModes.end(), uMode ) == m_vModes.end() )
  727. m_vModes.push_back( uMode );
  728. }
  729. void ChineseInputer::CompositeSort::ClearModes()
  730. {
  731. m_vModes.clear();
  732. }
  733. void ChineseInputer::CompositeSort::Sort(ChineseInputer::WordEnumerator& enumer )
  734. {
  735. enumer.sort( CompositeLess(m_vModes) );
  736. }
  737. //===================================================================================
  738. //
  739. // 汉字字典
  740. //
  741. //===================================================================================
  742. ChineseDictionary::WordTable ChineseDictionary::s_WordTable;
  743. /*
  744. * 非法词条
  745. */
  746. ChineseDictionary::WordItem ChineseDictionary::NullWordItemRef;
  747. /*
  748. * 查询汉字
  749. */
  750. ChineseDictionary::WordItemRef ChineseDictionary::Get( Word wdLookup )
  751. {
  752. WordTable::iterator it = s_WordTable.find( wdLookup );
  753. if ( it == s_WordTable.end()  )
  754. return NullWordItemRef;
  755. return WordItem( it->first, &(it->second) );
  756. }
  757. /*
  758. * 清空所有词条
  759. */
  760. void ChineseDictionary::Clear( )
  761. {
  762. s_WordTable.clear( );
  763. }
  764. /*
  765. * 加入汉字
  766. */
  767. void ChineseDictionary::AddWord( Word wd, const WordComment& wc )
  768. {
  769. WordTable::iterator it = s_WordTable.find( wd );
  770. // 加入新字
  771. if ( it == s_WordTable.end()  )
  772. {
  773. s_WordTable[wd] = wc;//WordItem( wd, wc );
  774. }
  775. else // 加入新得拼音
  776. {
  777. WordComment& wcHave = s_WordTable[wd];
  778. SpellGroup sg = wcHave.GetSpellGroup();
  779. sg.AddGroup ( wc.GetSpellGroup().GetAsString() );
  780. wcHave.SetSpellGroup( sg );
  781. }
  782. }
  783. /*
  784. * 从文件中装入字典
  785. */
  786. BOOL ChineseDictionary::Load( const TCHAR* szFile )
  787. {
  788. Clear();
  789. CFile file;
  790. if ( !file.Open( szFile, CFile::modeRead | CFile::typeBinary ) )
  791. return FALSE;
  792. TStreamAdapter<CFile> os(&file);
  793. // 读入大小
  794. int nSize;
  795. os >> nSize;
  796. // 读入所有条目
  797. Word wd;
  798. WordComment wc;
  799. for ( int i=0; i<nSize; i++ )
  800. {
  801. wd << os;
  802. wc << os;
  803. AddWord( wd, wc );
  804. } // end of all item
  805. file.Close();
  806. return TRUE;
  807. }
  808. ChineseDictionary::WordItem::operator BOOL() const
  809. {
  810. return *this != ChineseDictionary::NullWordItemRef;
  811. }
  812. /*
  813. * 将字典写入文件
  814. */
  815. BOOL ChineseDictionary::Save( const TCHAR* szFile )
  816. {
  817. CFile file;
  818. if ( !file.Open( szFile, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary ) )
  819. return FALSE;
  820. TStreamAdapter<CFile> os(&file);
  821. // write the size 
  822. int nSize = s_WordTable.size();
  823. os << nSize;
  824. WordTable::iterator it;
  825. for ( it=s_WordTable.begin(); it!=s_WordTable.end(); it++ )
  826. {
  827. // 保存字
  828. const Word& wd = it->first;
  829. wd >> os;
  830. // 保存注释
  831. const WordComment& wc = it->second;
  832. wc >> os;
  833. }
  834. // close the file
  835. file.Close();
  836. return TRUE;
  837. }
  838. /*
  839. * 部首查询器初始化
  840. */
  841. BOOL ChineseDictionary::QueryBase::Initialize( WordTable* pWordTbl )
  842. {
  843. m_pWordTbl = pWordTbl;
  844. return TRUE;
  845. }
  846. /*
  847. * 部首查询器销毁
  848. */
  849. void ChineseDictionary::QueryBase::Uninitialize(  )
  850. {
  851. m_pWordTbl = NULL;
  852. }
  853. /*
  854. * 根据输入部首, 查询汉字
  855. */
  856. BOOL ChineseDictionary::BSQuery::QueryWords( const TCHAR* szBuShou, 
  857. WordEnumerator& enumer )
  858. {
  859. if ( !m_pWordTbl ) 
  860. return FALSE;
  861. Word wdBS( szBuShou );
  862. // 查询满足条件的汉字
  863. WordTable::iterator it;
  864. for ( it=m_pWordTbl->begin(); it!=m_pWordTbl->end(); it++ )
  865. {
  866. const WordComment& wc = it->second;
  867. if ( wc.GetBS() == wdBS )
  868. enumer.push_back(it->first);
  869. }
  870. return TRUE;
  871. }
  872. /*
  873. * 根据输入部首, 查询汉字
  874. */
  875. BOOL ChineseDictionary::StrokesQuery::QueryWords( int nStrokes, 
  876. WordEnumerator& enumer )
  877. {
  878. if ( !m_pWordTbl ) 
  879. return FALSE;
  880. // 查询满足条件的汉字
  881. WordTable::iterator it;
  882. for ( it=m_pWordTbl->begin(); it!=m_pWordTbl->end(); it++ )
  883. {
  884. const WordComment& wc = it->second;
  885. if ( wc.GetStrokes() == nStrokes )
  886. enumer.push_back(it->first);
  887. }
  888. return TRUE;
  889. }
  890. /*
  891. * 根据输入笔画, 查询汉字
  892. */
  893. BOOL ChineseDictionary::StrokesQuery::QueryWords( const TCHAR* szStrokes, 
  894.  WordEnumerator& enumer )
  895. {
  896. int nStrokes = _ttoi(szStrokes);
  897. return QueryWords( nStrokes, enumer );
  898. }
  899. /**
  900. * 字符串查询基类
  901. */
  902. void ChineseDictionary::StringQueryBase::AddMap( const TCHAR*szString, Word wd)
  903. {
  904. m_String2Words[szString].push_back( wd );
  905. }
  906. ChineseDictionary::StringQueryBase::String2Words&
  907. ChineseDictionary::StringQueryBase::GetMapTable( )
  908. {
  909. return m_String2Words;
  910. }
  911. BOOL ChineseDictionary::StringQueryBase::QueryWords( const TCHAR* szSpell, 
  912. WordEnumerator& enumer )
  913. {
  914. String2Words::iterator it;
  915. for ( it=m_String2Words.begin(); it!=m_String2Words.end(); it++ )
  916. {
  917. const CString& strSpell = it->first;
  918. // 拷贝当前拼音包含得所有汉字
  919. if ( StringContainTester::Contain( strSpell, szSpell ) )
  920. {
  921. back_insert_iterator<WordEnumerator> bit(enumer);
  922. Words& words = it->second;
  923. copy( words.begin(), words.end(), bit );
  924. } // end of current words
  925. }
  926. return TRUE;
  927. }
  928. BOOL ChineseDictionary::StringQueryBase::Initialize( WordTable* pWordTbl )
  929. {
  930. if ( !QueryBase::Initialize(pWordTbl) )
  931. return FALSE;
  932. // 查询满足条件的汉字
  933. WordTable::iterator it;
  934. for ( it=m_pWordTbl->begin(); it!=m_pWordTbl->end(); it++ )
  935. InitWord( it->first, it->second );
  936. return TRUE;
  937. }
  938. void ChineseDictionary::StringQueryBase::Uninitialize(  )
  939. {
  940. m_String2Words.clear();
  941. QueryBase::Uninitialize();
  942. }
  943. /*
  944. * 初始化查询器
  945. */
  946. BOOL ChineseDictionary::SpellQuery::Initialize( WordTable* pWordTable)
  947. {
  948. if ( !StringQueryBase::Initialize(pWordTable) )
  949. return FALSE;
  950. // 对所有得行排序
  951. for ( iterator it=begin(); it!=end(); it++ )
  952. {
  953. Words& words = *it;
  954. //sort( words.begin(), words.end(), StrokesLess2() );
  955. words.sort( StrokesLess2() );
  956. }
  957. return TRUE;
  958. }
  959. /**
  960. * 初始化字
  961. */
  962. void ChineseDictionary::SpellQuery::InitWord( Word wd, 
  963.  const WordComment& wc )
  964. {
  965. const SpellGroup& sg = wc.GetSpellGroup();
  966. // 处理所有的拼音
  967. SpellGroup::const_iterator itSg;
  968. for ( itSg=sg.begin( ); itSg!=sg.end(); itSg++ )
  969. AddMap( *itSg, wd );  // 多音字处理结束
  970. }
  971. /**
  972. * 初始化字
  973. */
  974. void ChineseDictionary::StrokesOrderQuery::InitWord( Word wd, 
  975. const WordComment& wc )
  976. {
  977. AddMap( wc.GetStrokesOrder().GetAsDigits(), wd );
  978. }
  979. /*
  980. * 获得部首查询器
  981. */
  982. ChineseDictionary::BSQuery*
  983. ChineseDictionary::GetBSQuery()
  984. {
  985. return GetQuery( TypeTraits<BSQuery>() );
  986. }
  987. /*
  988. * 获得笔画查询器
  989. */
  990. ChineseDictionary::StrokesQuery*
  991. ChineseDictionary::GetStrokesQuery()
  992. {
  993. return GetQuery( TypeTraits<StrokesQuery>() );
  994. }
  995. /*
  996. * 获得拼音查询器
  997. */
  998. ChineseDictionary::SpellQuery*
  999. ChineseDictionary::GetSpellQuery()
  1000. {
  1001. return GetQuery( TypeTraits<SpellQuery>() );
  1002. }
  1003. ChineseDictionary::StrokesOrderQuery*
  1004. ChineseDictionary::GetStrokesOrderQuery()
  1005. {
  1006. return GetQuery( TypeTraits<StrokesOrderQuery>() );
  1007. }
  1008. //==============================================================================
  1009. //
  1010. // 生成字典
  1011. //
  1012. //==============================================================================
  1013. BOOL ChineseDictionaryMaker::Make( const TCHAR* szSpell,
  1014.   const TCHAR* szBS,
  1015.   const TCHAR* szStrokes )
  1016. {
  1017. WordTable wdTbl;
  1018. if ( !ProcessSpell( szSpell, wdTbl ) ||
  1019.  !ProcessBS(szBS,  wdTbl )   ||
  1020.  !ProcessStrokes(szStrokes, wdTbl ) )
  1021.  return FALSE;
  1022. // 清空
  1023. ChineseDictionary::Clear();
  1024. //  逐条加入到字典
  1025. WordTable::iterator it;
  1026. for ( it=wdTbl.begin(); it!=wdTbl.end(); it++ )
  1027. ChineseDictionary::AddWord( it->first, it->second );
  1028. return TRUE;
  1029. }
  1030. /*
  1031. * 处理拼音
  1032. */
  1033. BOOL ChineseDictionaryMaker::ProcessSpell( const TCHAR* szSpell, WordTable& wtbl )
  1034. {
  1035. CStdioFile file;
  1036. if ( !file.Open( szSpell, CStdioFile::modeRead )  )
  1037. return FALSE;
  1038. CString strLine;  //当前行
  1039. CString strSpell; // 当前拼音
  1040. TCHAR strWord[3]; // 当前字
  1041. // 依次处理所有汉字
  1042. while ( true )
  1043. {
  1044. // 读入字
  1045. if ( !file.ReadString(strLine) )
  1046. break;
  1047. ASSERT( strLine[0] == TCHAR('<') );
  1048. strSpell = strLine.Mid( 1, strLine.Find(TCHAR('>'), 1)-1 );
  1049. // 该拼音得所有汉字
  1050. file.ReadString(strLine);
  1051. int   nLineLen = strLine.GetLength();
  1052. for ( int i=0; i<nLineLen; i+= 3 )
  1053. {
  1054. strWord[0] = strLine[i];
  1055. strWord[1] = strLine[i+1];
  1056. strWord[2] = TCHAR('');
  1057. // 加入新的汉字拼音
  1058. ChineseDictionary::WordComment& wc = wtbl[Word(strWord)];
  1059. SpellGroup sg = wc.GetSpellGroup();
  1060. sg.Add( strSpell );
  1061. wc.SetSpellGroup(sg);
  1062. }
  1063. } // 所有汉字处理完成
  1064. file.Close();
  1065. return TRUE;
  1066. };
  1067. /**
  1068. * 处理部首
  1069. */
  1070. BOOL ChineseDictionaryMaker::ProcessBS( const TCHAR* szBS, WordTable& wtbl )
  1071. {
  1072. CStdioFile file;
  1073. if ( !file.Open(szBS, CStdioFile::modeRead )  )
  1074. return FALSE;
  1075. /*
  1076. CStdioFile bsFile;
  1077. bsFile.Open( _T("f:\bs.txt"),CStdioFile::modeCreate | CStdioFile::modeWrite );
  1078. */
  1079. CString strLine;  //当前行
  1080. CString strBS;   // 当前部首
  1081. TCHAR strWord[3]; // 当前字
  1082. while ( true )
  1083. {
  1084. if ( !file.ReadString(strLine ) )
  1085. break;
  1086. ASSERT( strLine[0] == TCHAR('<') );
  1087. // 部首
  1088. strBS = strLine.Mid( 1, 2 );
  1089. if ( strBS == _T("左") || strBS == _T("右") )
  1090. strBS = strLine.Mid( 3, 2 );
  1091. Word wdBS( strBS );
  1092. /*
  1093. bsFile.WriteString( _T("BSWord(_T("") );
  1094. bsFile.WriteString( strBS );
  1095. bsFile.WriteString( _T(""), 1, _T("" ) );
  1096. bsFile.WriteString( strLine );
  1097. bsFile.WriteString( _T("") ),n") );
  1098. */
  1099. // 该部首所有汉字
  1100. file.ReadString(strLine);
  1101. int   nLineLen = strLine.GetLength();
  1102. for ( int i=0; i<nLineLen; i+= 3 )
  1103. {
  1104. strWord[0] = strLine[i];
  1105. strWord[1] = strLine[i+1];
  1106. strWord[2] = TCHAR('');
  1107. // 加入汉字部首
  1108. ChineseDictionary::WordComment& wc = wtbl[Word(strWord)];
  1109. wc.SetBS( wdBS );
  1110. } // end of all word
  1111. }
  1112. file.Close();
  1113. /*
  1114. bsFile.Close();
  1115. */
  1116. return TRUE;
  1117. };
  1118. /**
  1119. * 处理笔画
  1120. */
  1121. BOOL ChineseDictionaryMaker::ProcessStrokes( const TCHAR* szStrokes, WordTable& wtbl )
  1122. {
  1123. CStdioFile file;
  1124. if ( !file.Open( szStrokes, CStdioFile::modeRead )  )
  1125. return FALSE;
  1126. CString strLine;  //当前行
  1127. TCHAR strWord[3]; // 当前字
  1128. CString strOrders; // 笔顺
  1129. CString strStrokes; // 笔画数
  1130. // 依次处理所有汉字
  1131. while ( true )
  1132. {
  1133. // 读入字
  1134. if ( !file.ReadString(strLine) )
  1135. break;
  1136. ASSERT( strLine[0] == TCHAR('<') && strLine[3] == TCHAR('>') );
  1137. strWord[0] = strLine[1];
  1138. strWord[1] = strLine[2];
  1139. strWord[2] = TCHAR('');
  1140. file.ReadString(strLine);
  1141. // 笔画数
  1142. int idxSpace = strLine.Find(TCHAR(' '));
  1143. strStrokes = strLine.Left( idxSpace );
  1144. int nStroks = _ttoi(strStrokes);
  1145. // 笔顺
  1146. CString strTemp = strLine.Right( strLine.GetLength() - idxSpace );
  1147. strTemp.TrimLeft();
  1148. strOrders = strTemp.Left( strTemp.Find(TCHAR(' ')) );
  1149. // 加入汉字
  1150. ChineseDictionary::WordComment& wc = wtbl[Word(strWord)];
  1151. wc.SetStrokes( (unsigned short)nStroks);
  1152. wc.SetStrokesOrder( StrokesOrder(strOrders) );
  1153. } // 所有汉字处理完成
  1154. file.Close();
  1155. return TRUE;
  1156. };
  1157. /**
  1158. * 部首表
  1159. */
  1160. ChineseDictionary::BSWord ChineseDictionary::s_BSWordTable[] =
  1161. {
  1162. BSWord(_T("一"), 1, _T("一部") ),
  1163. BSWord(_T("丨"), 1, _T("丨部") ),
  1164. BSWord(_T("丿"), 1, _T("丿部") ),
  1165. BSWord(_T("丶"), 1, _T("丶部") ),
  1166. BSWord(_T("乙"), 1, _T("乙(乛乚)部") ),
  1167. BSWord(_T("二"), 1, _T("二部") ),
  1168. BSWord(_T("十"), 1, _T("十部") ),
  1169. BSWord(_T("厂"), 1, _T("厂部") ),
  1170. BSWord(_T("匚"), 1, _T("匚部") ),
  1171. BSWord(_T("刂"), 1, _T("刂部") ),
  1172. BSWord(_T("卜"), 1, _T("卜部") ),
  1173. BSWord(_T("冂"), 1, _T("冂部") ),
  1174. BSWord(_T("亻"), 1, _T("亻部") ),
  1175. BSWord(_T("八"), 1, _T("八部") ),
  1176. BSWord(_T("人"), 1, _T("人(入)部") ),
  1177. BSWord(_T("勹"), 1, _T("勹部") ),
  1178. BSWord(_T("几"), 1, _T("几部") ),
  1179. BSWord(_T("儿"), 1, _T("儿部") ),
  1180. BSWord(_T("亠"), 1, _T("亠部") ),
  1181. BSWord(_T("冫"), 1, _T("冫部") ),
  1182. BSWord(_T("冖"), 1, _T("冖部") ),
  1183. BSWord(_T("讠"), 1, _T("讠(言)部") ),
  1184. BSWord(_T("卩"), 1, _T("卩究") ),
  1185. BSWord(_T("阝"), 1, _T("左阝部") ),
  1186. BSWord(_T("阝"), 1, _T("右阝部") ),
  1187. BSWord(_T("凵"), 1, _T("凵部") ),
  1188. BSWord(_T("刀"), 1, _T("刀究") ),
  1189. BSWord(_T("力"), 1, _T("力部") ),
  1190. BSWord(_T("厶"), 1, _T("厶部") ),
  1191. BSWord(_T("又"), 1, _T("又究") ),
  1192. BSWord(_T("廴"), 1, _T("廴部") ),
  1193. BSWord(_T("工"), 1, _T("工部") ),
  1194. BSWord(_T("土"), 1, _T("土部") ),
  1195. BSWord(_T("士"), 1, _T("士部") ),
  1196. BSWord(_T("扌"), 1, _T("扌部") ),
  1197. BSWord(_T("艹"), 1, _T("艹部") ),
  1198. BSWord(_T("寸"), 1, _T("寸部") ),
  1199. BSWord(_T("廾"), 1, _T("廾部") ),
  1200. BSWord(_T("大"), 1, _T("大部") ),
  1201. BSWord(_T("尢"), 1, _T("尢部") ),
  1202. BSWord(_T("弋"), 1, _T("弋部") ),
  1203. BSWord(_T("小"), 1, _T("小究") ),
  1204. BSWord(_T("口"), 1, _T("口部") ),
  1205. BSWord(_T("囗"), 1, _T("囗部") ),
  1206. BSWord(_T("巾"), 1, _T("巾部") ),
  1207. BSWord(_T("山"), 1, _T("山部") ),
  1208. BSWord(_T("彳"), 1, _T("彳部") ),
  1209. BSWord(_T("彡"), 1, _T("彡部") ),
  1210. BSWord(_T("犭"), 1, _T("犭部") ),
  1211. BSWord(_T("夕"), 1, _T("夕部") ),
  1212. BSWord(_T("夂"), 1, _T("夂部") ),
  1213. BSWord(_T("饣"), 1, _T("饣(食)部") ),
  1214. BSWord(_T("广"), 1, _T("广部") ),
  1215. BSWord(_T("忄"), 1, _T("忄究") ),
  1216. BSWord(_T("门"), 1, _T("门(門)部") ),
  1217. BSWord(_T("氵"), 1, _T("氵部") ),
  1218. BSWord(_T("宀"), 1, _T("宀部") ),
  1219. BSWord(_T("辶"), 1, _T("辶部") ),
  1220. BSWord(_T("彐"), 1, _T("彐(彑)部") ),
  1221. BSWord(_T("尸"), 1, _T("尸部") ),
  1222. BSWord(_T("己"), 1, _T("己(巳)部") ),
  1223. BSWord(_T("弓"), 1, _T("弓部") ),
  1224. BSWord(_T("子"), 1, _T("子(孑)部") ),
  1225. BSWord(_T("屮"), 1, _T("屮部") ),
  1226. BSWord(_T("女"), 1, _T("女部") ),
  1227. BSWord(_T("纟"), 1, _T("纟(糹)部") ),
  1228. BSWord(_T("马"), 1, _T("马(馬)部") ),
  1229. BSWord(_T("幺"), 1, _T("幺部") ),
  1230. BSWord(_T("巛"), 1, _T("巛部") ),
  1231. BSWord(_T("王"), 1, _T("王部") ),
  1232. BSWord(_T("韦"), 1, _T("韦(韋)部") ),
  1233. BSWord(_T("木"), 1, _T("木部") ),
  1234. BSWord(_T("犬"), 1, _T("犬部") ),
  1235. BSWord(_T("歹"), 1, _T("歹部") ),
  1236. BSWord(_T("车"), 1, _T("车(車)部") ),
  1237. BSWord(_T("戈"), 1, _T("戈部") ),
  1238. BSWord(_T("比"), 1, _T("比部") ),
  1239. BSWord(_T("瓦"), 1, _T("瓦部") ),
  1240. BSWord(_T("止"), 1, _T("止部") ),
  1241. BSWord(_T("攴"), 1, _T("攴部") ),
  1242. BSWord(_T("日"), 1, _T("日部") ),
  1243. BSWord(_T("曰"), 1, _T("曰部") ),
  1244. BSWord(_T("水"), 1, _T("水(氺)部") ),
  1245. BSWord(_T("贝"), 1, _T("贝(貝)部") ),
  1246. BSWord(_T("见"), 1, _T("见(見)部") ),
  1247. BSWord(_T("牛"), 1, _T("牛(牜)部") ),
  1248. BSWord(_T("手"), 1, _T("手部") ),
  1249. BSWord(_T("毛"), 1, _T("毛部") ),
  1250. BSWord(_T("气"), 1, _T("气部") ),
  1251. BSWord(_T("攵"), 1, _T("攵部") ),
  1252. BSWord(_T("片"), 1, _T("片部") ),
  1253. BSWord(_T("斤"), 1, _T("斤部") ),
  1254. BSWord(_T("爪"), 1, _T("爪(爫)部") ),
  1255. BSWord(_T("父"), 1, _T("父部") ),
  1256. BSWord(_T("月"), 1, _T("月部") ),
  1257. BSWord(_T("欠"), 1, _T("欠部") ),
  1258. BSWord(_T("风"), 1, _T("风(風)部") ),
  1259. BSWord(_T("殳"), 1, _T("殳部") ),
  1260. BSWord(_T("文"), 1, _T("文部") ),
  1261. BSWord(_T("方"), 1, _T("方部") ),
  1262. BSWord(_T("火"), 1, _T("火部") ),
  1263. BSWord(_T("斗"), 1, _T("斗部") ),
  1264. BSWord(_T("灬"), 1, _T("灬部") ),
  1265. BSWord(_T("户"), 1, _T("户部") ),
  1266. BSWord(_T("礻"), 1, _T("礻(示)部") ),
  1267. BSWord(_T("心"), 1, _T("心部") ),
  1268. BSWord(_T("肀"), 1, _T("肀(聿)部") ),
  1269. BSWord(_T("爿"), 1, _T("爿部") ),
  1270. BSWord(_T("毋"), 1, _T("毋(母)部") ),
  1271. BSWord(_T("示"), 1, _T("示(见礻)部") ),
  1272. BSWord(_T("石"), 1, _T("石部") ),
  1273. BSWord(_T("龙"), 1, _T("龙(龍)部") ),
  1274. BSWord(_T("业"), 1, _T("业部") ),
  1275. BSWord(_T("目"), 1, _T("目部") ),
  1276. BSWord(_T("田"), 1, _T("田部") ),
  1277. BSWord(_T("罒"), 1, _T("罒部") ),
  1278. BSWord(_T("皿"), 1, _T("皿部") ),
  1279. BSWord(_T("钅"), 1, _T("钅(金)部") ),
  1280. BSWord(_T("矢"), 1, _T("矢部") ),
  1281. BSWord(_T("禾"), 1, _T("禾部") ),
  1282. BSWord(_T("白"), 1, _T("白部") ),
  1283. BSWord(_T("瓜"), 1, _T("瓜部") ),
  1284. BSWord(_T("用"), 1, _T("用部") ),
  1285. BSWord(_T("鸟"), 1, _T("鸟(鳥)部") ),
  1286. BSWord(_T("疒"), 1, _T("疒部") ),
  1287. BSWord(_T("立"), 1, _T("立部") ),
  1288. BSWord(_T("穴"), 1, _T("穴部") ),
  1289. BSWord(_T("衤"), 1, _T("衤部") ),
  1290. BSWord(_T("疋"), 1, _T("疋部") ),
  1291. BSWord(_T("皮"), 1, _T("皮部") ),
  1292. BSWord(_T("癶"), 1, _T("癶部") ),
  1293. BSWord(_T("矛"), 1, _T("矛部") ),
  1294. BSWord(_T("耒"), 1, _T("耒部") ),
  1295. BSWord(_T("老"), 1, _T("老部") ),
  1296. BSWord(_T("耳"), 1, _T("耳部") ),
  1297. BSWord(_T("臣"), 1, _T("臣部") ),
  1298. BSWord(_T("西"), 1, _T("西(覀)部") ),
  1299. BSWord(_T("页"), 1, _T("页(頁)部") ),
  1300. BSWord(_T("虍"), 1, _T("虍部") ),
  1301. BSWord(_T("虫"), 1, _T("虫部") ),
  1302. BSWord(_T("缶"), 1, _T("缶部") ),
  1303. BSWord(_T("舌"), 1, _T("舌部") ),
  1304. BSWord(_T("竹"), 1, _T("竹部") ),
  1305. BSWord(_T("臼"), 1, _T("臼部") ),
  1306. BSWord(_T("自"), 1, _T("自部") ),
  1307. BSWord(_T("血"), 1, _T("血部") ),
  1308. BSWord(_T("舟"), 1, _T("舟部") ),
  1309. BSWord(_T("衣"), 1, _T("衣部") ),
  1310. BSWord(_T("羊"), 1, _T("羊究") ),
  1311. BSWord(_T("米"), 1, _T("米部") ),
  1312. BSWord(_T("艮"), 1, _T("艮部") ),
  1313. BSWord(_T("羽"), 1, _T("羽部") ),
  1314. BSWord(_T("糸"), 1, _T("糸部") ),
  1315. BSWord(_T("麦"), 1, _T("麦(麥)部") ),
  1316. BSWord(_T("走"), 1, _T("走部") ),
  1317. BSWord(_T("赤"), 1, _T("赤部") ),
  1318. BSWord(_T("豆"), 1, _T("豆部") ),
  1319. BSWord(_T("酉"), 1, _T("酉部") ),
  1320. BSWord(_T("辰"), 1, _T("辰部") ),
  1321. BSWord(_T("豕"), 1, _T("豕部") ),
  1322. BSWord(_T("卤"), 1, _T("卤(鹵)部") ),
  1323. BSWord(_T("里"), 1, _T("里部") ),
  1324. BSWord(_T("足"), 1, _T("足部") ),
  1325. BSWord(_T("身"), 1, _T("身部") ),
  1326. BSWord(_T("采"), 1, _T("采部") ),
  1327. BSWord(_T("谷"), 1, _T("谷部") ),
  1328. BSWord(_T("豸"), 1, _T("豸部") ),
  1329. BSWord(_T("角"), 1, _T("角部") ),
  1330. BSWord(_T("言"), 1, _T("言部") ),
  1331. BSWord(_T("辛"), 1, _T("辛部") ),
  1332. BSWord(_T("青"), 1, _T("青部") ),
  1333. BSWord(_T("其"), 1, _T("其部") ),
  1334. BSWord(_T("雨"), 1, _T("雨部") ),
  1335. BSWord(_T("齿"), 1, _T("齿(齒)部") ),
  1336. BSWord(_T("黾"), 1, _T("黾(黽)部") ),
  1337. BSWord(_T("隹"), 1, _T("隹部") ),
  1338. BSWord(_T("金"), 1, _T("金部") ),
  1339. BSWord(_T("鱼"), 1, _T("鱼(魚)部") ),
  1340. BSWord(_T("革"), 1, _T("革部") ),
  1341. BSWord(_T("骨"), 1, _T("骨部") ),
  1342. BSWord(_T("鬼"), 1, _T("鬼部") ),
  1343. BSWord(_T("食"), 1, _T("食部") ),
  1344. BSWord(_T("音"), 1, _T("音部") ),
  1345. BSWord(_T("鬥"), 1, _T("鬥部") ),
  1346. BSWord(_T("髟"), 1, _T("髟部") ),
  1347. BSWord(_T("麻"), 1, _T("麻部") ),
  1348. BSWord(_T("鹿"), 1, _T("鹿部") ),
  1349. BSWord(_T("黑"), 1, _T("黑部") ),
  1350. BSWord(_T("鼠"), 1, _T("鼠部") ),
  1351. BSWord(_T("鼻"), 1, _T("鼻部") )
  1352. };
  1353. ChineseDictionary::BSWords::iterator ChineseDictionary::BSWords::begin() const
  1354. {
  1355. return &ChineseDictionary::s_BSWordTable[0];
  1356. }
  1357. ChineseDictionary::BSWords::iterator ChineseDictionary::BSWords::end() const
  1358. {
  1359. return &ChineseDictionary::s_BSWordTable[size()];
  1360. }
  1361. int ChineseDictionary::BSWords::size() const
  1362. {
  1363. return sizeof(ChineseDictionary::s_BSWordTable) /
  1364.     sizeof(ChineseDictionary::s_BSWordTable[0]);
  1365. }
  1366. }