順列を列挙するプログラムの変更点は?

このQ&Aのポイント
  • 組み合わせを求めるプログラムを順列を列挙するプログラムに変更する方法を教えてください。
  • VBのプログラムで、組み合わせを求めるアルゴリズムを順列を列挙するアルゴリズムに変更する方法を教えてください。
  • 順列を列挙するプログラムで、どの部分を変更すると組み合わせから順列を求めることができるのか教えてください。
回答を見る
  • ベストアンサー

順列のプログラムについて(VB)

下記が、組み合わせを求めるプログラムです。 これのどこを変更すれば、順列を列挙するプログラムになりますか(ただし、重複順列でない。例、5P2=5*4=20通り)?教えていただけませんか? Public Class Form1 Dim w0, w1, count As String Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.Text = "コンビネーションサーチ" Label1.Text = "個の中から" Label2.Text = "個とる組リスト" Button1.Text = "計算" TextBox1.Text = "6" TextBox2.Text = "3" TextBox3.Text = "" TextBox3.ScrollBars = ScrollBars.Vertical count = 0 End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim n, m As Integer n = TextBox1.Text m = TextBox2.Text w1 = " }" w0 = "{ " TextBox3.Text = "" count = 0 combisearch(1, n, m) MsgBox("組み合わせ個数は、" & count & "個です。") End Sub Sub combisearch(ByVal st, ByVal ed, ByVal depth) Dim i, temp If depth - 1 < 1 Then For i = st To ed TextBox3.Text &= w0 & i & w1 & vbCrLf count += 1 Next Else For i = st To ed temp = w0 w0 &= i & " " combisearch(i + 1, ed, depth - 1) w0 = temp Next End If End Sub End Class

質問者が選んだベストアンサー

  • ベストアンサー
  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.5

ANo2~5です。 すいませんが、これまでのは、廃棄願います。 Public Class Form1 Dim w0, w1, count As String dim w2 As String '★追加 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.Text = "コンビネーションサーチ" Label1.Text = "個の中から" Label2.Text = "個とる組リスト" Button1.Text = "計算" TextBox1.Text = "6" TextBox2.Text = "3" TextBox3.Text = "" TextBox3.ScrollBars = ScrollBars.Vertical count = 0 End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim n, m As Integer n = TextBox1.Text m = TextBox2.Text w1 = " }" w0 = "{ " TextBox3.Text = "" count = 0 combisearch(1, n, m) MsgBox("組み合わせ個数は、" & count & "個です。") End Sub Sub combisearch(ByVal st, ByVal ed, ByVal depth) Dim i, temp If depth - 1 < 1 Then For i = 1 To ed '★置き換え 'For i = st To ed If InStr(w2, CStr(i) & " ") = 0 Then '★追加:重複の除外 TextBox3.Text &= w0 & i & w1 & vbCrLf count += 1 End If '★追加 Next w2 = "" '★追加 Else For i = 1 To ed '★置き換え 'For i = st To ed If InStr(w2, CStr(i) & " ") = 0 Then '★追加:重複の除外 temp = w0 w0 &= i & " " w2 = w2 & i & " " '★追加 combisearch(i + 1, ed, depth - 1) w0 = temp w2 = temp '★追加 End If '★追加 Next End If End Sub End Class ## EXCEL VBAで試しているので ## 書き換えでミスばっかりしてすいません。 5P4=120 と 5P2=20 がうまくいっていたのでたぶん大丈夫かと。

toshisanpc
質問者

お礼

今まで、ご回答ありがとうございました。 おかげさまで、見事順列列挙プログラムが完成しました。 また、プログラムのことで何か困ったことがあれば、ご回答お願いいたします。

その他の回答 (4)

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.4

あっ、すいません。 combisearch(1, ed, depth - 1 , i) です。 でも、depth = 2 のときうまくいくはずですが、 depth >2 のときに問題があることに気づいたのでちょっと考え直して改めて回答いれます。

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.3

ANo.2です。 >補足 >この方法では、重複順列を許しております。 大変失礼しました。 うっかりミスしていました。 以下の例のようにサブルーチンに除外する数字を渡すことで対応できると思います。 注:-999999999は除外する数字はないという意味。 ・・・ combisearch(1, n, m,-999999999) 'combisearch(1, n, m) MsgBox("組み合わせ個数は、" & count & "個です。") End Sub Sub combisearch(ByVal st, ByVal ed, ByVal depth,ByVal myVal) 'Sub combisearch(ByVal st, ByVal ed, ByVal depth) Dim i, temp If depth - 1 < 1 Then For i = st To ed if i <> myVal then '追加:重複の除外 TextBox3.Text &= w0 & i & w1 & vbCrLf count += 1 end if '追加 Next Else For i = st To ed if i <> myVal then '追加:重複の除外 temp = w0 w0 &= i & " " 'ここだけ。 combisearch(1, ed, depth - 1) 'combisearch(i + 1, ed, depth - 1) w0 = temp end if '追加 Next End If End Sub

toshisanpc
質問者

補足

2回目のご回答ありがとうございます。 しかし、 permsearch(1, ea, deptha - 1) の部分で、下記のエラーが出ます。 誠に申し訳ありませんが、どう対処すればよいでしょうか。 教えていただけませんでしょうか。 エラーメッセージ内容 ここから エラー 1 説明:'Public Sub permsearch(sa As Object, ea As Object, deptha As Object, myVal As Object)' のパラメーター    'myVal' に対して引数が指定されていません。 ファイル:G:\順列 & 組み合わせ探索\順列 組み合わせ探索\順列 組み合わせ探      索\Form1.vb 行:150 列:21 プロジェクト:順列 組み合わせ探索 ここまで なお、stは、saに、edは、eaに、depthは、depthaに変えております。

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.2

Sub combisearch(ByVal st, ByVal ed, ByVal depth) Dim i, temp If depth - 1 < 1 Then For i = st To ed TextBox3.Text &= w0 & i & w1 & vbCrLf count += 1 Next Else For i = st To ed temp = w0 w0 &= i & " " 'ここだけ。 combisearch(1, ed, depth - 1) 'combisearch(i + 1, ed, depth - 1) w0 = temp Next End If End Sub End Class

toshisanpc
質問者

補足

ご回答ありがとうございました。 しかし、この方法では、重複順列を許しております。 たとえば、5,2と入力すれば、5*4=20通りとなるのですが、ここでは、25となります。 つまり、(1,1).(2,2).(3,3).(4,4).(5,5)が余計です。 これを省く方法をできれば教えていただけませんでしょうか。 お願いいたします。

回答No.1

無理に拡張しようとせず、設計しなおした。 https://ideone.com/52cT1

関連するQ&A

  • このような使い方は間違っているのでしょうか?(VB.NET2002)

    このような使い方は間違っているのでしょうか?(VB.NET2002) Dim count As Int16 Private Sub JOB(ByVal x) x = x + 1 TextBox1.Text = x End Sub Private Sub Button1_Click(・・・・ JOB(count) End Sub

  • VBで倍数を出したい

    VBで倍数を出したい よろしくお願いします。 おそらく基本なんだと思うのですが、さっぱりわかりません。 TextBox Label Buttonと並んでいて、 TextBoxに入った整数に対し、 Buttonを1度押すたびに、 Labelに倍数が表記されていく、 という趣旨なのですが。 まず、前段階として下記を作らされました。 Public Class Form1 Dim i As Integer Dim m As Integer Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click i = TextBox1.Text lblmessage.Text = i + m m = lblmessage.Text End Sub End Class このように、labelの数字がどんどん変わっていくのはできたのですが、問題は、 Text…10 Label…10    20    30    40    50    60    70    80    90    100 となり、しかも一度に出るのではなく、Buttonひと押しにつき一つの解が出ね 次の一押しで改行され解が出る。 かつ、100で打ち止めにすること…だそうです。 いちおうめちゃくちゃですが、みんな風に作りました。 Public Class Form1 Dim a As Integer Dim b As Integer Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim b As Integer = 10 a = TextBox1.Text lblMessage.Text = a & ControlChars.CrLf & a + b End Sub End Class どうかヒントだけでもお願いします。

  • VB2010で簡単なプログラムが動かないのです・・

    説明が下手なのでそのままプログラムを書きます。 ListOfficeからShowDialogでDForm1を開いています。 さらにDForm1からShowDialogでStart_Formを開いて閉じるボタンで以下の命令と実行したいのですが・・・・ ListOffice.Text = Me.TextBox1.Text →OKで動きました DForm1.Text = Me.TextBox1.Text  →NG 動きません・・・ DForm1でその他にもTextboxでやってみましたが、それでも動かないのです・・・・ 原因不明です・・・・ 以前、ほかのプログラム作成の時は動いたのですが・・・ DForm1.Text = Me.TextBox1.Textの下にMsgbox(DForm1.Text)を入れて確認してみたらMe.TextBox1.Textの文字がきちんと表示されました。 ご協力お願い致しますm(__)m Public Class Start_Form Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click DForm1.Text = Me.TextBox1.Text ListOffice.Text = Me.TextBox1.Text Me.Close() End Sub End Class

  • VBプログラム エラーが出ます

    Public Class Form1 Private number As Integer Private rows As Integer Private columns As Integer Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If Not Integer.TryParse(TextBox1.Text, rows) OrElse _ Not Integer.TryParse(TextBox2.Text, columns) OrElse _ Not Integer.TryParse(TextBox3.Text, number) Then MessageBox.Show("数字で入力してください", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If Me.Bounds = New Rectangle(10, 10, 1300, 800) Dim cnt As Integer = 0 For k As Integer = 1 To number For i As Integer = 1 To rows For j As Integer = 1 To columns Dim tb As TextBox = New TextBox() cnt += 1 tb.Name = "tb" + cnt.ToString() Me.Controls.Add(tb) tb.Top = (i - 1) * 30 + 80 tb.Left = (j - 1) * 60 + 70 * (columns * (k - 1)) + 10 tb.Width = 50 Next Next Next End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim sum As Double Dim cnt As Integer = 0 For i As Integer = 1 To rows For j As Integer = 1 To columns Dim tb As TextBox = New TextBox() cnt += 1 : If cnt > rows * columns Then cnt = 1 tb.Name = "tbA" + cnt.ToString Me.Controls.Add(tb) tb.Top = (i - 1) * 30 + (80 + 40 * rows) tb.Left = (j - 1) * 60 + 10 tb.Width = 40 sum = 0 For k As Integer = 1 To number sum += Double.Parse(CType(Me.Controls("tb" + (cnt + (rows * columns * k-1))).ToString(), TextBox).Text)    エラー Next tb.Text = sum.ToString() Next Next End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Do Until Me.Controls.Count <= 6 For Each tbD As Object In Me.Controls If CType(tbD, Control).Name Like "tb*" Then Me.Controls. Remove(tbD) Next Loop End Sub End Class エラーと書いている箇所 どう直したらよいのでしょうか。 縮小変換しないで呼び出されるアクセス可能なitemがないためオーバーロードの解決に失敗しました と出ます。 あとwindowsの画面の大きさを入力される値が小さければ少し小さいwindowsになるように変えたいのですがどうしたよいのでしょう。

  • VB初心者です。コードの書き方が分かりません。

    VB初心者です。 VBで(zのn乗)-(xのn乗+yのn乗)の計算が出来るようにしたいのですが、答えが必ず-1になってしまいます。 Option Explicit On Public Class Form1 Dim x As Long Dim y As Long Dim z As Long Dim n As Long Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Me.Close() End Sub Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged End Sub Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged End Sub Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged End Sub Private Sub TextBox4_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox4.TextChanged End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click TextBox5.Text = (z ^ n) - (x ^ n + y ^ n) End Sub End Class 正しいコードの書き方を教えて下さい。 また特定の答えのときにメッセージを表示したいのですが、どうすればいいですか?

  • vbのsavefiledialogについて

    vbで、テキストボックスに、文字を入力し、ボタン2をクリックすると、ユーザーが指定したところに、指定した名前で、txt形式、html形式、doc形式(このうち、txtと、htmlは必須。)で保存するプログラムを作りたいと思っております。 サイトを見てみますが、なかなかよいものが見つかりません。どなたか教えてください。 書きかけのプログラムと、フォーム図を載せておきます。 また、変更した方がよければ、そちらもおしえてください。 Public Class Form1 Dim texta As String Dim a Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Button1.Text = "リセット" Button2.Text = "保存" texta = TextBox1.Text End Sub Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged texta = TextBox1.Text End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click TextBox1.Text = "" End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click a = DialogResult SaveFileDialog1.OverwritePrompt = True SaveFileDialog1.FileName = "" SaveFileDialog1.Filter = "テキストファイル(*.txt)|*.txt|すべてのファイル(*.*)|*.*" a = SaveFileDialog1.ShowDialog If a = Windows.Forms.DialogResult.OK Then Label1.Text = IO.Path.GetDirectoryName(SaveFileDialog1.FileName) Label2.Text = IO.Path.GetFileName(SaveFileDialog1.FileName) Else Label1.Text = "キャンセルされました。" Label2.Text = "" End If End Sub End Class

  • VB添削

    このプログラムは 例えば3 3 4とテキストボックスに数字が打ち込まれると 3×3行列が4個分 のテキストボックスがでてきます。 ここに数字を打ち込んでいき、ボタン2を押すと3×3のテキスト トボックスが出てくると同時に足し算した結果が出てくるようにしたいです。 以下のプログラムはできたところまで作成しています。 どこを直せばよいのでしょうか。 Public Class Form1 Private number As Integer Private rows As Integer Private columns As Integer Private Sub Form11_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load For i As Integer = 1 To 3 AddHandler Me.Controls("TextBox" & i).TextChanged, AddressOf TextBox_TextChanged Next End Sub Private Sub TextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) If System.Text.RegularExpressions.Regex.IsMatch(CType(sender, TextBox).Text, "[^0-9]") Then MessageBox.Show("数字で入力してください", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error) With CType(sender, TextBox) .Text = .Text.Substring(0, .Text.Length - 1) .SelectionStart = .Text.Length End With End If Dim cnt1 As Integer Dim cnt2 As Integer Dim cnt3 As Integer If Integer.TryParse(TextBox1.Text, cnt1) And Integer.TryParse(TextBox2.Text, cnt2) And Integer.TryParse(TextBox3.Text, cnt3) Then For k = 1 To cnt3 For i = 1 To cnt1 For j = 1 To cnt2 Dim tb As TextBox = New TextBox() tb.Name = "tb" + i.ToString() Me.Controls.Add(tb) tb.Top = (i - 1) * 28 + 55 tb.Left = (j - 1) * 30 + 40 * (cnt2 * (k - 1)) + 10 tb.Width = 25 Next Next Next End If End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.Bounds = New Rectangle(10, 10, 1350, 800) Me.AutoScroll = True End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim sum As Double Dim cnt As Integer = 0 For i As Integer = 1 To rows For j As Integer = 1 To columns Dim tb As TextBox = New TextBox() cnt += 1 : If cnt > rows * columns Then cnt = 1 tb.Name = "tb" + cnt.ToString Me.Controls.Add(tb) tb.Top = (i - 1) * 30 + (80 + 40 * rows) tb.Left = (j - 1) * 60 + 10 tb.Width = 40 sum = 0 For k As Integer = 1 To number sum += Double.Parse(CType(Me.Controls("tb" + (cnt + (rows * columns * (k - 1))).ToString()), TextBox).Text) Next tb.Text = sum.ToString() Next Next End Sub Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged End Sub Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged End Sub Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged End Sub End Class

  • VBのプログラム

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If Not Integer.TryParse(TextBox1.Text, rows) OrElse _ Not Integer.TryParse(TextBox2.Text, columns) OrElse _ Not Integer.TryParse(TextBox3.Text, number) Then MessageBox.Show("数字で入力してください", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If Me.Bounds = New Rectangle(10, 10, 1300, 900) Dim cnt As Integer = 0 For k As Integer = 1 To number For i As Integer = 1 To rows For j As Integer = 1 To columns Dim tb As TextBox = New TextBox() cnt += 1 tb.Name = "tb" + cnt.ToString() Me.Controls.Add(tb) tb.Top = (i - 1) * 20 + 70 tb.Left = (j - 1) * 50 + 60 * (columns * (k - 1)) + 5 tb.Width = 55 Next Next Next End Sub これはボタンを押すと テキストボックスに入力された値分だけテキストボックスが出てくるというものです。 例えば 3 4 4とテキストボックスに値が入力された場合 3行4列が4個分テキストボックスが出てきます。 しかし6 6 6と入力した場合画面に入りきらなくなってしまいます。 大きな値を入力しても画面に入れたいです。 これはスクロールなどしてできるようにしたいです。 どのようなソースでできるのでしょうか。

  • ボタンをクリックしても空白をリストに追加しないようにしたい

    初心者ですのでよろしくお願いいたします。 以下のようなコードでボタンを押すとテキストボックスに入力してあるテキストをリストに登録したいのですが、空白の場合は追加したくありません。どのように書けばいいでしょうか? よろしくお願いいたします。 (ちなみにLabel3にはリストに登録された数が出ます) Public Class Form1 Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click End End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ListBox1.Items.Add(TextBox1.Text) TextBox1.Clear() Label3.Text = ListBox1.Items.Count End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click ListBox1.Items.Remove(ListBox1.SelectedItem) Label3.Text = ListBox1.Items.Count End Sub End Class

  • VB2008改行できません

    VB2008改行できません お願いします。 メロンパン 3個 240円 コロッケパン 2個 … という風にしたいのですが、 一行目が表示され、2行目の「コロッケパン」を入れた瞬間、 1行目が消え、 コロッケパンのみが表示されます。 なぜでしょうか。 正しいコードと、どのような理屈でそうなるのか頂けると嬉しいです。 Public Class Form1 Dim cm, a As String Dim kosu, en As Integer Private Sub ShapeComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShapeComboBox.SelectedIndexChanged cm = ShapeComboBox.Text End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click kosu = TextBox1.Text Select Case ShapeComboBox.SelectedIndex Case 0 en = kosu * 120 Case 1 en = kosu * 180 Case 2 en = kosu * 240 End Select txtKaimono.Text = cm + kosu.ToString(" ##個") + en.ToString(" #,###円") + vbCrLf End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Application.Exit() End Sub End Class

専門家に質問してみよう