C# 将整数舍入到数组中最近的高位

C# 将整数舍入到数组中最近的高位,c#,arrays,C#,Arrays,我有这样一个整数数组:[32128102420484096] 给定一个特定的值,我需要得到数组中最接近的值,该值等于或大于该值 我有以下代码 private int GetNextValidSize(int size, int[] validSizes) { int returnValue = size; for (int i = 0; i < validSizes.Length; i++) { if (validSize

我有这样一个整数数组:[32128102420484096]

给定一个特定的值,我需要得到数组中最接近的值,该值等于或大于该值

我有以下代码

  private int GetNextValidSize(int size, int[] validSizes)
  {

      int returnValue = size;

      for (int i = 0; i < validSizes.Length; i++)
      {
          if (validSizes[i] >= size)
          {
              returnValue = validSizes[i];
              break;
          }
      }

      return returnValue;
  }
private int GetNextValidSize(int size,int[]validSize)
{
返回值=大小;
for(int i=0;i=大小)
{
returnValue=有效化[i];
打破
}
}
返回值;
}
这是可行的,但是有更好/更快的方法吗?数组包含的元素永远不会超过5-10个


澄清:如果原始值/大小大于任何有效大小,我实际上希望返回原始值/大小。validSizes数组可以被视为总是被排序的,并且它总是至少包含一个值。

如果您的数组被排序,您可以使用二进制搜索算法来加快排序速度


请参见此处:

如果您的数组已排序,则可以使用二进制搜索算法加快排序速度


>

鉴于你只有5-10个元素,我认为这是可以的。

< P>鉴于你只有5-10个元素,我认为这是可以的。

< P>只有5-10个元素,绝对可以用最简单的方法。让二进制切分正常工作将有助于更大的数组,但它至少有可能出现一对一的错误

但是,我不会中断,而是直接从循环返回,使其更加简单,并使用foreach:

  private int GetNextValidSize(int size, int[] validSizes)
  {    
      int returnValue = size;

      foreach (int validSize in validSizes)
      {
          if (validSize >= size)
          {
              return validSizes;
          }
      }

      // Nothing valid    
      return size;
  }
使用LINQ,您可以使这一点更加简单:

// Make sure we return "size" if none of the valid sizes are greater
return validSizes.Concat(new[] { size })
                 .First(validSize => validSize >= size);
如果没有
Concat
步骤,它会更简单。。。或者如果有一个
Concat
方法只需要一个元素。诚然,这很容易写:

public static IEnumerable<T> Concat(this IEnumerable<T> source,
                                    T tail)
{
    foreach (T element in source)
    {
        yield return element;
    }
    yield return tail;
}
或者(我意识到我提供的选项比这里真正需要的多得多!)使用默认值返回的
FirstOrDefault
重载:

public static T FirstOrDefault(this IEnumerable<T> source,
                               Func<T, bool> predicate,
                               T defaultValue)
{
    foreach (T element in source)
    {
        if (predicate(element))
        {
            return element;
        }
    }
    return defaultValue;
}

这两种方法对于单次使用来说都是多余的,但是如果您已经建立了一个额外的LINQ操作符库,那么它可能会很有用。

只有5-10个元素,一定要使用最简单的解决方案。让二进制切分正常工作将有助于更大的数组,但它至少有可能出现一对一的错误

int[] validSizes = new int[] { 32, 128, 1024, 2048, 4096 };

int sizeICareAbout = 4096;

Console.Write(validSizes.Max(i => i < sizeICareAbout ? i : Int32.MinValue));
但是,我不会中断,而是直接从循环返回,使其更加简单,并使用foreach:

  private int GetNextValidSize(int size, int[] validSizes)
  {    
      int returnValue = size;

      foreach (int validSize in validSizes)
      {
          if (validSize >= size)
          {
              return validSizes;
          }
      }

      // Nothing valid    
      return size;
  }
使用LINQ,您可以使这一点更加简单:

// Make sure we return "size" if none of the valid sizes are greater
return validSizes.Concat(new[] { size })
                 .First(validSize => validSize >= size);
如果没有
Concat
步骤,它会更简单。。。或者如果有一个
Concat
方法只需要一个元素。诚然,这很容易写:

public static IEnumerable<T> Concat(this IEnumerable<T> source,
                                    T tail)
{
    foreach (T element in source)
    {
        yield return element;
    }
    yield return tail;
}
或者(我意识到我提供的选项比这里真正需要的多得多!)使用默认值返回的
FirstOrDefault
重载:

public static T FirstOrDefault(this IEnumerable<T> source,
                               Func<T, bool> predicate,
                               T defaultValue)
{
    foreach (T element in source)
    {
        if (predicate(element))
        {
            return element;
        }
    }
    return defaultValue;
}
这两种方法对于单次使用来说都是多余的,但是如果您已经在构建一个额外的LINQ操作符库,那么它可能会很有用。

int[]validSizes=new int[]{32,128,1024,2048,4096};
int[] validSizes = new int[] { 32, 128, 1024, 2048, 4096 };

int sizeICareAbout = 4096;

Console.Write(validSizes.Max(i => i < sizeICareAbout ? i : Int32.MinValue));
int SIZECIAREABOUT=4096; Write(validSizes.Max(i=>i
如果输入最小值,则返回Int32.MinValue。上帝,我爱林克。

int[]validSizes=newint[]{32128102420484096};
int SIZECIAREABOUT=4096;
Write(validSizes.Max(i=>i

如果输入最小值,则返回Int32.MinValue。上帝,我爱LINQ。

你可以使用LINQ简化查询——如果你的列表被排序,它可能会像你能写的任何东西一样快

int someInitialValue;
int defaultIfNotFound = ... // set to some value, even initialValue
// attempt to find first value less than or equal
int bestMatch = myListOfValues.Concat( new []{defaultIfNotFound} )
                              .FirstOrDefault( x => x >= someInitialValue );
如果阵列未排序,或者需要更好的性能,请执行以下操作:

myListOfValues.OrderBy( x => x ).Concat( new []{defaultIfNotFound} )
                                .FirstOrDefault( x => x >= someInitialValue );
您提到您的列表相对较小(5-10项),所以线性搜索可能足够快。但是,在一个更大的列表(几十个或几百个项目)中,你可能要考虑找到值:

// index is positive if an exact match is found
// if no exact match is found, the index returned will be two's complement and
// reference the next number immediately larger than the search target
int index = myListOfValues.BinarySearch( someInitialValue );
if( index < 0 && ~index > myListOfValues.Length )
   bestMatch = someInitialValue;
else
   bestMatch = index < 0 ? myListOfValues[~index] : myListOfValues[index];
//如果找到精确匹配,则索引为正
//如果没有找到精确匹配,则返回的索引将是2的补码和
//引用下一个比搜索目标大的数字
int index=myListOfValues.BinarySearch(someInitialValue);
if(索引<0&&~index>mylistfvalues.Length)
bestMatch=someInitialValue;
其他的
最佳匹配=索引<0?myListOfValues[~index]:myListOfValues[index];

您可以使用LINQ来简化查询-如果对列表进行排序,它可能与您可以编写的任何查询一样快

int someInitialValue;
int defaultIfNotFound = ... // set to some value, even initialValue
// attempt to find first value less than or equal
int bestMatch = myListOfValues.Concat( new []{defaultIfNotFound} )
                              .FirstOrDefault( x => x >= someInitialValue );
如果阵列未排序,或者需要更好的性能,请执行以下操作:

myListOfValues.OrderBy( x => x ).Concat( new []{defaultIfNotFound} )
                                .FirstOrDefault( x => x >= someInitialValue );
您提到您的列表相对较小(5-10项),所以线性搜索可能足够快。但是,在一个更大的列表(几十个或几百个项目)中,你可能要考虑找到值:

// index is positive if an exact match is found
// if no exact match is found, the index returned will be two's complement and
// reference the next number immediately larger than the search target
int index = myListOfValues.BinarySearch( someInitialValue );
if( index < 0 && ~index > myListOfValues.Length )
   bestMatch = someInitialValue;
else
   bestMatch = index < 0 ? myListOfValues[~index] : myListOfValues[index];
//如果找到精确匹配,则索引为正
//如果没有找到精确匹配,则返回的索引将是2的补码和
//引用下一个比搜索目标大的数字
int index=myListOfValues.BinarySearch(someInitialValue);
if(索引<0&&~index>mylistfvalues.Length)
bestMatch=someInitialValue;
其他的
最佳匹配=索引<0?myListOfValues[~index]:myListOfValues[index];

我想你只会得到第一个较大的数字,不一定是最接近的较大的数字


如果数组未排序,则需要将其加倍传递才能找到正确的数字。首先,你会发现最大值,其次是仍然大于原始值的较小值。

我认为你只会得到第一个较大的数字,而不一定是最接近的较大的数字


如果数组未排序,则需要将其加倍传递才能找到正确的数字。首先,您将找到最大值,其次是仍然大于原始值的较小值。

它不起作用。这里有3个失败的测试用例。实际上,函数接口