Algorithm 求最小正值

Algorithm 求最小正值,algorithm,delphi,optimization,Algorithm,Delphi,Optimization,从固定数量(在本例中为3)的值中找出最小非零正值的最佳算法是什么?如果没有正面问题,则返回0 下面是我的天真方法(在Delphi中,但可以随意使用任何您喜欢的方法),但我认为还有一种更优雅的方法 value1Temp := MaxInt; value2Temp := MaxInt; value3Temp := MaxInt; if ( value1T > 0) then value1Temp := value1; if ( value2 > 0) then value2Te

从固定数量(在本例中为3)的值中找出最小非零正值的最佳算法是什么?如果没有正面问题,则返回0

下面是我的天真方法(在Delphi中,但可以随意使用任何您喜欢的方法),但我认为还有一种更优雅的方法

value1Temp := MaxInt;
value2Temp := MaxInt;
value3Temp := MaxInt;

if ( value1T > 0) then
  value1Temp := value1;
if ( value2 > 0) then
  value2Temp := value2;
if ( value3 > 0) then
  value3Temp  := value3;

Result := Min(value1Temp, Min(value2Temp, value3Temp));
if Result = MaxInt then
  Result := 0;
编辑:抱歉添加了如果没有正数所需的内容。我想我以前在那里有过它,但一定错过了。

我会做一个小循环(这是C语言,我不是Delphi的人):

int-maxPositiveValue(int*number,int-listSize)
{
int i,结果=0;
对于(i=0;i0&(数字[i]
此代码的优点是可读性很强,可以轻松地进行缩放以处理任意长度的值列表

更新:我已根据下面收到的评论更改了代码。

这段新代码稍微复杂一些,但它现在可以处理:

  • 列表不包含正整数的情况(返回0)
  • 列表包含一个或多个INT_MAX事件的情况
  • 任何长度的列表

  • 我同意亚当的观点。如果只需要容器中最小的自然数,那么从算法上讲,你不会比线性搜索更快

    他的代码应该运行得非常快,很可能会在x86中转换为CMOV,因此for循环中的if语句无论如何不会花费那么多

    如果你想要所有的非零数都按顺序排列,那么当然最好先排序,然后拼接

    Result := Min(IfThen(Value1 > 0, Value1, MAXINT), 
                  Min(IfThen(Value2 > 0, Value2, MAXINT),
                      IfThen(Value3 > 0, Value3, MAXINT)));
    
    根据问题,如果输入不是列表/数组,循环将不起作用

    如果这三个函数都不是正的和非零的,那么从这个问题上看不清楚函数应该做什么。

    • 检查列表中的值,直到找到正值为止,将“最小值”设置为该值
    • 浏览列表其余部分中的值
      • 如果0<当前值<最小值,则将最小值设置为当前值
    • 返回最小值

    无论阵列元素的类型是什么,这都有效

    template <typename T>
    T min_pos(T* a, int n)
    {
        int i /* = 0 */ /* Edit: commented this out */;
    
        // Find the first positive element in the array
        for (i = 0; i < n; ++i)
            if (a[i] > 0)
                break;
    
        // If no positive element was found, return 0
        if (i == n)
            return 0;
    
        T res = a[i];
    
        // Search the rest of the array for an element
        // that is positive yet smaller than res
        for (++i; i < n; ++i)
        {
            if ((a[i] > 0) && (a[i] < res))
                res = a[i];
        }
    
        return res;
    }
    
    模板
    T最小位置(T*a,int n)
    {
    int i/*=0*/*编辑:注释掉此*/;
    //查找数组中的第一个正元素
    对于(i=0;i0)
    打破
    //如果未找到正元素,则返回0
    如果(i==n)
    返回0;
    T res=a[i];
    //在数组的其余部分搜索元素
    //这是正的,但比res小
    对于(++i;i0)和&(a[i]
    这是C#

    public int GetSmallestPositive(IList pValues)
    {
    if(pValues==null)
    {
    抛出新ArgumentNullException(“pValues”);
    }
    int _negNumCount=0;
    int _minimate=int.MaxValue;
    for(int i=0;i//返回最小的非零正数,或null。
    //依赖最小值或最大值被视为作弊。
    公共静态int?最小非零正整数(
    int val1,int val2,int val3)
    {
    //我们不能保证3个输入中的任何一个都是正的
    int?结果=null;
    如果(值1>0)
    {
    结果=val1;
    如果(val2>0&&val20&&val30)
    {
    结果=val2;
    如果(val3>0&&val30)
    {
    结果=val3;
    }
    返回结果;
    }
    
    涵盖所有基础的c版本(我认为):

    public int GetMinimumPositiveValue(IEnumerable值)
    {
    int result=int.MaxValue;
    bool hasPositiveValue=false;
    foreach(值中的int值)
    {
    如果(值==1){返回值;}
    如果(值>0)
    {
    hasPositiveValue=true;
    如果(值<结果)
    {
    结果=值;
    }
    }
    }
    返回hasPositiveValue?结果:0;
    }
    
    这是我在仔细考虑之后想到的

    Result := 0;
    if value1 > 0 then
      Result := value1;
    if (value2 > 0) and ((Result = 0) or (value2 < Result)) then
      Result := value2;
    if (value3 > 0) and ((Result = 0) or (value3 < Result)) then
      Result := value3;
    
    结果:=0;
    如果值1>0,则
    结果:=值1;
    如果(value2>0)和((Result=0)或(value20)和((Result=0)或(value3

    当然,如果你有一个列表,更通用的算法会更好。

    对于那些试图解决C#中的一般问题的人来说,我认为代码行太多了。如果值是一个
    IEnumerable
    ,那么

    values.Select(v => (int?)v)
          .Where(v => v > 0)
          .Min() ?? 0;
    
    返回
    values
    中的最小正值,如果存在,则返回
    0
    。在这里,我利用
    Enumerable.Min(IEnumerable)这一事实如果序列为空,则
    将返回
    null
    。因此,我们过滤掉非正值,然后找到最小值。如果所有值均为非正值,则根据需要获得零,否则将找到正值的最小值。

    我会这样做:

    结果:=MaxInt;
    如果值1>0,则结果:=min(结果,值1);
    如果值2>0,则结果:=min(结果,值2);
    如果值3>0,则结果:=min(结果,值3);
    如果结果=MaxInt,则结果:=0

    如果您希望它与任意数量的问题一起循环,那么:

    结果:=MaxInt;
    对于I:=1到N do
    如果值[I]>0,则结果:=min(结果,值[I]);
    如果结果=MaxInt,则结果:=0

    如果希望值数组基于零,请将for循环更改为:0到N-1

    我认为这段代码非常清楚地说明了正在做什么

    把“then”语句放在同一个l上
    //return the smallest non-zero positive number, or null.
    //relying on Min or Max is considered cheating.
    public static int? smallestNonZeroPositiveNumberOfThree(
        int val1, int val2, int val3)
    {
        //we have no guarantee that any of the 3 inputs will be positive
        int? result = null;
        if (val1 > 0) 
        {
            result = val1; 
            if (val2 > 0 && val2 < result) { result = val2; }
            if (val3 > 0 && val3 < result) { result = val3; }
        }
        else if (val2 > 0)
        {
            result = val2; 
            if (val3 > 0 && val3 < result) { result = val3; }
        }
        else if (val3 > 0)
        {
            result = val3; 
        }
        return result;
    }
    
    public int GetMinimumPositiveValue(IEnumerable<int> values)
    {
        int result = int.MaxValue;
        bool hasPositiveValue = false;
    
        foreach (int value in values)
        {
            if(value == 1) { return value; } 
    
            if(value > 0)
            {
                hasPositiveValue = true;
    
                if(value < result)
                {
                    result = value;
                }
            }
        }
    
        return hasPositiveValue ? result : 0;
    }
    
    Result := 0;
    if value1 > 0 then
      Result := value1;
    if (value2 > 0) and ((Result = 0) or (value2 < Result)) then
      Result := value2;
    if (value3 > 0) and ((Result = 0) or (value3 < Result)) then
      Result := value3;
    
    values.Select(v => (int?)v)
          .Where(v => v > 0)
          .Min() ?? 0;
    
    int foo(int value1, int value2, int value3)
    {
        int value1Temp, value2Temp, value3Temp, tempMax;
        value1Temp = max(value1, 0);
        value2Temp = max(value2, 0);
        value3Temp = max(value3, 0);
        tempMax = value1Temp | value2Temp | value3Temp;
        if (value1Temp == 0) { value1Temp = tempMax; }
        if (value2Temp == 0) { value2Temp = tempMax; }
        if (value3Temp == 0) { value3Temp = tempMax; }
        return min(value1Temp, min(value2Temp, value3Temp));
    }
    
    int min(int x, int y)
    {
        return y + ((x - y) & -(x < y));
    }
    
    int max(int x, int y)
    {
        return x - ((x - y) & -(x < y));
    }
    
    int foo(int value1, int value2, int value3)
    {
        int value1Temp, value2Temp, value3Temp, tempMax, mask;
        value1Temp = max(value1, 0);
        value2Temp = max(value2, 0);
        value3Temp = max(value3, 0);
        tempMax = value1Temp | value2Temp | value3Temp;
        mask = -(value1Temp > 0);
        value1Temp = (value1Temp & mask) | (tempMax & ~mask);
        mask = -(value2Temp > 0);
        value2Temp = (value2Temp & mask) | (tempMax & ~mask);
        mask = -(value3Temp > 0);
        value3Temp = (value3Temp & mask) | (tempMax & ~mask);
        return min(value1Temp, min(value2Temp, value3Temp));
    }
    
    values.Min(r => r > 0 ? r : (int?)null) ?? 0
    
    function LowestPositiveInt(IntArr : array of Integer):Integer;
    var
      iX : integer;
      bValid : boolean;
    begin
      Result := MaxInt;
      bValid := False;
      for ix := 0 to High(IntArr) do
        if (IntArr[ix] > 0) then
          begin
            bValid := true;
            if (IntArr[iX] < Result) then
              Result := IntArr[ix];
          end;
      if not bValid then
        Result := 0;
    end;
    
    ShowMessage(IntToStr( LowestPositiveInt([5,2,3,-1,12]) ));
    
    Result := LowestPositiveInt( [ Value1, Value2, Value3 ] );
    
    #include <stdio.h>
    #include <limits.h>
    
    int smallest_v1(int a, int b, int c)
    {
            int min = INT_MAX;
    
            min = a>0 && a<min ? a : min;
            min = b>0 && b<min ? b : min;
            min = c>0 && c<min ? c : min;
    }
    
    // See Hacker's Delight, chapter 4.
    int smallest_v2(int a, int b, int c)
    {
            int min = INT_MAX;
    
            if ( (unsigned) a < min ) min = a;
            if ( (unsigned) b < min ) min = b;
            if ( (unsigned) c < min ) min = c;
    
            return min;
    }
    
    int main()
    {
            printf("min v1: %d\n", smallest_v1(-10, 7, 3));
            printf("min v2: %d\n", smallest_v1(-10, 7, 3));
    }
    
    1 <= i <= 10
    
    (unsigned)(i - 1) <= 9
    
    [1,2,42,-12].delete_if{|n| n <= 0 }.min || 0
    
    function cmMinInt( XX, YY, ZZ : longint ) : longint;
    begin
       result := max(0,longint(
       min(longint((XX-1) xor $80000000),
       min(longint((YY-1) xor $80000000),
       longint((ZZ-1) xor $80000000)
       )) xor $80000000)+1);
    end;
    
    function cmMinInt( XX, YY, ZZ : longint ) : longint;
    begin
       // swap ordinal coding for range MININT..0 with range 1..MAXINT
       XX := XX-1;             // move region division to between 0 and 1
       XX := XX xor $80000000; // swap regions, preserving ordering
       XX := longint(XX);      // cram back into signed 32-bit
       // similarly with YY and ZZ
       YY := longint((YY-1) xor $80000000);
       ZZ := longint((ZZ-1) xor $80000000);
       // find min of three recoded values
       result := min(XX,min(YY,ZZ));
       // swap ordering back again
       result := result xor $80000000;  // swap regions, preserving ordering
       result := result+1;              // move region division back home
       result := longint(result);       // cram back into signed 32-bit
       // if all three were neg, result at this point is neg -- clip to zero
       result := max(0,result);
    end;
    
    foo xs = let xs1 = filter (>0) xs in if null xs1 then 0 else minimum xs1
    
    foo3 x1 x2 x3 = foo [x1, x2, x3]
    
    def PosMin(*numbers):
        try:
            return min(num for num in numbers if num > 0)
        except:
            return 0
    
    return min (num for num in numbers if num > 0, sentinel=0)
    
    function MinPositive(const AIntegers: array of Integer): Integer;
    var
      LoopI: Integer;
      LFirstPositivePos: Integer;
    begin
      Result := 0;
      LFirstPositivePos := MaxInt;
      for LoopI := Low(AIntegers) to High(AIntegers) do
      begin
        if (AIntegers[LoopI] > 0) then
        begin
          Result := AIntegers[LoopI];
          LFirstPositivePos := LoopI;
          Break;
        end;
      end;
    
      for LoopI := LFirstPositivePos to High(AIntegers) do
      begin
        if (AIntegers[LoopI] > 0) and (AIntegers[LoopI] < Result) then
        begin
          Result := AIntegers[LoopI];
        end;
      end;
    end;
    
    function MinPositive3(const I1, I2, I3: Integer): Integer;
    begin
      Result := MinPositive([I1, I2, I3]);
    end;