4 Website: http://www.vultaire.net/software/jben/
5 License: GNU General Public License (GPL) version 2
6 (http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt)
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>
24 #include "kanjilist.h"
31 KanjiList::KanjiList(const BoostHM
<wchar_t, KInfo
>* kDictHash
) {
32 kanjiHash
= kDictHash
;
35 int KanjiList::AddFromString(const wstring
& s
) {
36 int kanjiAdded
= 0, len
= s
.length();
38 BoostHM
<wchar_t,KInfo
>::const_iterator it
;
40 for(int i
=0;i
<len
;i
++) {
42 it
= kanjiHash
->find(c
);
43 if(it
!=kanjiHash
->end()) {
44 if(find(kanjiList
.begin(), kanjiList
.end(), c
)==kanjiList
.end()) {
45 kanjiList
.push_back(c
);
54 /* Convert the kanjilist into a wide char string,
55 with lineWidth kanji per line (0 == no line breaks). */
56 wstring
KanjiList::ToString(int lineWidth
) {
58 int lineWidthCounter
=0;
59 int len
= kanjiList
.size();
60 for(int i
=0;i
<len
;i
++) {
61 result
.append(1, kanjiList
[i
]);
64 if(lineWidthCounter
>=lineWidth
) {
65 result
.append(1, L
'\n');
73 void KanjiList::Clear() {
77 int KanjiList::AddByGrade(int lowGrade
, int highGrade
) {
81 for(BoostHM
<wchar_t,KInfo
>::const_iterator
82 ki
=kanjiHash
->begin(); ki
!=kanjiHash
->end(); ki
++) {
83 grade
= ki
->second
.grade
;
85 (grade
<=highGrade
|| highGrade
==0))
86 kanjiStr
.append(1, ki
->first
);
89 return AddFromString(kanjiStr
);
92 int KanjiList::AddByFrequency(int lowFreq
, int highFreq
) {
96 for(BoostHM
<wchar_t,KInfo
>::const_iterator ki
=kanjiHash
->begin(); ki
!=kanjiHash
->end(); ki
++) {
97 freq
= ki
->second
.freq
;
98 if(freq
>=lowFreq
&& freq
<=highFreq
)
99 kanjiStr
.append(1, ki
->first
);
102 return AddFromString(kanjiStr
);
105 int KanjiList::Size() {return kanjiList
.size();}
107 void KanjiList::InplaceMerge(vector
<wchar_t>& v
, BoostHM
<wchar_t,int>& indexer
, int start
, int middle
, int end
) {
108 /* Merge is implemented as a bubble sort started at halfway
109 (since we know the first whole half is already sorted) */
112 i
= highIndex
= middle
;
114 if(i
>0 && (indexer
[v
[i
]] < indexer
[v
[i
-1]])) {
127 SortKanjiList sorts the currently loaded kanji list based upon a specified
128 KANJIDIC field, like F (frequency) or G (jouyou grade). Sorting is done
129 via a merged sort. This might be overkill, but I wanted to try doing
132 void KanjiList::Sort(int sortType
, bool reverseOrder
) {
133 int totalSize
= kanjiList
.size();
134 if(totalSize
<=1) return; /* Size 0 or 1 list is already sorted */
136 myCharIndexer
= new BoostHM
<wchar_t,int>;
137 myCharIndexer
->clear();
138 vector
<wchar_t>::iterator vi
;
140 /* Create index based on the sort type */
142 const KDict
* kd
= KDict::Get();
144 for(vi
=kanjiList
.begin();vi
!=kanjiList
.end();vi
++) {
145 ki
= kd
->GetEntry(*vi
);
146 if(sortType
==ST_GRADE
)
148 else if(sortType
==ST_FREQUENCY
)
152 oss
<< "Unknown sort type: " << sortType
<< endl
;
153 el
.Push(EL_Error
, oss
.str());
156 if(value
==-1) value
=INT_MAX
;
157 myCharIndexer
->assign(*vi
, value
);
160 /* Sort our data based upon the stored key in the hash table */
161 /* This code, a merge sort, was created based upon code at:
162 http://en.wikipedia.org/wiki/Merge_sort#C.2B.2B_implementation
163 These pages were referred to:
164 http://www.cppreference.com/cppalgorithm/merge.html
165 http://www.cppreference.com/cppalgorithm/inplace_merge.html */
166 int rangeSize
, rangeStart
;
167 for(rangeSize
=1; rangeSize
<totalSize
; rangeSize
*= 2) {
169 rangeStart
<totalSize
-rangeSize
;
170 rangeStart
+= rangeSize
*2) {
171 /* Our range sort function is HERE */
176 rangeStart
+ rangeSize
,
177 min(rangeStart
+ rangeSize
*2, totalSize
));
181 delete myCharIndexer
;
184 wchar_t KanjiList::operator[](unsigned int index
) {
185 if(index
<kanjiList
.size()) return kanjiList
[index
];
189 int KanjiList::GetIndexByChar(wchar_t c
) {
190 int i
, len
= kanjiList
.size();
192 if(kanjiList
[i
]==c
) return i
;
196 vector
<wchar_t>& KanjiList::GetVector() {return kanjiList
;}