主頁 > 軟體工程 > 根據與目標數相加的組合數計算整數串列的分數

根據與目標數相加的組合數計算整數串列的分數

2022-06-27 21:17:45 軟體工程

嘗試撰寫一種從數字串列中計算的方法,6這些數字的總和與該數字相加target,其余不能產生目標的數字不應考慮在內。每個號碼最多只能使用一次。

例如:

  • 如果target12并且一個數字串列是,[6, 6, 6, 6, 6, 6]那么回傳值應該是36
  • 如果我們收到一個數字串列,[1, 3, 4, 5, 6, 6]并且 atarget應該是125 1 6=12而且5 4 3=12,但是,數字只能使用一次并且不能重復使用,因此只有一個組合可以貢獻結果)。

我的代碼在線

編輯:關于這個{6, 6, 6, 6, 6, 6}例子,6 6 = 12,然后如果重復,我們也總結一下。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class MyClass {
    public static void main(String args[]) {
      ArrayList<Integer> numbers = new ArrayList<>(6);
      numbers.add(1);
      numbers.add(3);
      numbers.add(4);
      numbers.add(5);
      numbers.add(6);
      numbers.add(6);
      
      System.out.println(sumRecursively(numbers, 0, 12, new ArrayList<Integer>()));
    }
    
    private static int sumRecursively(ArrayList<Integer> numbers, int sum, int target, ArrayList<Integer> partial) {
        for(int i: partial) sum  = i;
        
        if(sum == target) { return sum; }
        else {
            for(int n = 0; n < numbers.size();   n) {
                partial.add(numbers.remove(n));
                sumRecursively(numbers, sum, target, partial);
            }
        }
        
        return sum;
    }
}

描述:數字可以從1-6, 為陣列串列中的每個單元格/索引生成任何內容six slots in space數字可以是 到 之間1的任何值6但是,主要關注的是盡可能sum達到目標。當兩個或三個 or n-pairs 已用于對匹配目標求和時,則將它們全部洗掉。看看remainders如果有的話,看看他們是否總和目標,return否則sum

此外,目標范圍是:3-123并由LOW表示。所有帶有 LOW 的東西,都被總結為 match 3

我目前的解決方案不起作用。


我現在寫了這個函式:

private static int sumRecursively(ArrayList<Integer> numbers, 
        int sum, int target, int n) {
    if(sum > target)
        sum = 0;
    if(sum == target) { return sum; }
    sum  = numbers.remove(n);
    return sumRecursively(numbers, sum, target, n);
} 

此方法適用于[1, 3, 4, 5, 6, 6]并給出12,因為將前6 的所有內容相加得到 13但是,如果都是[6,6,6,6,6,6]示例,則總和變為12因為,它不會繼續下去。


注意:如果您玩過 Yahtzee 游戲,那么您就知道了。

https://en.wikipedia.org/wiki/Yahtzee


新版本:

private static int sumRecursively(ArrayList<Integer> numbers, 
        int sum, int target, int n, ArrayList<Integer> sums) {
        
        if(sum > target)
            sum = 0;
        
        if(numbers.size() == 0) {
            sums.add(sum);
            return sums.stream().mapToInt(Integer::intValue).sum();
        }
        
        if(sum == target) { sums.add(sum); sum = 0; }
        sum  = numbers.remove(n);;
        return sumRecursively(numbers, sum, target, n, sums);
    }

類似的問題仍然存在,例如,對目標12[1,3,2,2,6,5]給出 6 例如,這里,或1 5 6 = 123 2 2 5 = 12

問題:整個問題是關于,找出從 1 到 6 的總共 6 個不同數字的串列中的數字組合,總和為目標值。如果潛在的候選者湊齊,這些候選者不能再次被重復使用。檢查余數是否有可能與目標值相加,如果沒有找到,則回傳包含所有目標值的總和串列的總和。例如,得到一個 6 x 6 的串列,目標 6 6=12, 6 6=12 6 6=12 = 那么 36 應該是總和。


這段代碼給出:

static void sum_up_recursive(ArrayList<Integer> numbers, int target, ArrayList<Integer> partial) 
    {
       int s = 0;
       for (int x: partial) s  = x;
       if (s == target) {
            System.out.println("sum(" Arrays.toString(partial.toArray()) ")=" target);
       }
       if (s >= target)
            return;
       for(int i=0;i<numbers.size();i  ) {
             ArrayList<Integer> remaining = new ArrayList<Integer>();
             int n = numbers.get(i);
             for (int j=i 1; j<numbers.size();j  ) remaining.add(numbers.get(j));
             ArrayList<Integer> partial_rec = new ArrayList<Integer>(partial);
             partial_rec.add(n);
             sum_up_recursive(remaining,target,partial_rec);
       }
    }
    
    static void sum_up(ArrayList<Integer> numbers, int target) {
        sum_up_recursive(numbers,target,new ArrayList<Integer>());
    }

用法:

Integer[] numbers = {1,3,4,5,6,6};
        sum_up(new ArrayList<Integer>(Arrays.asList(numbers)), 12);

輸出:

sum([1, 5, 6])=12
sum([1, 5, 6])=12
sum([3, 4, 5])=12
sum([6, 6])=12

問題:如何停止,一旦找到一個組合,并確保重復使用不同的數字。

uj5u.com熱心網友回復:

為了確保每個組合中的所有元素都是唯一的,我們會跟蹤已使用的索引。即每次我們找到一個總和等于目標數的組合時,我們應該禁止使用已在該組合中使用過的元素,但不能更早(因為可能有很多組合無法產生目標,并且因此,任何元素都應該有資格被使用,直到我們沒有構建一個完整的組合來給目標使用這個元素)。

為了跟蹤所采用的元素,我們需要一個在每個遞回分支中都可見的物件。并且我們已經在每次遞回呼叫時傳遞了一個數字串列,如果我們每次找到一個通過洗掉該組合中已使用的元素來生成目標數字的組合時都修改它會怎樣?如果我們在第一次組合之后走這條路,事情會變得復雜,因為我們將無法依賴索引(因為它們可以以不可預測的方式改變) 在構建單個組合時 - 確保屬于特定組合的每個元素在組合中僅使用一次至關重要。由于元素的值可能相同,我們應該使用迭代順序來正確構造每個組合,但是每次洗掉元素都會造成混亂。那么,有沒有更好的方法呢?

我們可以維護一個boolean值陣列,每個元素是這個陣列將指示特定索引處的數字是否已經屬于給定目標的組合。

我沒有將遞回方法與操作該boolean陣列的代碼混為一談,而是使用簡單且不言自明的方法將其封裝在一個類中,并sumRecursively()使用了該類的一個實體。

public class CombinationTracker {
    private boolean[] isUsed;
    
    public CombinationTracker(int size) {
        this.isUsed = new boolean[size];
    }
    
    public boolean indexIsUsed(int ind) {
        return isUsed[ind];
    }
    
    public boolean allNotUsed(List<Integer> indices) {
//            return indices.stream().noneMatch(i -> isUsed[i]); // this line does the same as the loop below
        
        boolean result = true;
        for (int idx: indices) {
            if (isUsed[idx]) {
                result = false;
                break;
            }
        }
        return result;
    }
    
    public void setIsUsed(List<Integer> indices) {
        for (int ind: indices)
            setIsUsed(ind);
    }
    
    public void setIsUsed(int ind) {
        isUsed[ind] = true;
    }
}

使用這種方法,我們能夠從尚未使用的數字構造組合,并通過在進行遞回呼叫時傳遞索引來迭代從特定位置開始的數字串列。我們可以確定,任何位于當前位置之前的元素都不會添加到當前組合中。

現在,快速回顧一下遞回

每個遞回實作都由兩部分組成:

  • 基本情況- 表示預先知道結果的邊緣情況(或一組邊緣情況)。對于這個問題,有兩種極端情況:

    • 我們已經設法找到一個給出目標數的組合,即currentSum == target,結果將等于target;

    • 到達串列的末尾(并且組合不會導致目標),結果將是(這種邊緣情況通過遞回情況下回圈0的終止條件自動解決,因此無需單獨處理)。for

  • 遞回案例- 進行遞回呼叫和主要邏輯所在的解決方案的一部分。遞回情況下,我們遍歷數字串列,并且在每個迭代步驟(如果尚未使用索引),我們根據當前元素的值(取決于我們是否超過目標進行兩次遞回呼叫與否)。一般來說,我們有兩個機會:要么取當前元素,要么忽略它。這些遞回呼叫的結果將相加并產生遞回 case的回傳值。

因為我們需要幾個額外的引數,所以創建一個輔助多載方法(將在客戶端代碼中使用)是一個好習慣,它只需要一個數字串列和一個目標值,并將實際作業委托給遞回方法。

這就是它的樣子。

public static int sumRecursively(List<Integer> numbers, int target) {
    
    return sumRecursively(new ArrayList<>(numbers),
                          new ArrayList<>(),
                          new CombinationTracker(numbers.size()),
                          0, 0, target);
}

實際遞回方法:

private static int sumRecursively(List<Integer> numbers,
                                  List<Integer> combination,
                                  CombinationTracker tracker,
                                  int currentIndex,
                                  int currentSum, int target) {
    
    if (currentSum == target && tracker.allNotUsed(combination)) { // base case - a combination has been found
        tracker.setIsUsed(combination);
        return target;
    }
    
    // recursive case
    int result = 0;
    
    for (int i = currentIndex; i < numbers.size(); i  ) {

        int next = numbers.get(i);

        if (tracker.indexIsUsed(i)) continue;
        if (currentSum   next > target) continue;
        // there are two opportunities for each number: either use next number, or ignore it
        // add next number
        if (next   currentSum <= target) {
            List<Integer> newCombination = new ArrayList<>(combination);
            newCombination.add(i);
            result  = sumRecursively(numbers, newCombination, tracker, i   1, currentSum   next, target);
        }
        // ignore next number
        result  = sumRecursively(numbers, new ArrayList<>(combination), tracker, i   1, currentSum, target);
    }
    return result;
}

main()

public static void main(String[] args) {
    System.out.println(sumRecursively(List.of(1, 3, 4, 5, 6, 6), 12));
    System.out.println(sumRecursively(List.of(6, 6, 6, 6, 6, 6), 12));
}

輸出:

12
36

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/495647.html

標籤:爪哇 列表 算法 递归 组合

上一篇:簡寫` =`是在這個程式中更新變數的唯一方法嗎?[復制]

下一篇:無法從'void'轉換為'System.Collections.Generic.Dictionary<string,bool>'

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more