SophiaFramework UNIVERSE 5.3 |
以下のコードは、 ファイル(SFXFile)からカンマで区切られた CSV データを読み込み、 配列(SFXArray)に格納します。
例 13.9. ファイルから CSV データを読み込み、配列に格納する
SFCError error; // エラー値 SFXFile file; // SFXFile インスタンス SFXAnsiStringStreamReader reader; // ファイル読み込み用ストリーム SFXAnsiString stringFromFile; // データが読み込まれる変数 SFXAnsiString csvElement; SInt32 startOfComma, endOfComma; // カンマの位置 SInt32 sum; // 要素の和 SFXArray<SInt32> array; // SInt32 型データ要素からなる配列 SFXArray<SInt32>::Enumerator etor; // SInt32 型データ要素からなる配列の列挙子 // 読み込みモードでファイルを開く if ((error = file.OpenReadOnly(SFXPath("/data.csv"))) == SFERR_NO_ERROR) { // ファイル読み込み用ストリームの取得 ( バッファサイズ: 1024 ) if ((error = file.GetStreamReader(1024, &reader)) == SFERR_NO_ERROR) { // フェッチを行う if ((error = reader.Fetch()) == SFERR_NO_ERROR) { // ファイル読み込み用ストリームバッファから stringFromFile にデータを読み込む if ((error = reader.ReadSFXAnsiString(&stringFromFile)) == SFERR_NO_ERROR) { startOfComma = 0; // カンマの位置を探す endOfComma = stringFromFile.FirstIndexOf(','); while (endOfComma >= 0) { // カンマが見つかる限り繰り返す // 部分文字列を取得する csvElement = stringFromFile.Substring(startOfComma, endOfComma); // 文字列を数字に変換して array に格納する if ((error = array.InsertLast(csvElement.AsSInt32())) != SFERR_NO_ERROR) { // エラーが発生したとき break; } // 次のカンマを探すために startOfComma を設定する startOfComma = endOfComma + 1; // 次のカンマの位置を startOfComma 文字目から探す endOfComma = stringFromFile.FirstIndexOf(',', startOfComma); } if (error == SFERR_NO_ERROR) { // 最後の文字列を取得する csvElement = stringFromFile.Substring(startOfComma, stringFromFile.GetLength()); // 文字列を数字に変換して array に格納する if ((error = array.InsertLast(csvElement.AsSInt32())) == SFERR_NO_ERROR) { // ここで読み込みを完了する // 列挙子を取得する etor = array.GetFirstEnumerator(); sum = 0; while (etor.HasNext()) { // 各要素についての処理 SInt32 c; c = etor.GetNext(); // 次の要素を取得する sum += c; // その要素を加算する } TRACE("%d", sum); } } } } reader.Release(); } file.Close(); }
以下のコードは、 挿入ソートアルゴリズムを利用してリスト(SFXList)の要素をソートします。
例 13.11. リストのソート
SFCError error; // エラー値 SFXList<SInt32> list; // SInt32 型データ要素からなるリスト SFXList<SInt32>::Enumerator etor; // SInt32 型データ要素からなるリストの列挙子 SInt32 number[] = {14, 3, 22, -5, 8, 16, 1, 0, -7, -2}; // ソート対象のデータ SInt32 i, j, ithValue, jthValue; for (i = 0; i < lengthof(number); ++i) { error = list.InsertLast(number[i]);// 配列 number の要素を list に追加する if (error != SFERR_NO_ERROR) { // エラーが発生したとき ... return; } } // リストの要素を値でソートする // ※ 挿入ソートアルゴリズムを利用する for (i = 1; i < list.GetSize(); ++i) { ithValue = list.Get(i); // i 番目の要素の値を ithValue に格納する etor = list.GetFirstEnumerator(); // リストの列挙子を取得する for (j = 0; j < i; ++j) { // ※ 0 ≦ j < i jthValue = etor.GetNext(); // j 番目の要素の値を jthValue に格納する(列挙子は次の要素に進む) if (jthValue > ithValue) { // j 番目の要素の値が i 番目の要素の値よりも大きい場合 // j 番目の要素の前に i 番目の要素を移動する list.Remove(i); // i 番目の要素を削除する(i 番目の要素の値は ithValue に格納されている) error = list.Insert(j, ithValue); // j 番目の要素の前に旧 i 番目の要素の値を挿入する if (error != SFERR_NO_ERROR) { // エラーが発生したとき ... return; } break; } } } // すべての要素をデバッグウィンドウに表示する etor = list.GetFirstEnumerator(); // リストの列挙子を取得する while (etor.HasNext()) { TRACE("%d", etor.GetNext()); }
クラスインスタンスのように 4 バイトより大きなデータは、 要素としてコレクションクラスに格納できません。 このような場合は、4 バイトのポインタを要素としてコレクションクラスに格納します。
以下のコードは、 直線(SFXLine)をリスト(SFXList)の要素とし、 始点の X 座標でソートしています。
例 13.13. SFXLine インスタンスのリスト処理
SFCError error; // エラー値 SFXList<SFXLinePtr> list; // SFXLinePtr 型データの要素からなるリスト SFXList<SFXLinePtr>::Enumerator etor; // リスト要素の列挙子 SFXMTRandom random; // 乱数 SFXLinePtr line, ithLine, jthLine; // SFXLine インスタンスへのポインタ SInt32 i, j; // 10 個の直線を作成し、リストに格納する for (i = 0; i < 10; ++i) { // 始点と終点の座標値をランダム関数を使用して生成し、直線を作成する if ((line = new SFXLine(random.GetSInt16(), random.GetSInt16(), random.GetSInt16(), random.GetSInt16())) != null) { // 直線へのポインタを要素としてリストに追加する error = list.InsertLast(line); } else { // 直線の生成に失敗したとき error = SFERR_NO_MEMORY; } if (error != SFERR_NO_ERROR) { //エラーが発生したときはループを抜ける break; } } // リストに格納された直線を始点の X 座標でソートする // ※ 挿入ソートアルゴリズムを利用する if (error == SFERR_NO_ERROR) { for (i = 1; i < list.GetSize(); ++i) { ithLine = list.Get(i); // i 番目の直線へのポインタを ithLine に格納する etor = list.GetFirstEnumerator(); // リストの列挙子を取得する for (j = 0; j < i; ++j) { // ※ 0 ≦ j < i jthLine = etor.GetNext(); // j 番目の直線へのポインタを jthLine に格納する(列挙子は次の要素に進む) if (jthLine->GetStartX() > ithLine->GetStartX()) { // 直線の始点の X 座標に関して、j 番目の直線が i 番目の直線よりも大きい場合 // j 番目の直線の前に i 番目の直線を移動する list.Remove(i); // i 番目の要素を削除する(i 番目の直線そのものは削除されない) error = list.Insert(j, ithLine); // j 番目の要素の前に旧 i 番目の直線へのポインタを挿入する break; } } if (error != SFERR_NO_ERROR) { //エラーが発生したときはループを抜ける break; } } } // リストを使用後、要素をクリアする前に必ず直線を削除する // ※ これを行わないと、メモリリークが発生する etor = list.GetFirstEnumerator(); while (etor.HasNext()) { line = etor.GetNext(); delete line; } // リストをクリアする list.Clear();
以下のコードは、 ハッシュマップ(SFXLinkedHashMap)を利用して文字列中の単語の出現回数をカウントします。 ハッシュマップのペア要素のキーを単語、値を出現回数として処理しています。
例 13.14. 文字列のカウント
SFXAnsiString string("abc def def def ghi ghi"); // カウント対象の文字列 SFXLinkedHashMap<SFXAnsiString, SInt32> hashmap; // ハッシュマップ(キー: 単語、値: 出現回数) SFXAnsiString word; // 切り出した単語 Bool isAlphabet = false; // 英数字を処理中のときは true になる SInt32 startOfWord, endOfWord; SInt32 i; // 末尾にダミーの非アルファベット文字を追加する string += '.'; for (i = 0; i < string.GetLength(); ++i) { // string[i] が英数字であるか判定する if (SFXAscii::IsAlphaDigit(string[i])) { // 英数字を処理中でないとき if (!isAlphabet) { startOfWord = i; // 単語の先頭を設定する isAlphabet = true; } } else { // 英数字を処理中のとき if (isAlphabet) { endOfWord = i; // word の切り出し word = string.Substring(startOfWord, endOfWord); if (hashmap.ContainsKey(word)) { // word が含まれるとき // これまでの出現回数を取得する SInt32 count = hashmap.Get(word); // 回数を 1 加算する hashmap.Set(word, count + 1); } else { // 初めて出現したので、回数を 1 に設定する hashmap.Set(word, 1); } isAlphabet = false; } } } // 結果をデバッグウィンドウに表示する TRACE("\"def\": %d, \"ghi\": %d, \"abc\": %d, \"xyz\": %d", hashmap.Get("def"), hashmap.Get("ghi"), hashmap.Get("abc"), hashmap.Get("xyz"));
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |