首页 新闻 搜索 专区 学院

判断发帖是否过于频繁的算法问题

0
悬赏园豆:100 [待解决问题]

发帖过于频繁的规则是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
dudu的主页 dudu | 高人七级 | 园豆:38829
提问于:2020-04-25 15:28
< >
分享
所有回答(6)
0

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;
                }
            }

        }
    }
}
dudu | 园豆:38829 (高人七级) | 2020-04-25 16:36
0

没有测试,大致思路就是检查第一条和第五条之间的间隔。
只需要维护一个最大长度为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);
}
拓拓 | 园豆:590 (小虾三级) | 2020-04-26 10:07

有意思 巧妙利用一个队列解决 真棒,不过你这样 所有用户都要维护一个队列 是不是 数据了就大了

支持(0) 反对(0) winds_随风 | 园豆:87 (初学一级) | 2020-04-26 16:13

@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);//预计十分钟之后开始清理
    }
}
支持(1) 反对(0) 拓拓 | 园豆:590 (小虾三级) | 2020-04-26 19:49

@拓拓: 很棒 !!

支持(0) 反对(0) winds_随风 | 园豆:87 (初学一级) | 2020-04-29 11:43
0
       //这里默认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;
        }
gt1987 | 园豆:650 (小虾三级) | 2020-04-26 10:15
0

看样子,问主是问如何从已经有的数据里得出是否发帖过于频繁的结论。而不是在插入一条数据前判断最后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;
    }
}
会长 | 园豆:9130 (大侠五级) | 2020-04-26 12:01
0

查询用户的最后发帖时间 order by 发帖时间 limit 5,1 用这个时间和现在的时间做比较 就实现了

开窍 | 园豆:150 (初学一级) | 2020-05-12 03:15
0

获取当前要发帖时间-时间长度(10),查询对应用户这个时间之后的发帖个数,判断是否允许发帖

wwr01 | 园豆:637 (小虾三级) | 2020-10-14 11:17
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册