2006-12-20 ■ C++ C++ オブジェクト指向も大分わかってきた気がする。 気がする。 #include #include using namespace std; class Prime { private: int *PrimeList, *PrimeResult, *CountIndex; int ResCount, num; char equation[64]; void PrimeCalclator(int); public: bool PrimeChecker(int); int* PrimeListMaker(int, int); char* EquationMaker(int); }; // bool PrimeChecker(int); // 渡された値を素数かどうかチェックする // // 引数 -> 素数判定をする値 // 戻り値 -> 素数ならtrue, そうでないならfalse // bool Prime::PrimeChecker(int value) { int division = 3; int maxDiv = sqrt(value); // 1と2の例外処理 if (value == 1) return false; if (value == 2) return true; // 偶数も先にはじく if (value % 2 == 0) return false; // 受け取った値がその平方根までの奇数で割りきれるかを順番にチェック while (division <= maxDiv) { if ((value % division) == 0) return false; division += 2; } // チェックに一度も引っかからなければtrueを返す return true; } // int* PrimeListMaker(int); // 受け取った値までの素数リストを作成する // // 引数 -> int Max = 作成する素数リストの最大値, int division = リストの最大値を操作する値 // 戻り値 -> 素数リストが格納された配列の先頭のアドレス // int* Prime::PrimeListMaker(int Max, int division = 1) { int array = 1; num = 0; // array*100がMax/5を超えるまでarrayを増やす while ( (Max / 5) > (array * 100) ) array++; // その分だけメモリを確保、素数リスト用の配列とする PrimeList = new int[array * 100]; // リストの最大値を操作 *メソッドPrimeCalclator用* Max /= division; // Maxまでの数値を一つずつ素数判定していく for (int i = 1; i <= Max; i++) { // iがtrue(素数)なら素数リストのnum番目にiを代入する if ( Prime::PrimeChecker(i) ) { PrimeList[num] = i; num++; } } return PrimeList; } // void PrimeCalclator(int); // 受け取った値を素因数分解し、結果をPrimeResultとCountIndexに格納する // // 引数 -> int value = 素因数分解する値 // 戻り値 -> なし // void Prime::PrimeCalclator(int value) { int count = 0, PowCount = 1; ResCount = 0; // 素数リストの取得 Prime::PrimeListMaker(value, 2); PrimeResult = new int[num / 2]; // 割れる数を格納する配列 CountIndex = new int[num / 2]; // 割れる回数(指数)を格納する配列 // 条件判定のため先頭のみ初期化 PrimeResult[0] = NULL; // valueが1になるまで割り続ける do { if ( value % PrimeList[count] == 0 ) { // 値が素数で割り切れた場合 // 初めて割る数はPrimeResultに格納する if (PowCount == 1) { if (PrimeResult[0] != NULL) ResCount++; //割れる数が見つかるまではインクリメントしない PrimeResult[ResCount] = PrimeList[count]; } // 現在の指数を格納する CountIndex[ResCount] = PowCount; // 割られる数と指数の更新 value /= PrimeList[count]; PowCount++; } else { // 割り切れなかった場合は指数を初期化し、カウンターを回す PowCount = 1; count++; } } while (value != 1); delete PrimeList; } // char* EquationMaker(int); // 式をchar配列型で生成する // // 引数 -> 素因数分解する値 // 戻り値 -> 式を格納した文字列の先頭のアドレス // char* Prime::EquationMaker(int input){ int StrPoint; // ** 例外処理 ** // inputが1ならここでプログラムを終わる if (input == 1) { sprintf(equation, "%d = %d", input, input); return equation; } // inputが素数ならここでプログラムを終わる if ( Prime::PrimeChecker(input) ) { sprintf(equation, "%d = %d", input, input); return equation; } // 素因数分解 Prime::PrimeCalclator(input); // 書式 => "input = PrimeResult[i]^CountIndex[i] * PrimeResult[i]..." StrPoint = sprintf(equation, "%d = ", input); for (int i = 0; i <= ResCount; i++) { // i個目の割れる数を記入 StrPoint += sprintf(equation + StrPoint, "%d", PrimeResult[i]); // i番目の指数が1でないなら記入 if (CountIndex[i] != 1) StrPoint += sprintf(equation + StrPoint, "^%d", CountIndex[i]); // ループの終わり(式の終わり)でないなら記入 if (i != ResCount) StrPoint += sprintf(equation + StrPoint, " * "); } delete PrimeResult; delete [] CountIndex; return equation; } // // メイン関数 // void main() { Prime judgment; int input; char *answer[64]; cout << "素因数分解したい数値を入力してください:"; cin >> input; // 結果の取得 *answer = judgment.EquationMaker(input); cout << *answer << endl; }