OSDN Git Service

UTF-8
[jugglemaster/source.git] / workspace / JuggleMaster / src / com / jm / gen / StringEx.java
1 package com.jm.gen;\r
2 \r
3 public class StringEx {\r
4         public static int InStrEx(int uStart, char[] sText1, char[] sText2)\r
5         {\r
6             //char[] sFound;\r
7             int sFound;\r
8             int  uLen1, uLen2;\r
9 \r
10             // 比較可能性をチェック\r
11             uLen1 = StdLib.strlen(sText1);\r
12             uLen2 = StdLib.strlen(sText2);\r
13             if(!(uLen1 > 0) || !(uLen2 > 0) || !(uStart > 0) || uStart > (uLen1 - uLen2 + 1))\r
14                 return 0;\r
15 \r
16             sFound = StdLib.strstr(sText1, uStart - 1, sText2);\r
17             if(sFound >= 0)\r
18                 //return sFound - sText1 + 1;\r
19                 return sFound + 1;\r
20             else\r
21                 return 0;\r
22         }\r
23 \r
24         public static int TextToIntArray(char[] sText, int[] pdwValue, int iSize, boolean bCompress){\r
25             char[] sTrans;\r
26             char[] sBuff;\r
27             int[] pdwBuff;\r
28             int dwSwap;\r
29             int wFirst;\r
30             int wLast;\r
31             int wSwap;\r
32             boolean bZero;\r
33             char ch;\r
34             char[] sNum = new char[10];\r
35             int i;\r
36             int j;\r
37             int iLen;\r
38             int iCount;\r
39             int iBlock;\r
40             int iIndex;\r
41             int iStart;\r
42             int iEnd;\r
43 \r
44             // 引数チェック\r
45             iLen = StdLib.strlen(sText);\r
46             if(!StdLib.toBoolean(iLen))\r
47                 return 0;\r
48 //          for(i = 0; i < iLen; i++)\r
49 //              // 2バイト文字が含まれていたら中止\r
50 //              if(_ismbblead(sText[i]))\r
51 //                  return -1;\r
52 \r
53             // 文字列の整形\r
54             sBuff = new char[iLen * 4 + 1];\r
55             iCount = 0;\r
56             for(i = 0; i < iLen; i++){\r
57                 if(StdLib.isalpha(sText[i])){\r
58                     // a〜z を 10〜35 に変換\r
59                     sBuff[iCount] = '\0';\r
60                     //wsprintf(sNum, " %02d ", StdLib.tolower(sText[i]) - 'a' + 10);\r
61                     StdLib.wsprintf(sNum, StdLib.tolower(sText[i]) - 'a' + 10);\r
62                     StdLib.strcat(sBuff, sNum);\r
63                     iCount += 4;\r
64                 }\r
65                 else{\r
66                     sBuff[iCount] = sText[i];\r
67                     iCount++;\r
68                 }\r
69             }\r
70             iLen = iCount;\r
71             // 記号を変換\r
72             sTrans = new char[iLen + 1];\r
73             iCount = 0;\r
74             ch = ' ';\r
75             // 内部状態 ch が取りうる値は '0'、'1'、' '、'-' の4つで、それぞれ\r
76             // 「区切られた数字」「区切られていない数字」「区切り」「継続」を表す\r
77             for(i = 0; i < iLen; i++){\r
78                 // 冗長な記号を削除\r
79                 switch(sBuff[i])\r
80                     {\r
81                     case '0':\r
82                     case '1':\r
83                     case '2':\r
84                     case '3':\r
85                     case '4':\r
86                     case '5':\r
87                     case '6':\r
88                     case '7':\r
89                     case '8':\r
90                     case '9':\r
91                         // 数字のとき\r
92                         if(ch == '0'){\r
93                             // 内部状態が区切られた数字なら空白を出力\r
94                             sTrans[iCount] = ' ';\r
95                             iCount++;\r
96                         }\r
97                         // 数字を出力して、内部状態を区切られていない数字に変更\r
98                         sTrans[iCount] = sBuff[i];\r
99                         iCount++;\r
100                         ch = '1';\r
101                         break;\r
102 \r
103                     case ' ':\r
104                         // 空白のとき\r
105                         if(ch == '1')\r
106                             // 内部状態が区切られていない数字なら、これを区切られた数字に変更\r
107                             ch = '0';\r
108                         break;\r
109 \r
110                     case ',':\r
111                         // コンマのとき\r
112                         if(ch != ' '){\r
113                              // 内部状態が区切りでなければ空白を出力\r
114                             sTrans[iCount] = ' ';\r
115                             iCount++;\r
116                         }\r
117                         // 内部状態を区切りに変更\r
118                         ch = ' ';\r
119                         break;\r
120 \r
121                     case '-':\r
122                         // 範囲記号のとき\r
123                         if(ch != '-'){\r
124                              // 内部状態が継続でなければ範囲記号を出力\r
125                             sTrans[iCount] = '-';\r
126                             iCount++;\r
127                         }\r
128                         // 内部状態を継続に変更\r
129                         ch = '-';\r
130                         break;\r
131 \r
132                     default:\r
133                         // それ以外なら中止\r
134                         //free(sTrans);\r
135                         //free(sBuff);\r
136                         sTrans = null;\r
137                         sBuff = null;\r
138                         \r
139                         return -1;\r
140                     }\r
141             }\r
142             sTrans[iCount] = '\0';\r
143 \r
144             // 単独のハイフンを除去\r
145             iIndex = InStrEx(1, sTrans, StdLib.stoc(" - "));\r
146             while(iIndex > 0){\r
147                 sTrans[iIndex] = '\0';\r
148                 StdLib.strcpy(sBuff, sTrans);\r
149                 //StdLib.strcat(sBuff, sTrans + iIndex + 2);\r
150                 StdLib.strcat(sBuff, sTrans, iIndex + 2);\r
151                 StdLib.strcpy(sTrans, sBuff);\r
152                 iIndex = InStrEx(1, sTrans, StdLib.stoc(" - "));\r
153             }\r
154             if(sTrans[0] == '-' && sTrans[1] == ' '){\r
155                 // 先頭の単独ハイフンも除去\r
156                 //StdLib.strcpy(sBuff, sTrans + 2);\r
157                 StdLib.strcpy(sBuff, sTrans, 2);\r
158                 StdLib.strcpy(sTrans, sBuff);\r
159             }\r
160             iCount = StdLib.strlen(sTrans);\r
161             if(iCount > 1)\r
162                 if(sTrans[iCount - 1] == '-' && sTrans[iCount - 2] == ' ')\r
163                     // 末尾の単独ハイフンも除去\r
164                     sTrans[iCount - 2] = '\0';\r
165             if(!StdLib.toBoolean(StdLib.strlen(sTrans))){\r
166                 // 文字列に数字が指定されていなければ関数を抜ける\r
167                 //free(sTrans);\r
168                 //free(sBuff);\r
169                 sTrans = null;\r
170                 sBuff = null;\r
171                 \r
172                 return 0;\r
173             }\r
174 \r
175             // 必要な配列の大きさを取得\r
176             iBlock = 1;\r
177             // ブロック数を数える\r
178             iIndex = InStrEx(1, sTrans, StdLib.stoc(" "));\r
179             while(iIndex > 0){\r
180                 iBlock++;\r
181                 iIndex = InStrEx(iIndex + 2, sTrans, StdLib.stoc(" "));\r
182             }\r
183 \r
184             pdwBuff = new int[iBlock];\r
185             // 整形された文字列を自然数の配列に変換\r
186             iStart = 0;\r
187             for(i = 0; i < iBlock; i++){\r
188                 //strcpy(sBuff, sTrans + iStart);\r
189                 StdLib.strcpy(sBuff, sTrans, iStart);\r
190                 iEnd = InStrEx(1, sBuff, StdLib.stoc(" "));\r
191                 iIndex = InStrEx(1, sBuff, StdLib.stoc("-"));\r
192                 if(StdLib.toBoolean(iEnd))\r
193                     // 区切りがあればその前まで\r
194                     sBuff[iEnd - 1] = '\0';\r
195                 else\r
196                     // なければ最後まで\r
197                     iEnd = StdLib.strlen(sBuff) + 1;\r
198                 if(StdLib.toBoolean(iIndex) && iIndex < iEnd){\r
199                     // 範囲指定の場合\r
200                     sBuff[iIndex - 1] = '\0';\r
201                     wFirst = StdLib.atoi(sBuff);\r
202                     //wLast = StdLib.atoi(sBuff + iIndex);\r
203                     wLast = StdLib.atoi(sBuff, iIndex);\r
204                     if(iIndex == iEnd - 1)\r
205                         wLast = 0xFFFF;\r
206                     if(wFirst > wLast){\r
207                         // 範囲の開始数が終了数より大きければこれを交換\r
208                         wSwap = wFirst;\r
209                         wFirst = wLast;\r
210                         wLast = wSwap;\r
211                     }\r
212                     if(wFirst == wLast)\r
213                         // 範囲の開始数と終了数が同じなら単独の数値とみなす\r
214                         pdwBuff[i] = wFirst;\r
215                     else\r
216                         pdwBuff[i] = StdLib.MAKELONG(wFirst, wLast);\r
217                 }\r
218                 else\r
219                     // 単独の数値の場合\r
220                     pdwBuff[i] = StdLib.atoi(sBuff);\r
221                 iStart += iEnd;\r
222             }\r
223 \r
224             // 数字の昇順に並べ替え\r
225             for(i = 0; i < iBlock - 1; i++){\r
226                 for(j = i + 1; j < iBlock; j++){\r
227                     if(StdLib.LOWORD(pdwBuff[j]) < StdLib.LOWORD(pdwBuff[i])){\r
228                         dwSwap = pdwBuff[j];\r
229                         pdwBuff[j] = pdwBuff[i];\r
230                         pdwBuff[i] = dwSwap;\r
231                     }\r
232                 }\r
233             }\r
234             // 単独の 0 があるかどうか調べる\r
235             if(StdLib.toBoolean(pdwBuff[0]))\r
236                 bZero = false;\r
237             else\r
238                 bZero = true;\r
239 \r
240             // 冗長な数字を削除\r
241             if(bCompress){\r
242                 // 全く同じ数字があれば削除\r
243                 for(i = 0; i < iBlock - 1; i++){\r
244                     for(j = i + 1; j < iBlock; j++){\r
245                         if(StdLib.toBoolean(pdwBuff[j]) && pdwBuff[j] == pdwBuff[i])\r
246                             pdwBuff[j] = 0;\r
247                     }\r
248                 }\r
249                 // 連続する単独の数字を範囲に変換する\r
250                 for(i = 0; i < iBlock - 1; i++){\r
251                     if(!StdLib.toBoolean(StdLib.HIWORD(pdwBuff[i]))){\r
252                         wFirst = StdLib.LOWORD(pdwBuff[i]);\r
253                         wSwap = wFirst;\r
254                         for(j = i + 1; j < iBlock; j++){\r
255                             if(!StdLib.toBoolean(StdLib.HIWORD(pdwBuff[j]))){\r
256                                 wLast = StdLib.LOWORD(pdwBuff[j]);\r
257                                 if(wLast == wSwap + 1){\r
258                                     pdwBuff[i] = StdLib.MAKELONG(wFirst, wLast);\r
259                                     pdwBuff[j] = 0;\r
260                                     wSwap = wLast;\r
261                                 }\r
262                             }\r
263                         }\r
264                     }\r
265                 }\r
266                 // 範囲内に単独の数字、重なる範囲、およびその前後の数字を取り込む\r
267                 for(i = 0; i < iBlock; i++){\r
268                     wFirst = StdLib.LOWORD(pdwBuff[i]);\r
269                     wLast  = StdLib.HIWORD(pdwBuff[i]);\r
270                     if(StdLib.toBoolean(wLast)){\r
271                         // 範囲指定があれば処理する\r
272                         for(j = 0; j < iBlock; j++){\r
273                             wSwap = StdLib.LOWORD(pdwBuff[j]);\r
274                             if(j != i && (StdLib.toBoolean(wSwap) || bZero)){\r
275                                 // 自分自身や指定されていない 0 はチェックしない\r
276                                 if(StdLib.toBoolean(StdLib.HIWORD(pdwBuff[j]))){\r
277                                     // 別の範囲だった場合\r
278                                     if(wFirst <= wSwap && wSwap <= wLast){\r
279                                         wLast = Math.max(wLast, StdLib.HIWORD(pdwBuff[j]));\r
280                                         pdwBuff[i] = StdLib.MAKELONG(wFirst, wLast);\r
281                                         pdwBuff[j] = 0;\r
282                                     }\r
283                                 }\r
284                                 else{\r
285                                     // 単独の数字だった場合\r
286                                     if(wFirst - 1 <= wSwap && wSwap <= wLast + 1){\r
287                                         wFirst = Math.min(wFirst, wSwap);\r
288                                         wLast  = Math.max(wLast,  wSwap);\r
289                                         pdwBuff[i] = StdLib.MAKELONG(wFirst, wLast);\r
290                                         pdwBuff[j] = 0;\r
291                                     }\r
292                                 }\r
293                             }\r
294                         }\r
295                     }\r
296                 }\r
297                 // 0が入った配列を除いて詰める\r
298                 i = 0;\r
299                 while(i < iBlock - 1){\r
300                     if(StdLib.toBoolean(pdwBuff[i]))\r
301                         i++;\r
302                     else{\r
303                         for(j = i + 1; j < iBlock; j++)\r
304                             pdwBuff[j - 1] = pdwBuff[j];\r
305                         iBlock--;\r
306                         pdwBuff[iBlock] = 0;\r
307                     }\r
308                 }\r
309                 i = 0;\r
310                 while(i < iBlock && StdLib.toBoolean(pdwBuff[i]))\r
311                     i++;\r
312                 iBlock = i;\r
313                 // 0 が指定されていたとき\r
314                 if(bZero){\r
315                     wFirst = StdLib.LOWORD(pdwBuff[0]);\r
316                     if(StdLib.toBoolean(wFirst)){\r
317                         // 0 が存在しなければこれを挿入\r
318                         wLast = StdLib.HIWORD(pdwBuff[0]);\r
319                         if(StdLib.toBoolean(wLast)){\r
320                             // 最初の数字が範囲だった場合\r
321                             if(wFirst == 1)\r
322                                 pdwBuff[0] = StdLib.MAKELONG(0, wLast);\r
323                             else{\r
324                                 for(i = iBlock; i > 0; i--)\r
325                                     pdwBuff[i] = pdwBuff[i - 1];\r
326                                 pdwBuff[0] = 0;\r
327                                 iBlock++;\r
328                             }\r
329                         }\r
330                         else{\r
331                             // 最初の数字が単独の数字だった場合\r
332                             if(wFirst == 1)\r
333                                 pdwBuff[0] = StdLib.MAKELONG(0, 1);\r
334                             else{\r
335                                 for(i = iBlock; i > 0; i--)\r
336                                     pdwBuff[i] = pdwBuff[i - 1];\r
337                                 pdwBuff[0] = 0;\r
338                                 iBlock++;\r
339                             }\r
340                         }\r
341                     }\r
342                     else\r
343                         if(iBlock == 0)\r
344                             iBlock++;\r
345                 }\r
346             }\r
347 \r
348             // 整数配列が指定されていればここに値を格納\r
349             if(pdwValue != null && StdLib.toBoolean(iSize)){\r
350                 iBlock = Math.min(iBlock, iSize);\r
351                 for(i = 0; i < iBlock; i++)\r
352                     pdwValue[i] = pdwBuff[i];\r
353             }\r
354 \r
355             // 後始末\r
356             //free(sTrans);\r
357             //free(sBuff);\r
358             //free(pdwBuff);\r
359             sTrans = null;\r
360             sBuff = null;\r
361             pdwBuff = null;\r
362             \r
363             return iBlock;\r
364         }\r
365 }\r