C# 如何获取最接近我的数字的特定步骤上的值
我有一个任意的数值(float)和一个任意的步长(也是float) 我想在步长上找到最接近数值的数字,而不需要走太远的路(直到我到达为止) 例如: 步骤是5 值是1038 这一步是0-5-10-15-1035-1040- 因此,最接近的值为1040。这很容易找到,只需循环搜索我的数字之前的最后一个值,后面的第一个值,然后选择更接近的值 但这是O(n),我想要更快的东西(有时步骤非常小,值非常大,对于UI反应,这必须非常快地完成) 有没有一种方法可以只进行一次计算而不进行循环 编辑:不需要从0开始。步骤可以是负的,也可以是正的(但步骤-40将给出与步骤40完全相同的结果)。如果通过巧妙的计算而不是循环来完成,则不需要起点 英语不是我的母语。我很清楚“步骤”可能是个错误的词,但我找不到合适的词来解释。我希望我的例子能让我的问题更清楚C# 如何获取最接近我的数字的特定步骤上的值,c#,math,calculation,C#,Math,Calculation,我有一个任意的数值(float)和一个任意的步长(也是float) 我想在步长上找到最接近数值的数字,而不需要走太远的路(直到我到达为止) 例如: 步骤是5 值是1038 这一步是0-5-10-15-1035-1040- 因此,最接近的值为1040。这很容易找到,只需循环搜索我的数字之前的最后一个值,后面的第一个值,然后选择更接近的值 但这是O(n),我想要更快的东西(有时步骤非常小,值非常大,对于UI反应,这必须非常快地完成) 有没有一种方法可以只进行一次计算而不进行循环 编辑:不需要从0开始
如果有人知道如何更清楚地解释(包括更改标题),欢迎编辑。你可以用数学来解释。首先,获得
value
和step
的绝对值,然后通过从value
中减去value%step
来确定step
两侧的数字,对于较低的数字,将step
添加到较低的数字中
然后只需确定哪个数字更接近值
,并返回该值(但首先将其乘以值的符号
):
静态浮点GetClosestNumber(浮点值,浮点步长)
{
//获取参数的绝对值
var absValue=Math.Abs(值);
步骤=数学Abs(步骤);
//确定值两边的数字
var low=absValue-absValue%步长;
var高=低+阶跃;
//返回最接近的一个,如果值小于0,则乘以-1
var结果=absValue-低<高-absValue?低:高;
返回结果*数学符号(值);
}
下面是一个小测试方法和相关类:
class Item
{
public float Value { get; set; }
public float Step { get; set; }
}
static void Main()
{
var testItems = new List<Item>
{
new Item {Value = 1038, Step = 5},
new Item {Value = .8f, Step = .25f},
new Item {Value = .9f, Step = .25f},
new Item {Value = -86, Step = -45},
new Item {Value = -168, Step = -45},
new Item {Value = -168, Step = 45},
};
foreach (var testItem in testItems)
{
Console.WriteLine("The closest number to {0}\twhen stepping by {1}\tis {2}",
testItem.Value, testItem.Step, GetClosestNumber(testItem.Value, testItem.Step));
}
GetKeyFromUser("\nDone! Press any key to exit...");
}
类项目
{
公共浮点值{get;set;}
公共浮点步骤{get;set;}
}
静态void Main()
{
var testItems=新列表
{
新项{Value=1038,Step=5},
新项{Value=.8f,Step=.25f},
新项{Value=.9f,Step=.25f},
新项{Value=-86,Step=-45},
新项{Value=-168,Step=-45},
新项{Value=-168,Step=45},
};
foreach(测试项中的var测试项)
{
WriteLine(“当通过{1}\tis{2}步进时,与{0}\t最近的数字”,
testItem.Value,testItem.Step,GetClosestNumber(testItem.Value,testItem.Step));
}
GetKeyFromUser(“\n完成!按任意键退出…”);
}
输出
关于:
int step = 3;
int value = 10;
if ((value % step) == 0)
{
return value;
}
else
{
return ((value / step) + 1) * step;
}
你试过什么?共享代码除非你创建一个散列,否则你不会得到比平均N/2更好的结果。如果只执行一次,则创建哈希的时间大于N/2。如果你做了很多次,Hash只会带来改进。你没有注意到他说的值和步长值都是浮点数。我承认问题中没有明确说明这一点,但你的答案不能很好地处理负数(浮点数可以是负数)。例如,-86的步数为45将得到-45,而-90将非常接近我的测试用例中的一个,数字为-168,而步骤:45的步数为-90(实际上应该是-180)@KaitoKid哦,我看到你使用了一个正的
步数和一个负的值。我添加了一个条件,如果value
和step
没有相同的符号,则始终返回零(因为step总是从零开始,所以value
和step
必须位于0
的同一侧)。好的,我明白你的意思了。我修改了该方法以考虑到这一点,方法是使用value
和step
的绝对值来确定value
两侧的数字,然后返回与value
符号相乘的结束值……不要忘记0
int step = 3;
int value = 10;
if ((value % step) == 0)
{
return value;
}
else
{
return ((value / step) + 1) * step;
}