Added .gitignore info for Windows build files.
[jben.git] / kanjilist.cpp
blob6f9c250fe4a2d49e59651bb67cc9f7641fc689c2
1 /*
2 Project: J-Ben
3 Author: Paul Goins
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)
8 File: kanjilist.cpp
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"
25 #include "global.h"
26 #include <algorithm>
27 using namespace std;
29 KanjiList::KanjiList(const BoostHM<wxChar,string> *kanjiDicHash) {
30 kanjiHash = kanjiDicHash;
33 #if 0
34 vector<wxChar>::iterator KanjiList::Find(wxChar c) {
35 vector<wxChar>::iterator it;
36 for(it=kanjiList.begin();it!=kanjiList.end();it++) {
37 if(*it==c) break;
39 return it;
41 #endif
43 int KanjiList::AddFromString(const wxString& s) {
44 int kanjiAdded = 0, len = s.length();
45 wxChar c;
46 BoostHM<wxChar,string>::const_iterator it;
48 for(int i=0;i<len;i++) {
49 c = s[i];
50 it = kanjiHash->find(c);
51 if(it!=kanjiHash->end()) {
52 if(find(kanjiList.begin(), kanjiList.end(), c)==kanjiList.end()) {
53 kanjiList.push_back(c);
54 kanjiAdded++;
59 return kanjiAdded;
62 wxString KanjiList::ToString() {
63 return ToString(0);
66 wxString KanjiList::ToString(int lineWidth) {
67 wxString result;
68 int lineWidthCounter=0;
69 int len = kanjiList.size();
70 for(int i=0;i<len;i++) {
71 result.append(kanjiList[i]);
72 if(lineWidth>0) {
73 lineWidthCounter++;
74 if(lineWidthCounter>=lineWidth) {
75 result.append(_T('\n'));
76 lineWidthCounter=0;
80 return result;
83 void KanjiList::Clear() {
84 kanjiList.clear();
87 int KanjiList::AddByGrade(int lowGrade, int highGrade) {
88 wxString kanjiStr;
89 int grade;
91 for(BoostHM<wxChar,string>::const_iterator ki=kanjiHash->begin(); ki!=kanjiHash->end(); ki++) {
92 grade = jben->kdict->GetIntField(ki->first, _T("G"));
93 if(grade>=lowGrade &&
94 (grade<=highGrade || highGrade==0))
95 kanjiStr.append(ki->first);
98 return AddFromString(kanjiStr);
101 int KanjiList::AddByFrequency(int lowFreq, int highFreq) {
102 wxString kanjiStr;
103 int freq;
105 for(BoostHM<wxChar,string>::const_iterator ki=kanjiHash->begin(); ki!=kanjiHash->end(); ki++) {
106 freq = jben->kdict->GetIntField(ki->first, _T("F"));
107 if(freq>=lowFreq && freq<=highFreq)
108 kanjiStr.append(ki->first);
111 return AddFromString(kanjiStr);
114 int KanjiList::Size() {return kanjiList.size();}
116 void KanjiList::InplaceMerge(vector<wxChar>& v, BoostHM<wxChar,int>& indexer, int start, int middle, int end) {
117 /* Merge is implemented as a bubble sort started at halfway
118 (since we know the first whole half is already sorted) */
119 int i, highIndex;
120 wxChar temp;
121 i = highIndex = middle;
122 while(i<end) {
123 if(i>0 && (indexer[v[i]] < indexer[v[i-1]])) {
124 temp = v[i-1];
125 v[i-1] = v[i];
126 v[i] = temp;
127 i--;
128 } else {
129 highIndex++;
130 i=highIndex;
136 SortKanjiList sorts the currently loaded kanji list based upon a specified
137 KANJIDIC field, like F (frequency) or G (jouyou grade). Sorting is done
138 via a merged sort. This might be overkill, but I wanted to try doing
139 it, so I did.
141 void KanjiList::Sort(int sortType, bool reverseOrder) {
142 int totalSize = kanjiList.size();
143 if(totalSize<=1) return; /* Size 0 or 1 list is already sorted */
145 myCharIndexer = new BoostHM<wxChar,int>;
146 myCharIndexer->clear();
147 vector<wxChar>::iterator vi;
149 wxString fieldMarker;
150 switch(sortType) {
151 case ST_GRADE:
152 fieldMarker=_T("G");
153 break;
154 case ST_FREQUENCY:
155 fieldMarker=_T("F");
156 break;
157 default:
158 fieldMarker=_T("INVALID");
161 /* Create index based on the sort type */
162 int value;
163 for(vi=kanjiList.begin();vi!=kanjiList.end();vi++) {
164 value = jben->kdict->GetIntField(*vi, fieldMarker);
165 if(value==-1) value=INT_MAX;
166 myCharIndexer->assign(*vi, value);
169 /* Sort our data based upon the stored key in the hash table */
170 /* This code, a merge sort, was created based upon code at:
171 http://en.wikipedia.org/wiki/Merge_sort#C.2B.2B_implementation
172 These pages were referred to:
173 http://www.cppreference.com/cppalgorithm/merge.html
174 http://www.cppreference.com/cppalgorithm/inplace_merge.html
176 The below is an original implementation designed to work with a wxHashMap and vector<wxChar>. */
177 int rangeSize, rangeStart;
178 for(rangeSize=1; rangeSize<totalSize; rangeSize *= 2) {
179 for(rangeStart=0; rangeStart<totalSize-rangeSize; rangeStart += rangeSize*2) {
180 /* Our range sort function is HERE */
181 InplaceMerge(
182 kanjiList,
183 *myCharIndexer,
184 rangeStart,
185 rangeStart + rangeSize,
186 min(rangeStart + rangeSize*2, totalSize));
190 #if 0
191 /* DEBUG ONLY: Check that the sort works as intended! */
192 if(totalSize>0) {
193 int lastVal = (*myCharIndexer)[kanjiList[0]];
194 for(int i=1;i<totalSize;i++) {
195 value = (*myCharIndexer)[kanjiList[i]];
196 if(value<lastVal)
197 fprintf(stderr, "Error! Index %d has value of %d, while %d has value of %d!\n", i, value, i-1, lastVal);
198 else
199 printf("%d=%d\t", i, value);
200 lastVal = value;
203 #endif
205 delete myCharIndexer;
208 #if 0
209 wxChar KanjiList::GetCharByIndex(unsigned int index) {
210 return operator[](index);
212 #endif
214 wxChar KanjiList::operator[](unsigned int index) {
215 if(index<kanjiList.size()) return kanjiList[index];
216 return _T('\0');
219 int KanjiList::GetIndexByChar(wxChar c) {
220 int i, len = kanjiList.size();
221 for(i=0;i<len;i++)
222 if(kanjiList[i]==c) return i;
223 return -1;
226 vector<wxChar>& KanjiList::GetVector() {return kanjiList;}