5

假设您有一个对象列表。用户在工作时主要使用所有对象。您如何对对象列表进行排序,以使列表适应用户最常使用的顺序?您可以为此使用什么算法?

编辑:许多答案建议计算使用对象的次数。这不起作用,因为所有对象的使用量都相同,只是顺序不同。

4

10 回答 10

2

在您的对象内部,保留一个 usedCount。每当使用对象时,增加此计数。然后你可以简单地这样做:

objects.OrderByDescending(o => o.UsedCount);
于 2012-06-28T12:59:22.373 回答
1

我会不断统计该对象被使用的次数,以及使用的顺序。

因此,如果对象 X 被第三次使用,则将其与运行计数进行平均,并将结果用作它在列表中的位置。

例如:

项目使用使用顺序
--------------------------------------
对象 X 10 1,2,3,1,2,1,3,1,2,2 (18)
对象 Y 10 3,1,2,3,3,3,1,3,3,1 (23)
对象 Z 10 2,3,1,2,1,2,2,2,2,3 (20)

使用将是用户使用该对象的次数,使用顺序将是该项目在该顺序中的使用位置的列表(或总和)。

单独使用每个订单的列表可能会出现一些性能问题,因此您可能只想保留头寸的总和。如果您保留一个总和,只需在每次使用对象时将顺序添加到该总和。

要计算位置,您只需使用位置的总和除以使用次数即可得到平均值。那时您所要做的就是按平均值对列表进行排序。

在上面的示例中,您将获得以下平均值(和顺序):

对象 X 1.8
对象 Z 2.0
对象 Y 2.3
于 2012-06-28T13:54:20.120 回答
0

您可以将 number_of_views 字段添加到您的对象类,每次使用对象时 ++ 它并按该字段对列表进行排序。当所有对象的 number_of_views 相同但不为 0 时,您应该为所有对象设置此字段 = 0。

于 2012-06-28T13:00:13.617 回答
0

来自https://stackoverflow.com/a/2619065/1429439

可能使用 OrderedMultiDictionary,其中 usedCount 作为键,对象作为值。

于 2012-06-28T13:38:51.073 回答
0

我还会为每个对象使用一个计数器来监视它的使用,但不是在每次使用后重新排序整个列表,我建议只对列表进行“本地”排序。就像在冒泡排序中一样,我只会将计数器刚刚增加的对象与上面的对象进行比较,并在需要时交换它们。如果交换,我会比较该对象和它的新上层对象,依此类推。

但是,如果正确实现了排序,它与以前的方法并没有太大的不同。

于 2012-06-28T13:03:12.740 回答
0

当用户与对象交互时,保存对第二个对象执行的前一个对象的 ID,以便您始终拥有指向在任何给定对象之前使用的对象的指针。

此外,存储最常用的第一个对象的 ID,以便您知道从哪里开始。

当您构建要显示的对象列表时,您从存储为最常用的第一次使用的对象开始,然后搜索存储了第一次使用的对象 ID 的对象以在下一个显示。

于 2012-09-12T16:25:26.223 回答
0

编辑:添加了订单偏好!!!看代码

我不喜欢 Carra 所说的 Last used 方法,因为它会造成许多令人困惑的排序变化。

count_accessed 字段要好得多,尽管我认为应该将其调整为
用户在过去 XX 分钟/小时/天等内访问该项目的次数等...

最好的数据结构肯定是

    static TimeSpan TIME_TO_LIVE;
    static int userOrderFactor = 0;

    LinkedList<KeyValuePair<DateTime, int>> myAccessList = new     LinkedList<KeyValuePair<DateTime, int>>();

    private void Access_Detected()
    {
        userOrderFactor++;
        myAccessList.AddLast(new KeyValuePair<DateTime, int>(DateTime.Now, userOrderFactor));
        myPriority += userOrderFactor; // take total count differential, so we dont waste time summing the list
    }



    private int myPriority = 0;
    public int MyPriority
    {
        get
        {
            DateTime expiry = DateTime.Now.Subtract(TIME_TO_LIVE);
            while (myAccessList.First.Value.Key < expiry)
            {
                myPriority += myAccessList.First.Value.Value; // take care of the Total Count 
                myAccessList.RemoveFirst();
            }
            return myPriority;
        }
    }

希望这会有所帮助......它几乎总是 O(1) BTW......
让我想起了操作系统的睡眠机制

于 2012-06-28T13:12:43.050 回答
0

如果您的 User 类看起来像这样:

class User  
{  
    Collection<Algo> algosUsed = new List<Algo>();     //Won't compile, used for explanation
    ...
}  

你的算法类看起来像这样:

class Algo  
{  
    int usedCount;  
...  
}  

您应该能够将Algo对象的特定实例绑定到User允许记录使用频率的对象。在最基本的层面上,您会将信息序列化为文件或流。您很可能想要一个数据库来跟踪正在使用的内容。然后,当你抓住你的User并调用一个sort函数时,你按参数algos排序参数UserusedCountAlgo

于 2012-06-28T13:07:15.393 回答
0

听起来你想要一个缓存。我想你可以看看缓存使用的算法,然后拿出关于上下文切换的整个业务......有一种叫做“时钟扫描”的算法......但是对于你正在寻找的东西来说,这可能都太复杂了. 采取懒惰的方式,我想说只是做一个“用过的东西”的哈希:num_of_uses 或者,在你的类中,每次使用对象时都有一个 var you ++。

每隔一段时间,按 num_of_uses 或对象按 ++'d 变量的值对散列进行排序。

于 2012-06-28T13:14:51.960 回答
0

添加用户访问对象的日期时间列表。每次用户使用对象时,添加一个日期时间。

现在只需计算列表中 w (现在 - x 天)的日期时间条目数并按此排序。您可以删除 >(现在 - x 天)的日期时间。

用户可能在一个月内使用不同的项目,这将反映这些变化。

于 2012-06-28T12:59:08.673 回答