DOBON.NET DOBON.NETプログラミング掲示板過去ログ

文字列の自動生成

  • 題名: 文字列の自動生成
  • 著者: まや
  • 日時: 2008/11/07 10:46:35
  • ID: 23321
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[.NetFramework2.0 VS2005]
分類:[.NET]

文字列を自動生成しようと考えていますが、やり方がイマイチわからないので
教えて頂けないでしょうか。

「a,b,c」の文字からなる、「2」桁の文字で作成できる文字列のパターンを
生成します。
この場合、
aa
ab
ac
ba
bb
bc
ca
cb
cc
の9通りです。(文字数)の(桁数)乗

オブジェクト指向で作成すればできそう?と思ったのですが、どのように
すればいいかわかず、参考サイトもなかなか見つけれないでいます。

ご教授頂けないでしょうか。宜しくお願いします。
> 環境/言語:[.NetFramework2.0 VS2005] 
> 分類:[.NET] 

言語は何ですか?VB or C# or その他?

> 文字列を自動生成しようと考えていますが、やり方がイマイチわからないので
> 教えて頂けないでしょうか。

どの辺りがわかりませんか?説明しにくいと思いますが、
どこまで考えたのかを明示して頂かないとどう説明するのがよいのか判断できません。
まやさんが、文字列の連結はできるのか/できないのか、もわからない状況です。

これを実現するために必要な知識を挙げます。
(1) 文字列を連結する方法
(2) 配列またはリストで複数のデータをまとめて扱う方法
(3) ループ処理(特にFor文)
(4) 配列またはリストから順にデータを取り出す方法 ((2)と(3)を組み合わせる)

ここまでできればやりたいことができます。

> 「a,b,c」の文字からなる、「2」桁の文字で作成できる文字列のパターンを
> 生成します。
> この場合、
> aa
> ab
> ac
> ba
> bb
> bc
> ca
> cb
> cc
> の9通りです。(文字数)の(桁数)乗

一気に完成を目指すのではなく、そこに辿り着くために必要な知識を身につけてください。

まずは文字a、b、cを順番に表示するプログラムは作成してみてはどうでしょうか。
ただし、

Console.WriteLine("a")
Console.WriteLine("b")
Console.WriteLine("c")

のように「文字列を表示する」処理を3つ並べるのではなくFor文を使って、
3つの文字列データを表示するやり方で作成してください。
申し訳ありません。ご指摘の通り、どこまでができる範囲なのか明記できていませんでした。

[VB.Net]
Dim word() As String = {"a", "b", "c"}
Dim s As String
For i As Integer = 0 To word.Length() - 1
 For j As Integer = 0 To word.Length() - 1
  s = word(i) & word(j)
  Console.WriteLine(s)
 Next
Next

上記のようにすれば、とりあえず要件は満たせるのですが、生成する文字列の桁数が
増えると上記ロジックでは当然のことながら、For分が増える一方です。
桁数を増やしても(パラメータで渡せるようにする)ロジックの修正なしで対応できれば
と思っています。

この要件を満たすには、オブジェクト指向で記述すればいいのではないか?とまでは
思ったのですが、どのように実装すればよいのかがわかりませんでした。

宜しくお願い致します。
なるほど、基本的な実装はできているけれど、今考えている実装では、
桁数が増えるとFor文のループを増やす必要があり、動的に桁数を変更できない、
ということが問題だったのですね。

> この要件を満たすには、オブジェクト指向で記述すればいいのではないか?と
> までは思ったのですが、どのように実装すればよいのかがわかりませんでした。

オブジェクト指向はまったく関係なくて、純粋なアルゴリズムの問題です。
いくつかやり方はあると思いますが、今、私が考えた方法をご紹介します。
--
以降の話で、"a","b","c"といった文字の種類の数をX、桁数をNとしてお話します。

考え方のポイントは以下の2点です。
【1】 N重ループを1重ループに変換する
【2】 順列を作るということはN桁まで数字をX進数で数え上げることと同じ

順を追って説明します。
【1】N重ループを1重ループに変換する

For i = 0 To X - 1 
   For j = 0 To X -1

というループは、

For i = 0 To X ^ 2 - 1

と直せます。N重ループが相手なら、

For i = 0 To X ^ N - 1

となります。さらに、このループの中で、N桁の文字列を作りたいので、
N回ループするFor文を追加してやります。そうすると

For i = 0 To X ^ N - 1
    For j = 0 To N - 1

これで文字の種類、桁数が可変の順列を作るためのFor文が完成です。

【2】順列を作るということはN桁まで数字をX進数で数え上げることと同じ

「"a","b","c"の3種類で2桁を文字列を作る」という作業は具体的に何を
やっているか見てみましょう。"a","b","c"という個々の文字ではなく、
それぞれを0番目の要素、1番目の要素、2番目の要素として見ると、
すべての順列は以下のようになります。

順列  要素の番号
aa    0 0
ab    0 1
ac    0 2
ba    1 0
bb    1 1
bc    1 2
ca    2 0
cb    2 1
cc    2 2

要素の番号の2桁目(右の桁)を見てください。0、1、2、0、1、2、…と
0〜2の繰り返しになっています。1桁目はというと、2桁目が2になった直後に
値が増えています。

例えば、99までの数字を数えることを想像してください。2桁に揃えて数える
内容を記載すると00、01、02、〜08、09、10、11、・・・、99となります。
これは10進数の数値ですが、順列の要素の番号は0〜2の3種類の数字で
構成される数値、つまり、3進数の数値になっています。
つまり、「"a","b","c"の3種類で2桁を文字列を作る」という問題は3進数の
数値を数え上げること言い換えることができます。
一般化するとX進数のN桁の数字をすべて作成することと同じと言えます。

ここまでのヒントでどうでしょうか。
ありがとうございます。
そのような考え方をすると、オブジェクト指向と捉えなくても
よかったんですね。
大変わかりやすい説明で、概念は理解できました。


For i As Integer = 0 To X ^ N - 1
 '↑実際に生成されるパスワードの個数分ループしている
 s = String.Empty
 For j As Integer = 0 To N - 1
  '↑1番目の要素から、3番目の要素まで繰り返すことで
  ' 文字列を連結していく
  s = s & ○○○
 Next
 Console.WriteLine("生成された文字列:" & s)
Next


上記のような流れになるのではと思ったのですが、「○」で書いた箇所に
実際どのような値を入れれば思うように文字列を生成できるかわからず
つまづいてしまいました。
> 上記のような流れになるのではと思ったのですが、「○」で書いた箇所に
> 実際どのような値を入れれば思うように文字列を生成できるかわからず

○○○に入れたいものは、"a"や"b"や"c"ですよね。
これらの値はまやさんのコードで言うと配列wordに入っています。
適切なword(index)の値が○○○に入れたい値ということになります。
このindexをどう計算すればいいのかわからない、ということかと思いますが、
これは先ほど書いた通り「N桁までの数字をX進数で数え上げる」ことと同じことです。

まずどういう結果にならないといけないのかを確認しましょう。
今作ろうとしているものの想定では、例えば、"ac"という文字列を生成するときはi=2になっています。
そして、j=0のときindex=0、j=1のときindex=2と結果を得る必要があります。

iとjとXからindexの0や2を求めるわけです。他の生成文字列の場合も踏まえて、
どういう計算をしないといけないのかを考えてください。

ここでちょっとしたお題です。
「123という数値を1と2と3に分割してください。
 文字列として処理するのではなく、計算で分割すること。
 使用するのは、For文と演算子「\、Mod、^」です。」

これができれば解決すると思います。
すいません・・・

>
> ここでちょっとしたお題です。
> 「123という数値を1と2と3に分割してください。
>  文字列として処理するのではなく、計算で分割すること。
>  使用するのは、For文と演算子「\、Mod、^」です。」
>

ここで言う、「Mod」は余り、「^」は階乗、「\」は何ですか??
  • 題名: Re[7]: 文字列の自動生成
  • 著者: よねKEN
  • 日時: 2008/11/07 23:04:56
  • ID: 23336
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
■No23334に返信(まやさんの記事)

> ここで言う、「Mod」は余り、「^」は階乗、「\」は何ですか??

ヘルプ調べましたか?
Web上なら以下に記載があります。
「機能別の演算子一覧」
http://msdn.microsoft.com/ja-jp/library/asfcc119(VS.80).aspx
(\マークはこちらの一覧ではバックスラッシュ(/の左右反対の記号になっていますが、同じ意味です。)

後、単なる書き間違いだと思いますが、「^」は階乗ではなくべき乗ですね。

DOBON.NET | プログラミング道 | プログラミング掲示板