非递归实现:从给定的字典中抽出所有相加值SUM的全部组合

例如

dic = {0 : 1,
       1 : 3,
       2 : 5,
       3 : 9,
       4 : 4}

SUM = 9

抽取组合为

  • 3:9
  • 2:5   4:4     (5+4=9)
  • 0:1   1:3   2:5     (1+3+5=9)

本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标  
  代表的数被选中,为0则没选中。    
  首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。    
  然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为  
 “01”组合,同时将其左边的所有“1”全部移动到数组的最左端。    
  当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得  
  到了最后一个组合。    
  例如求5中选3的组合:

  1   1   1   0   0   //1,2,3
  1   1   0   1   0   //1,2,4
  1   0   1   1   0   //1,3,4
  0   1   1   1   0   //2,3,4
  1   1   0   0   1   //1,2,5
  1   0   1   0   1   //1,3,5
  0   1   1   0   1   //2,3,5
  1   0   0   1   1   //1,4,5
  0   1   0   1   1   //2,4,5
  0   0   1   1   1   //3,4,5 

因此非递归实现的大致代码如下:

#coding=utf-8
#从m个数字里面抽出来n个

def sum(pos,target):
    sum = 0
    for i in range(len(pos)):
        if pos[i] == 1:
            sum += dic[i]
    if sum == target:
        return True
def leftfix(index,onecount,pos,target):
    if index >= 2 and index < len(pos)-2:
        pos[0:index] = [1]*onecount+[0]*(index-onecount)
        if sum(pos,target):
            print pos
def find(m ,n ,target):
    pos = [1]*n+[0]*(m-n)
    if sum(pos,target):
        print pos
    i = 0
    j = 0
    while True:
        if i>=len(pos)-1:break
        if pos[i] == 1:
            j += 1
            if pos[i+1] == 0:
                j -= 1
                #之前的i个数字里面有j个1 i-j个0
                pos[i], pos[i + 1] = pos[i + 1], pos[i]
                if sum(pos,target):
                    print pos
                leftfix(i,j,pos,target)
                i = -1
                j = 0
        i+=1

dic = {0 : 1,
       1 : 3,
       2 : 5,
       3 : 9,
       4 : 4}

for n in range(1,len(dic)+1):
    find(len(dic),n,9)
时间: 2024-10-21 02:25:40

非递归实现:从给定的字典中抽出所有相加值SUM的全部组合的相关文章

递归实现:从给定的字典中抽出所有相加值SUM的全部组合

递归的话,只需要考虑第一个数字的两种情况:选择或者不选择 class Dic: def __init__(self,id,values): self.id = id self.values = values def fun(dic,res,target,index): if target == 0: print res return if index == len(dic)-1: return #not choice this fun(dic,res,target,index+1) #choic

二叉树的非递归遍历(先序、中序、后序和层序遍历)

[前文] 二叉树的非递归遍历有 先序遍历.中序遍历 .后续遍历 和 层序遍历. 非递归算法实现的基本思路:使用堆栈.而层序遍历的实现:使用队列. 如下图所示的二叉树: 前序遍历顺序为:ABCDE (先访问根节点,然后先序遍历其左子树,最后先序遍历其右子树) 中序遍历顺序为:CBDAE (先中序遍历其左子树,然后访问很节点,最后中序遍历其右子树) 后续遍历顺序为:CDBEA (先后序遍历其左子树,然后后续其右子树,最后访问根节点) 层序遍历顺序为:ABECD (由上至下.从左到右遍历二叉树) [准

学习日志---非递归二叉树游标遍历(前中后层序)

实现: //二叉树类 public class MyBiTree { private MyBiTreeNode  root;//根节点 MyBiTree() { this.root = null; } MyBiTree(Object data,MyBiTree left,MyBiTree right) { MyBiTreeNode l,r; if(left==null) { l = null; } else {    l=left.root;  } if(right==null) { r = n

二叉树的非递归遍历(先序, 中序, 后序)

先序遍历: /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<int> preorderTraversal(TreeNode *root) { stack&

非递归求二叉树的前序、中序和后序遍历

一.前序遍历 分析: 1.前序遍历是中左右,因此利用栈,记录栈顶根结点的同时,先压右子树,后压左子树,从而先遍历左子树. 2.每次弹出的栈顶结点符合前序遍历的顺序,因此可直接记录. 3.注意:由于压入栈的是树的结点,所以栈内数据类型为Node*. struct Node{ int val; Node *left, *right; }; vector<int> get_preorder(Node *root){ vector<int> preorder; stack<Node*

二叉树递归与非递归遍历,最近公共父节点算法

#include <iostream> #include <stack> using namespace std; #define MAX 100 //字符串最大长度 typedef struct Node //二叉树结点 { char data; Node *lchild,*rchild; } *Btree; void createBT(Btree &t); //先序构造二叉树 void preorder(Btree &t); //二叉树递归先序遍历 void i

二叉树遍历(递归与非递归)

/*二叉树遍历(递归版本&非递归版本)(1)中序遍历(2)先序遍历(3)后续遍历*/ struct BinTree { int data; /*数据域*/ BinTree* leftchild; /*左孩子*/ BinTree* rightchild; /*右孩子*/};/*中序遍历(递归版本)*/void InOrder(BinTree* root){ if(root){ InOrder(root->leftchild); cout << root->data; InOr

非递归二叉树的遍历

我们都知道,对二叉树进行递归遍历非常简单,但递归算法需要额外的栈机制来存储每次递归的值.既然递归算法内部使用栈实现的,那么我们也可以借助于栈来实现二叉树的非递归遍历.下面我们将讲解利用非递归实现二叉树的前序.中序和后序遍历. 1.非递归二叉树前序遍历: 我们知道,二叉树的前序遍历对节点的访问顺序是根节点.左子节点然后右自节点.根据其访问顺序我们可以很容易用栈来实现.具体实现思路如下: 1.遍历根节点的左子树,将每个节点的左子节点存入栈中,并在访问遍历的节点. 2.当遇到左子节点为空时,从栈中取出

十四、python字典中的方法汇总

'''1.访问.修改,删除字典中的值:''' dict={'a':'11','b':'22','c':'33','d':'44'}print dict['a'],dict['d'] #访问dict['b']='abc' #修改print dict#删除del dict['c'] #删除字典中的某个值print dictdict.clear() #清空字典print dictdel dict #删除字典--------------------------------------------- 11