发帖过于频繁的规则是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),查询对应用户这个时间之后的发帖个数,判断是否允许发帖