Algorithm 求最小正值
从固定数量(在本例中为3)的值中找出最小非零正值的最佳算法是什么?如果没有正面问题,则返回0 下面是我的天真方法(在Delphi中,但可以随意使用任何您喜欢的方法),但我认为还有一种更优雅的方法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
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]
此代码的优点是可读性很强,可以轻松地进行缩放以处理任意长度的值列表
更新:我已根据下面收到的评论更改了代码。
这段新代码稍微复杂一些,但它现在可以处理:
我同意亚当的观点。如果只需要容器中最小的自然数,那么从算法上讲,你不会比线性搜索更快 他的代码应该运行得非常快,很可能会在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;