找到最小索引的最有效方法,其中它的值减去前一个索引的值小于给定的x?

时间:2015-05-16 13:08:40

标签: c# arrays sorting data-structures

我有五个长整数p,q,s,m和x。数组[]由以下公式创建。

Dim This_Year As Integer
Dim Last_Year As Integer

Private Sub Workbook_Open()
    This_Year = Year(Date)
    Last_Year = This_Year - 1
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    If Intersect(Target, [A:A]) Is Nothing Then Exit Sub
    If IsDate(Target) And Year(Target) = This_Year Then
        Application.EnableEvents = False
        Target.Value = DateSerial(Last_Year, Month(Target), Day(Target))
        Application.EnableEvents = True
    End If
End Sub

数字的第一个值(数字[0])是s。

numbers[0] = s; for(int i=1; i<numbers.Length;i++){ numbers[i] = (p * numbers[i-1] + q) % m; } i < j|numbers[j] - numbers[i]| <= x找到索引j的最有效方法是什么。

例如,在p = 3,q = 7,s = 1,m = 29 en x = 1的情况下,阵列将是:

数字[0] = 1,数字[1] = 10,数字[2] = 8,数字[3] = 2.

在这种情况下,索引j将是3,因为|numbers[j] - numbers[i]| >= m-x,因为x是1.

我考虑使用诸如计数排序或基数排序的变体之类的东西,但是我无法使用任何东西。

3 个答案:

答案 0 :(得分:0)

因为我&lt; j,那么你需要授予这些数字的长度至少为2。

你可以做两个嵌套循环,外部循环从j = 1到数字.Length - 1(将可能的解决方案赋予最小的j)到i = 0到i&lt;学家

然后根据您的规格比较两个位置。如果为true,则返回j。如果它完成两个循环,则没有解决方案。

编辑:代码示例

public int GetSmallestIndex(long[] numbers, long x, long m)
{
    if (numbers.Length >= 2)
    {
        for (int j = 1; j < numbers.Length; j++)
        {
            for (int i = 0; i < j; i++)
            {
                long diff = Math.Abs(numbers[j] - numbers[i]); 
                if (diff <= x || diff >= m - x)
                    return j;
            }
        }
    }

    return -1; //If no solution is found, return -1 as convention
}

答案 1 :(得分:0)

了解某些内容是否更有效的唯一方法是使用StopWatch中的System.Diagnostics对其进行基准测试。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        public static void Main()
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();
            const long x = 1;
            var numbers = new long[] {3, 7, 1, 29};
            var theSmallestIndex = SmallestIndex(x, numbers);
            stopWatch.Stop();
            Console.WriteLine("Elapsed Time: {0}", stopWatch.Elapsed);
            Console.WriteLine("Smallest Index: {0}", theSmallestIndex);
            Console.ReadKey();
        }

        public static long SmallestIndex(long x, long[] numbers)
        {
            var values = ValuesMinusTheValueOfPreviousIndex(x, numbers.ToList());
            var smallest = values.Values.OrderBy(n => n).FirstOrDefault();
            var result = values.Where(n => n.Value.Equals(smallest));
            return result.FirstOrDefault().Key;
        }

        public static Dictionary<int, long> ValuesMinusTheValueOfPreviousIndex(long x, List<long> numbers)
        {
            var results = new Dictionary<int, long>();
            foreach (var number in numbers)
            {
                var index = numbers.IndexOf(number);
                var previousNumber = index > 0 ? numbers.ElementAt(index - 1) : 0;
                var result = number - previousNumber;
                results.Add(index, result);
            }

            return results;
        }
    }
}

答案 2 :(得分:0)

编辑:根据您在评论中的要求添加了Math.Abs​​

        long p = 3, q = 7, s = 1, m = 29, x = 1;
        long[] numbers = new long[10];

        numbers[0] = s;
        for (int i = 1; i < numbers.Length; i++)
        {
            numbers[i] = (p * numbers[i - 1] + q) % m;
        }

        // Find the smallest index j in numbers, where i < j && 
        //    (numbers[j] - numbers[i] <= x    ||     numbers[j] - numbers[i] >= m-x)
        int smallestIndex = 0;
        long comparison;
        for (int j = 1; j < numbers.Length; j++)
        {
            for (int i = 0; i < j; i++)
            {
                comparison = Math.Abs(numbers[j] - numbers[i]);
                if (comparison <= x || comparison >= m - x)
                {
                    smallestIndex = j;
                    break;
                }
            }
            if (smallestIndex != 0) break;
        }

        if (smallestIndex == 0)
        {
            // No result matches the conditions
        }
        else
        {
            // j is the smallest index matching the conditions
            // Before using Abs, in the example j is 2, because 8 - 10 = -2, lesser than x
            // Now using absolute values, In the example j is 3
        }