Java版最优组合算法转换成Delphi版本

CSDN曾卫大牛的Java代码(https://blog.csdn.net/u014344668/article/details/109491754),正好有个需求用到(开有额度限制的发票,尽可能的张数最少),请求帮忙转为Delphi,谢谢。

需求:
1.目标数组 {10,6,5,3,10,2,1,1,6,1,1}
2.要求组合之和不能大于10,且组合最小

CSDN曾卫大牛的Java代码(https://blog.csdn.net/u014344668/article/details/109491754),正好有个需求用到(开有额度限制的发票,尽可能的张数最少),请求帮忙转为Delphi,谢谢。

需求:
1.目标数组 {10,6,5,3,10,2,1,1,6,1,1}
2.要求组合之和不能大于10,且组合最小

算法实现
/**
 * @Description: 最优组合算法
 * @Author zengwei
 * @Date 2020-11-03-18:32
 **/
public class TheBestCombineAlgorithm {
    public static void main(String[] args){
        int[] arr = {10,6,5,3,10,2,1,1,6,1,1};
        int max = 10;

        int[][] end = getArray(arr,max);
        for (int[] ints : end) {
          if (ints != null) {
          System.out.println(Arrays.toString(ints));
          }
        }
    }

    private static int[][] getArray(int[] arr, int max) {
        List<Integer> recordIndex = new ArrayList<>();//记录使用过的元素的索引位置
        int[][] finalArray = new int[arr.length][];
        //1.从左到右遍历所有元素
        int arrIndex = 0;//记录二维数组的位置
        for (int i=0;i<arr.length;i++){//每循环一次,位置往后移动一次
          int currentElement = arr[i];
          if(recordIndex.contains(i)){
          continue;//如果当前位置被使用了,跳过本次循环,进入下次循环
          }
          //判断当前元素是否已经大于后者等于10
          if(currentElement >= max){
          finalArray[arrIndex] = new int[]{currentElement};
          //同时将当前索引位置存入到list中
          recordIndex.add(i);
          }else{
          List<Integer> element = new ArrayList<>();
          element.add(currentElement);
          while(currentElement <max){
          //2.除了当前元素外,查找最小元素
          int searchMinIndex = bubble(i,arr,recordIndex);
          if(searchMinIndex == -1){
          break;
          }
          currentElement += arr[searchMinIndex];
          if(currentElement > max){
          break;//因为如果相加大于10,说明不需要这个值了
          }
          //3.拼接到新的int数组中
          element.add(arr[searchMinIndex]);
          //4.将当前索引位置存入recordIndex中
          recordIndex.add(searchMinIndex);
          }
          //JDK1.8特性 将List对象转为int[]数组
          finalArray[arrIndex] = element.stream().mapToInt(j -> j).toArray();
          }
          arrIndex ++;
        }
        //4.存入到新的二维数组中
        return finalArray;
    }

    /**
     * 冒泡比较,查找最小元素位置
     * @param i 查找开始位置
     * @param arr 目标数组
     * @param recordIndex 存储已经被使用的元素
     * @return 返回最小元素索引位置
     */
    private static int bubble(int i, int[] arr, List<Integer> recordIndex) {
        int min = arr[i];//记录最小元素的值
        int index = -1;//记录最小元素位置
        for (;i<arr.length;i++){
          if(recordIndex.contains(i)){
          continue;
          }
          if(min > arr[i]){//每次都和最小值比较
          min = arr[i];
          index = i;
          }
        }
        return index;
    }
}

输出结果
[10]
[6, 1, 1, 1, 1]
[5, 2, 3]
[10]
[6]

郑重感谢:以下Delphi版算法来自Delphi盒子用户:devil10086 (testabc) 。感谢devil10086 (testabc)为Delphi社区做出的贡献。欢迎加入Delphi开发局QQ群:32422310  Delphi控件源码下载网站  

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    Button2: TButton;
    Memo3: TMemo;
    Button3: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

uses
  System.Generics.Collections;

type
  TArrayEx = array of array of Integer;

const
  arrInput: TArray<Integer> = [10,6,5,3,10,2,1,1,6,1,1];
  Max = 20;

/// <summary>
///  * 冒泡比较,查找最小元素位置
///* @param i 查找开始位置
///* @param arr 目标数组
///* @param recordIndex 存储已经被使用的元素
///* @return 返回最小元素索引位置
/// </summary>
function bubble(i: Integer; inArr: TArray<Integer>; recordIndex: TList<Integer>): Integer;
var
  min, index, iTemp: Integer;
begin
  min := inArr[i];//记录最小元素的值
  index := -1;//记录最小元素位置
  for iTemp := 0 to Pred(Length(inArr)) do
  begin
    if(recordIndex.contains(iTemp)) then
    continue;
    if(min > = inArr[iTemp]) then//每次都和最小值比较
    begin
      min := inArr[iTemp];
      index := iTemp;
    end;
  end;
  Result := index;
end;

function getArray(arr: TArray<Integer>; max: Integer): TArrayEx;
var
  recordIndex, element: TList<Integer>;
  finalArray: TArrayEx;
  arrIndex: Integer; //记录二维数组的位置
  i,j, currentElement, searchMinIndex: Integer;
begin
  recordIndex := TList<Integer>.Create;
  SetLength(finalArray,Length(arr), Length(arr));
  //1.从左到右遍历所有元素
  arrIndex := 0;
  for i := 0 to Pred(Length(arr)) do
  begin
    currentElement := arr[i];
    if recordIndex.Contains(i) then
      Continue;   //如果当前位置被使用了,跳过本次循环,进入下次循环

    //判断当前元素是否已经大于后者等于10
    if(currentElement >= max) then
    begin
      finalArray[arrIndex] := [currentElement];
      //同时将当前索引位置存入到list中
      recordIndex.add(i);

    end
    else
    begin
      element := TList<Integer>.Create;
      element.add(currentElement);

      while(currentElement < max) do
      begin
        //2.除了当前元素外,查找最小元素
        searchMinIndex := bubble(i,arr,recordIndex);
        if(searchMinIndex = -1) then
          Break;
        currentElement := currentElement + arr[searchMinIndex];

        if(currentElement > max) then
          Break;  //因为如果相加大于10,说明不需要这个值了

        //3.拼接到新的int数组中
        element.add(arr[searchMinIndex]);

        //4.将当前索引位置存入recordIndex中
        recordIndex.add(searchMinIndex);
      end;

      //将List对象放入数组
      for j := 0 to element.Count-1 do
        finalArray[arrIndex, j] := element.Items[j];
    end;
    inc(arrIndex);
  end;
  Result := finalArray;
end;

procedure TForm2.Button1Click(Sender: TObject);

  procedure p_test(AMax: integer ; mmo: TMemo);
  var
    outPut: TArrayEx;
    i, j: Integer;
    s: string;
  begin
//  output := getArray(arrInput,Max);
    output := getArray(arrInput,AMax);
    mmo.Lines.Clear;
    for i:= Low(outPut) to High(outPut) do
    begin
      s := '';
        for j := Low(outPut[i]) to High(outPut[i]) do
        if outPut[i, j] > 0 then
          s := s + ' ' + IntToStr(outPut[i, j]);
      if s<>'' then
       mmo.Lines.Add(s);
    end;
  end;

begin
       if sender=Button1 then p_test(10,memo1)
  else if sender=Button2 then p_test(15,memo2)
  else if sender=Button3 then p_test(20,memo3)
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  Button1Click(Button1);
  Button1Click(Button2);
  Button1Click(Button3);
end;


end.

窗体代码:

object Form2: TForm2
  Left = 0
  Top = 0
  Caption = 'Form2'
  ClientHeight = 236
  ClientWidth = 686
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 8
    Top = 8
    Width = 181
    Height = 13
    Caption = #30446#26631#25968#32452': [10,6,5,3,10,2,1,1,6,1,1]'
  end
  object Button1: TButton
    Left = 8
    Top = 33
    Width = 220
    Height = 25
    Caption = #35201#27714#32452#21512#20043#21644#19981#33021#22823#20110'10'#65292#19988#32452#21512#26368#23567
    TabOrder = 0
    OnClick = Button1Click
  end
  object Memo1: TMemo
    Left = 8
    Top = 64
    Width = 220
    Height = 153
    Lines.Strings = (
      'Memo1')
    TabOrder = 1
  end
  object Memo2: TMemo
    Left = 234
    Top = 64
    Width = 220
    Height = 153
    Lines.Strings = (
      'Memo1')
    TabOrder = 2
  end
  object Button2: TButton
    Left = 234
    Top = 33
    Width = 220
    Height = 25
    Caption = #35201#27714#32452#21512#20043#21644#19981#33021#22823#20110'15'#65292#19988#32452#21512#26368#23567
    TabOrder = 3
    OnClick = Button1Click
  end
  object Memo3: TMemo
    Left = 458
    Top = 64
    Width = 220
    Height = 153
    Lines.Strings = (
      'Memo1')
    TabOrder = 4
  end
  object Button3: TButton
    Left = 458
    Top = 33
    Width = 220
    Height = 25
    Caption = #35201#27714#32452#21512#20043#21644#19981#33021#22823#20110'20'#65292#19988#32452#21512#26368#23567
    TabOrder = 5
    OnClick = Button1Click
  end
end

 效果:

Delphi版本最优组合算法

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值