- ベストアンサー
ユニークな文字列を順次, 生成する関数
C++において, 適当な文字列を元に, ユニークな文字列を順次, 生成する関数を作りたいと思っています. (LISPで云う, 関数gensym()と似た役割を持つ関数です.) 例えば, "hoge"というstringを元に, "hoge0", "hoge1", "hoge4", "hoge8", "hoge100", ...., といったように, stringが互いに重複しないように, 適当な数字を連結した文字列を順次生成したいのです. 以下のように, 私なりの方法を考えてみたのですが, これだと, 今まで生成したstringを保存するhoge_setが必要になります. 何かより良い(シンプル, 効率的な)方法がありましたら, 教えていただけますでしょうか? よろしくお願い致します. (乱数を用いた方法) 1. 元となるstring型の変数nameを, "hoge" で初期化. 既に作成したstring文字列を保存する, set < string > hoge_setを宣言. 2. 乱数を生成し, それをnameにappendしたものを, string型の変数name2に代入. 3. 同じ文字列が存在したら, 2. に戻る. 同じ文字列が存在しなかったら, hoge_setに追加する.
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
たとえば時刻を取得してそのまま使うとか、 16進変換して使うとか、 16進変換したものを暗号化して使うとかすれば できます。
その他の回答 (3)
- jacta
- ベストアンサー率26% (845/3158)
hoge_setを使うにしても、コンテナの要素をstringにする必要はないと思います。整数で十分ではないでしょうか? それより、double型に1.1ずつ加算するなどして、その内部表現を2進数で表せば、それなりに乱数ぽく見えます。さらに凝るなら、ビットの並びを反転してもよいでしょうし...。
- xcrOSgS2wY
- ベストアンサー率50% (1006/1985)
過去の実行で生成した文字列とも重複を避ける必要があり、なおかつ過去に生成した文字列を保存せずに済ませるには、過去と現在を明確に区別できるような何らかの情報を文字列に持たせる必要があります。 いちばん分かりやすいのは現在時刻でしょうか。例えば"hoge2005_06_25_13_03_40"などと生成するわけです。 このときに注意しないといけないことは2点あります。 (1) 文字列に持たせている時刻の分解能が1秒ですから、1秒未満の間隔で文字列を生成すると同じ文字列になってしまいます。これを避けるには、分解能より短い間隔で文字列生成のリクエストがあった場合次の時刻単位になるまで生成を待つ必要があります。分解能を上げれば(例えば1ミリ秒刻みにすれば)その頻度は減りますが、やはり同じ注意は必要です。 (2) 過去の実行と現在の実行で、利用している時刻設定が同じであることを保証する必要があります。例えば、あるパソコンAで実行した後、別のパソコンBで実行するような場合、パソコンAとパソコンBの時刻が正確に一致していないと、場合によっては同じ文字列が生成されてしまうことになります。
お礼
詳細な回答をいただき、どうもありがとうございます. (1), (2)の注意点を踏まえつつ, 参考にさせていただきます. 今のところ, No.2の回答者である「FAYさん」の回答に従って, 現在時刻を 暗号化して使おうかな, と思っています. 「FAYさん」がおっしゃるように, 文字列を暗号化する理由は (これは私の主観かもしれませんが), 生成される文字列に時間らしきものが入っていると, ユーザが,「この文字列は, 時間と深く関連を持たせる目的で, 生成した文字列なのかなぁ?」、 と誤解してしまうかもしれないからです. (正確には, 一意の文字列を生成する目的で, 現在時刻を使っています.)
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
生成される文字列はデタラメでなくてはならんのですか? そうでないなら、単に 000, 0001, 0002, ... で十分では?
補足
回答、ありがとうございます. 説明すべき内容が一部, 不足していました. どうもすみませんでした. 後々、複数のhoge_setを統合することを想定しています. ですから, できるだけ名前が衝突して欲しくない,と考えています.
お礼
そうですね. シンプルで,良い回答をしていただき, ありがとうございます!!