代码之家  ›  专栏  ›  技术社区  ›  Manjunath apardoe

如何从递归代码中删除重复项?许多6面骰子将被卷起,并且只打印一些独特的组合,这些组合加起来就达到了所需的总和。

c++
  •  0
  • Manjunath apardoe  · 技术社区  · 8 年前

    在下面的代码中,我可以打印出所有的骰子组合,它们加起来就是所需的和。我想在修改代码以删除重复条目方面获得一些帮助。

    void rep(int n, string ans, int currentSum, int targetSum)
    {
        if(n==0)
        {
            if(currentSum==targetSum)
                cout << "{" << ans << "}"<<endl;
        }
        else
        {
            for(int i=1 ; i<=6 ; i++)
            {
                if(n>1)
                {
                      rep(n-1, ans + to_string(i) + ", ", currentSum+i, targetSum);
                }
                else
                {
                    rep(n-1, ans + to_string(i), currentSum+i, targetSum);
                }
            }
        }
    }
    
    
    void ManyDiceSum(int howManyDice, int targetSum)
    {
        if(howManyDice>0)
            rep(howManyDice,"",0,targetSum);
    }
    
    int main()
    {
        int howManyDice, targetSum;
    
        howManyDice=3;
        targetSum=7;
    
        ManyDiceSum(howManyDice, targetSum);
    
        return 0;
    }
    

    3个骰子和7个目标和的输出应该是:

    {1, 1, 5}
    {1, 2, 4}
    {1, 3, 3}
    {2, 2, 3}
    

    但是,我的代码显示了所有组合:

    {1, 1, 5}
    {1, 2, 4}
    {1, 3, 3}
    {1, 4, 2}
    {1, 5, 1}
    {2, 1, 4}
    {2, 2, 3}
    {2, 3, 2}
    {2, 4, 1}
    {3, 1, 3}
    {3, 2, 2}
    {3, 3, 1}
    {4, 1, 2}
    {4, 2, 1}
    {5, 1, 1}
    

    约束条件包括: 它必须使用递归 和使用 只有一个循环 如果 必要的。

    2 回复  |  直到 8 年前
        1
  •  0
  •   Daniel Langr    8 年前

    基于@jarod42评论的示例性解决方案:

    void rep(int n, std::string ans, int currentSum, int TargetSum, int startFrom) {
       if (n == 0) {
          if (currentSum == TargetSum)
             std::cout << "{" << ans << "}" << std::endl;
       } else 
          for (int i = startFrom; i <= 6; i++) 
             if (n > 1)
                rep(n-1, ans + to_string(i) + ", ", currentSum + i, TargetSum, i);
             else
                rep(n-1, ans + to_string(i), currentSum + i, TargetSum, i);
    }
    
    void ManyDiceSum(int howManyDice, int TargetSum) {
       if (howManyDice > 0)
          rep(howManyDice, "", 0, TargetSum, 1);
    }  
    
        2
  •  1
  •   Slava    8 年前

    首先,您不需要将目标和当前总和都传递给函数,只有目标是足够的,首先检查它将显著加快整个过程:

    void rep( int n, int target, std::string ans = std::string(), int last = 1 )
    {
        if( n == 0 ) {
            if( target == 0 )
                std::cout << "{" << ans << "}" << std::endl;
            return;
        }
        const auto limit = std::min( 6, target );
        // or even following, but not sure this is quite right though
        //const auto limit = std::min( 6, target - n * last ); 
        for( int i = last ; i <= limit; ++i ) 
            rep(n-1, target - i, ans + to_string(i) + ( n > 1 ? ", " : "" ), i );
    }
    
    void ManyDiceSum( int howManyDice, int TargetSum ) 
    {
       if (howManyDice > 0)
          rep( howManyDice, TargetSum );
    }  
    

    为了避免重复,请从上次启动的号码继续。