VB算法问题,一个堆数字中凑出指定数字

作者&投稿:闻行 (若有异议请与网页底部的电邮联系)
求一组数据最多可能组合的算法,VB~

这是一个组合的问题,我不会vb但会C++,我用C++编了一个,思想如下,希望对你有所帮助:定义三个数组,a,b,c,都是整形的,a中放你所说的一堆数,b和a的数组长度一样,c比a的长度大1,虽然直接选出所有组合很难,但有一个巧点的方法(来源于集合论),因为b和a数组长度一样,可以有一个对应并系:b[i]---a[i].现规定数组b中和每一个元素只能是0或1,这样,如果我们们从a中选取K个元素,就相当于b中有K个1,n-k个0.(因为b和a之间是一一对应的),如此就有如下算法能选出所有可能的组合:初始化b的所有元素为0,做一个循环,每一次对b进行"加"1,这里的"加"1是像二进制里运算一样,当b[0]=0时,加1后,b[0]变为1,当b[0]=1时,b[0]就变成o了,并且向前进一位,依些类推(就像二进制的加法:0111+1=1000一样,只不过在程序里,0,1是数组b的元素).然后判断b中是否有k个1,如果是,输出那些在b中为1对应的a中的元素(即:如果b[i]=1,则输出a[i],否则就不输出a[i],输出的就是可能的组合之一);循环的次数应该为2^n-1次(即从b中的元素为全0到b中的元素为全1),这样就能输出所有的可能的组合.至于上面提到的数组c,只是起到一个进位标志的做用,辅助完成对b进行"加"1和操作.
我的源代码如下(以从10个元素中选取5个为例)
#include
void add(int b[],int c[],int n){//对标志数组加1,参数n表示数组的长度
int i;
for(i=0;i<n+1;i++)c[i]=0;
c[0]=1;
for(i=0;i<n;i++){
if(c[i]==1){
if(b[i]==1){
b[i]=0;
c[i+1]=1;
}else b[i]=1;
}
}
}
bool is(int b[],int k){//判断此时的组合是否符合要求
int i;
int sum=0;
for(i=0;i<10;i++){
if(b[i]==1)sum++;
}
if(sum==k)return true;
else return false;
}
void putout(int a[],int b[],int n){//输出符合要求的数字
int i;
for(i=0;i<n;i++)
if(b[i]==1)cout<<a[i]<<" ";
cout<<endl;
}

void main(){
int a[10];//这里选的数是10,可以改成任意的你休处理的数n
int b[10];
int c[11];//为了确保数组不会溢出,此数组要比n大1
int i;
int j=0;
for(i=0;i<10;i++){//初始化
a[i]=i;//这里的a[i]就是你要处理的数,你可以改,只要初始化一下。
b[i]=0;
}
cout<<a[1];
for(i=0;i<1023;i++){//对于所有的情况进行筛选
add(b,c,10);// 对标志数组进行加1
if(is(b,5))//判断是否符合要求
{
putout(a,b,10);//符合要求,输出
j++;//测试用的代码,看总的输出的个数,验证一下,是不是等于C(n,k)这个组个合数
}
}
cout<<j;
}
我验证了一下,确实是正确的.组合的个数为252个,等于C(10,5).

Dim S As String

Private Sub Command1_Click()
Dim I As Integer, W As String
I = Val(Text1.Text) '取得查找的位数,由文本框中输入
W = Mid(S, I, 1) '得到第I位的数值
Label1.Caption = "第" & Str(I) & "位的值=" & W '显示第I位的数值
Label3.Caption = "这个15位数=" & S '显示这个15位数
End Sub

Private Sub Form_Load()
Dim X As Long, Y As Long
Randomize
X = Int(10000000 * Rnd + 1000000) '随机产生一个7位数
Randomize
Y = Int(100000000 * Rnd + 10000000) '随机产生一个8位数
S = LTrim(Str(X)) & LTrim(Str(Y)) '产生一个15位数的字符串
End Sub

这是个求子集合加总问题(subset sum problem)。是算法理论中比较有名的NP问题。

有几种经典解法:

1.组合论。 有所有集合元素的组合,然后求和与和目标比较。 方法简单,但算法复杂度高,当集合数较大,比如≥ 15后,速度明显慢;


2. 动态规划。递归求解,属于典型的divide and conquer方案。


3. 回溯法(backtracking),子集合属于这个里面的一个特例。 -- 虽然也要递归,但相较上面的方法,在集合比较大的时候,也能保持不错的效率。


下面给出回溯法的vb代码(vb 2010)。

  Private Sub output(ByRef ta() As Integer, ByVal ta_size As Integer)
        Dim ra(ta_size - 1) As Integer 'differ from c/c++
        Array.Copy(ta, ra, ta_size)

        Dim converter = New Converter(Of Integer, String)(Function(num) num.ToString)
        Dim str = String.Join("+", Array.ConvertAll(ra, converter))

        lbSubset.Items.Add(str)
  End Sub
  
   Private Sub getSubsetSum(ByRef sa() As Integer, ByRef ta() As Integer,
                             ByVal sa_size As Integer, ByVal ta_size As Integer,
                             ByVal sum As Integer, ByVal cnt_node As Integer, ByVal target As Integer)
        Dim i As Integer

        If target = sum Then
            output(ta, ta_size)
            If cnt_node + 1 < sa_size And sum - sa(cnt_node) + sa(cnt_node + 1) <= target Then
                getSubsetSum(sa, ta, sa_size, ta_size - 1, sum - sa(cnt_node), cnt_node + 1, target)
            End If
            Return
        Else
            If cnt_node < sa_size And sum + sa(cnt_node) <= target Then
                For i = cnt_node To sa_size - 1 ' differ from c/c++
                    ta(ta_size) = sa(i)
                    If sum + sa(i) <= target Then
                        getSubsetSum(sa, ta, sa_size, ta_size + 1, sum + sa(i), i + 1, target)
                    End If
                Next i
            End If
        End If
    End Sub
    
    Private Sub generateSubsets(ByRef sa() As Integer, ByVal size As Integer, ByVal target As Integer)
        Dim ta(size - 1) As Integer
        Dim total As Integer = 0

        Array.Sort(sa)
        total = sa.Sum

        If (sa(0) <= target) And (total >= target) Then
            getSubsetSum(sa, ta, size, 0, 0, 0, target)
        End If
    End Sub
    
     Private Sub btnStart_Click(sender As System.Object, e As System.EventArgs) Handles btnStart.Click
        Dim size As Integer = 15
        Dim target As Integer = 10
        Dim data() As Integer
        Dim i As Integer

        lbSubset.Items.Clear()

        ReDim data(size - 1) 'differ from c/c++
        For i = LBound(data) To UBound(data)
            data(i) = i + 1
        Next i

        generateSubsets(data, size, target)
    End Sub



数据20-30个,这个高效与低效,运行时间应该差不了多少吧!
我给个简单的算法:
1,将这些数据读入一个数组a()
2,对数组内的数据进行升序排序
3,依次从数组中取一个数与其他数进行求和
1)先算两个数之和100的。从a(0)开始,当a(i)>50时,即可跳出循环,开始进行三个数之和是100的计算
2)当a(i)>34时,跳出循环,进行四个数之和是100的计算
3)当a(i)>25时,跳出循环,进行五个数之和是100的计算
依次类推

将一堆数字看成一个数组,从第一个开始,遍历剩下的数,如果第一个和第n个的和=100,就输出;遍历完后,从第二个在开始,遍历剩下的,如果第二个和第n个的和=100,...............


一个算法问题
答案是:C 我们可以把一个单链表比做一群小孩子手拉手的排着队,要在一个链表中插入一个节点的话,就相当于在小孩这个队伍中间加入一个人,怎么才能做到呢,就是找到要插入的位置,把这个位置之间的两个小孩的手分开,然后让前一个小孩的手牵着新加入小孩的一只手,让新加入小孩的另一只手去牵后一...

求一个算法问题 0+0=0; 1+0=1;0+1=2;1+1=3;
就是把加数和被加数做为二进制数的高低位就行了

请教一个订单的平均分配算法问题
总数 div 人数 = 整除后的结果 a这样每人先分 a 个总数 mod 人数 = 取模后的结果 b从第一个人开始,每人一个,直到第b个人算法结果:10份分三个人 , 每人先分 10div 3 = 3个, 剩余 10mod3 = 1个,只能给一个人,这样结果 为 4,3, 32份分三个人,每人先分 2div3= 0个,剩余 ...

已知两个有序集合A和B,现要求一个新的有序集合C=A-B,求算法
C语言实现A、B两个有序集合的差集C,参考代码如下:include<stdio.h> define M 8 define N 10 int A[M]= {34,40,44,47,48,54,65,66};int B[N]= {33,34,45,48,49,51,54,56,58,65};int C[M];int main(){ int ia=0,ib=0,ic=0;int i;while(ia<M&&ib<N)if(A[ia]=...

汉诺塔问题公式是什么?
2.每次移动一块碟子,小的只能叠在大的上面 3.把所有碟子从A杆全部移到C杆上 经过研究发现,汉诺塔的破解很简单,就是按照移动规则向一个方向移动金片:如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C 此外,汉诺塔问题也是程序设计中的经典递归问题。补充:汉诺塔的算法实现(c++...

请设计一个算法,找出a、b、c、d四个互不相同的数中的最小值
一。先假设最小值为a,即min = a;二。拿b和min比较,如果b小于min,则min=b;三。拿c和min比较,如果c小于min,则min=c;四。拿d和min比较,如果d小于min,则min=d;五。输出min。

设计一个算法代码 ,解字谜ABCAB*A=DDDDDD
include <stdio.h> int main(){ int a, b, c, dddddd;for(a=1; a<=9; a++)for(b=0; b<=9; b++)for(c=0; c<=9; c++){ dddddd = (a*10000 + b*1000 + c*100 + a*10 + b) * a;if(dddddd % 111111 == 0)printf(" %d%d%d X %d = %d\\n", a,b,c,a,...

在一个流程图中画出算法:输入两个数a,b求出它们的和,积,平方和,和的平...
在一个流程图中画出算法:输入两个数a,b求出它们的和,积,平方和,和的平方(在一个算法完成)  我来答 1个回答 #热议# 该不该让孩子很早学习人情世故?Cool_hot_like 2014-10-21 · TA获得超过3.9万个赞 知道大有可为答主 回答量:3.5万 采纳率:85% 帮助的人:3485万 我也去答题访问个人...

看我右下角的两种算法,一个是用的E=BLV,一个用的E=BS\/T,为什么算出来的...
第一个公式B基本不变。问题说B的变化率与时间变化率成比例关系。。当然用第二个呀。再说第一个公式要求V恒定或者瞬时

0-1背包问题的多种解法代码(动态规划、贪心法、回溯法、分支限界法)
for (int i=0; i<n+1; i++) { ppm[i] = new int[c+1]; } int x[6]; Knapsack<int>(v, w, c, n, ppm); TraceBack<int>(ppm, w, c, n, x); return 0; } 二.贪心算法求解0-1背包问题 1.贪心法的基本思路: ——从问题的某一个初始解出发逐步逼近给定的目标,以尽可能...

邢台县18293659346: VB,将若干个数插入到一个数组中的指定位置 -
董唐清开: 说一下思路: 1、定义数组时建议定义成动态数组(DIM PRESERVE); 2、输入一个数,数组动态增加1个; 3、比如在第3位插入4个数,则先将数组增加4,再从增加前的益一个一个移动到后面去(空出前面要插入的地方); 4、再将插入的数据赋给相应数组.

邢台县18293659346: 如何将几个数字进行搭配相加,得出指定区间的组合(求算法或代码,javascript/VB/C#均可) -
董唐清开: k4me的算法基本上已经是最简单的了,比我想的优化了10多倍,我按照他的算法把自己代码整理了一下,贴出来大家指正var RANGE_MAX = 55; var RANGE_MIN = 50; function sumArr(arr){ var sum = 0; for(var i=0;i<arr.length;i++){ sum+=arr[i]; } ...

邢台县18293659346: 求一组数据最多可能组合的算法,VB -
董唐清开: '没有使用任何算法, 直接排序输出.Dim StrOut() As String Private Sub Command1_Click() Dim Num() As Variant Dim GroupMax As Long Dim i As Long, j As Long, l As Long, m As Long, n As Long Dim lngTemp() As Long Dim TT As Long ...

邢台县18293659346: 如何用VB从指定的数里生成出个随机数 -
董唐清开: 第一个问题:你可以先这几个数放丰一个数组中,然后随机生成一个下标,不就行了.第二个问题:你在窗体上画两个按钮Command1、Command2、一个Timer控件Timer1、一个标签Label1.Timer1的Enabled属性设为False,Interval...

邢台县18293659346: VB 组合算法 -
董唐清开: Dim str(6), str1(15), str2(500), str3(20) As String Dim i, j, k, m, n, sc, st(6), num(15) As Integer Dim sn As Boolean For i = 1 To 6 str(i) = CStr(i) Next '算法 '6个数字组合不同的两位数 m = 1 For i = 1 To 6 For j = 1 To 6 If j > i Then str1(m) = str(i) + str(j) ...

邢台县18293659346: 如何用VB求组合的算法 -
董唐清开: Option Explicit Sub GetList(ByRef DataArray() As Integer, ByRef List() As Integer, ByVal Pos As Integer) Dim L As Integer, H As Integer, LL As Integer, HH As Integer Dim D() As Integer Dim i As Integer Dim j As Integer L = LBound(DataArray) H = ...

邢台县18293659346: 输入一个3位数,输出由这3位数重新组成的最大3位数 vb算法 -
董唐清开: Private Sub Command1_Click() x = CInt(InputBox("请输入一个三位数")) a = x \ 100 b = x \ 10 Mod 10 c = x Mod 10 If a If a If b MsgBox ("您输入的数是" & x & vbCrLf & "由这3位数重新组成的最大3位数是:" & 100 * a + 10 * b + c) End Sub

邢台县18293659346: VB中如何提取数据中指定的一段 -
董唐清开: 一行一行的读 读到W0了 开始记录 然后再继续一行行的读啊 读到L0就结束...Dim tmpString As String Open "c:\123.txt" For Input As #1 Do Until EOF(1) Line Input #1, tmpString If UCase(tmpString) = "W0" Then Do Line Input #1, tmpString If UCase(tmpString) = "L0" Then Exit Do MsgBox tmpString Loop End If Loop Close #1

邢台县18293659346: 请VB编程求解:用1 - 8八个数字不重复使用,组成两个四位数,其中一个是另一个的四倍计算结果在文本框中显示出来.请问怎么用VB编程写算法?最好提供... -
董唐清开:[答案] 已通过测试,结果有两组满意请及时采纳,谢谢 Private Sub Command1_Click()Text1 = ""Dim num(8) As IntegerFor i = 1 To 8 For j = 1 To 8 If i j Then For k = 1 To 8 If k i And k j Then ...

邢台县18293659346: vb 挑数字算法 -
董唐清开: 取数很简单先定义三个变量为整型a=val(Text1.text) mod 10 取个位b=val(Text1.text) / 10 mod 10 取十位c= val(Text1.text) / 100 取百位然后又加判断判断奇偶数例如判断个位:if a mod 2 =1 thenprint("这是奇数")elseprin("这是偶数")end if用求余,因为 变量 mod 2 ,得出的结果只有 1 和 0 ,等于 1 的话就是奇数,等于0的话就是偶数.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网