发帖过于频繁的规则是10分钟内发帖达到5篇,假设以下的发帖时间,请问如何判断发帖是否过于频繁?
2020-4-25 1:00
2020-4-25 1:01
2020-4-25 1:02
2020-4-25 1:03
2020-4-25 1:05
2020-4-25 2:10
2020-4-25 2:12
2020-4-25 3:20
        C# 的一种实现
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
namespace Q127043
{
    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<DateTime> dates = new[]
            {
                DateTime.Parse("2020-4-25 1:00"),
                DateTime.Parse("2020-4-25 1:01"),
                DateTime.Parse("2020-4-25 1:02"),
                DateTime.Parse("2020-4-25 1:03"),
                DateTime.Parse("2020-4-25 1:05"),
                DateTime.Parse("2020-4-25 2:10"),
                DateTime.Parse("2020-4-25 2:12"),
                DateTime.Parse("2020-4-25 3:20")
            };
            dates = dates.OrderByDescending(d => d);
            foreach (var date in dates)
            {
                if (dates.Count(d => d > date.AddMinutes(-10) && d <= date) >= 5)
                {
                    Console.WriteLine("hit");
                    break;
                }
            }
        }
    }
}
                        没有测试,大致思路就是检查第一条和第五条之间的间隔。
只需要维护一个最大长度为4的队列,在插入第五条之前先把第一条出队与第五条比较时间,时间小于10分钟说明有五条记录
IEnumerable<DateTime> dates = new[]
{
    DateTime.Parse("2020-4-25 1:00"),
    DateTime.Parse("2020-4-25 1:01"),
    DateTime.Parse("2020-4-25 1:02"),
    DateTime.Parse("2020-4-25 1:03"),
    DateTime.Parse("2020-4-25 1:05"),
    DateTime.Parse("2020-4-25 2:10"),
    DateTime.Parse("2020-4-25 2:12"),
    DateTime.Parse("2020-4-25 3:20")
};
dates = dates.OrderBy(d => d);
var queue = new Queue<DateTime>();
foreach (var date in dates)
{
    if (queue.Count == 4 && queue.Dequeue().AddMinutes(10) > date)
    {
        Console.WriteLine("hit");
        break;
    }
    queue.Enqueue(date);
}
                        有意思 巧妙利用一个队列解决 真棒,不过你这样 所有用户都要维护一个队列 是不是 数据了就大了
@winds_随风: 首先是数据量,一个包含4个datetime的队列估计也就能占用64byte内存,100万用户也就64M内存,并不大
其次是减少占用问题,思路就是懒加载和定时清理,大致这样:
public class foo
{
    
    readonly List<Queue<DateTime>>[] RingQueue = Enumerable.Repeat(new List<Queue<DateTime>>(), 11).ToArray();
    int index = 0;
    public void Remove()
    {
        // 每分钟执行一次
        foreach (var queue in RingQueue[index])
        {
            var currentDate = DateTime.Now;
            // 尝试全部出队
            while (queue.Count > 0 && queue.Peek().AddMinutes(10) < currentDate)
            {
                queue.Dequeue();
            }
            if (queue.Count > 0)
            {
                // 10分钟之后再清理一次
                RingQueue[index + 10].Add(queue);
            }
            else
            {
                // 清理掉这个队列
            }
            // 清空
            RingQueue[index] = new List<Queue<DateTime>>();
        }
        index = (index + 1) % 11;
    }
    public void Add()
    {
        // 添加
        var newqueue = new Queue<DateTime>();
        newqueue.Enqueue(DateTime.Now);
        RingQueue[index + 10].Add(newqueue);//预计十分钟之后开始清理
    }
}
    @拓拓: 很棒 !!
       //这里默认times已经排序过的,如果不是可以先进行一次 降序
        static bool IsFrequece(IList<DateTime> times)
        {
            if (times == null || times.Count < 5)
            {
                return false;
            }
            int i = 4;  //从index=4开始检索
            while (i < times.Count)
            {
                DateTime current = times[i];
                DateTime first = times[i - 4];
                if (current - first <= TimeSpan.FromMinutes(10))
                {
                    return true;
                }
                i++;
            }
            return false;
        }
                        看样子,问主是问如何从已经有的数据里得出是否发帖过于频繁的结论。而不是在插入一条数据前判断最后4条记录是否是在过去10分钟内插入的。
var reader = new reader('data');
var queue = new queue();
while(true)
{
    var item = reader.get();
    if(queue.length < 5)
    {
         queue.in(item);
    }
    else{
          var first = queue.out();
          if(item.time - first.time < 10)
          {
                 return true;
          }
    }
    if(reader.noMore)
    {
            return false;
    }
}
                        查询用户的最后发帖时间 order by 发帖时间 limit 5,1 用这个时间和现在的时间做比较 就实现了
获取当前要发帖时间-时间长度(10),查询对应用户这个时间之后的发帖个数,判断是否允许发帖