样本方法&x27;C';挑战

样本方法&x27;C';挑战,c,algorithm,data-structures,C,Algorithm,Data Structures,我最近被问到一个理论上的C问题,我想知道最好的方法是什么: 如果我有一个10个字的文档,那么确定是否有重复的文字以及是否有重复的文字的最佳方法是什么?我如何跟踪有多少重复的文字 任何关于你将如何实现这一点的见解都是非常好的 使用scanf将单词读入字符串数组 对于每个单词,使用strncmp与列表后面的其他单词进行比较 有速度和空间优化,但我(通常)为了简单而优化。关键字是“十”:这意味着最简单的方法是在每个单词前面用两个嵌套循环检查每个单词,这样做很好。如果这个数字是10000000,那么使用

我最近被问到一个理论上的C问题,我想知道最好的方法是什么:

如果我有一个10个字的文档,那么确定是否有重复的文字以及是否有重复的文字的最佳方法是什么?我如何跟踪有多少重复的文字

任何关于你将如何实现这一点的见解都是非常好的

  • 使用scanf将单词读入字符串数组
  • 对于每个单词,使用strncmp与列表后面的其他单词进行比较

  • 有速度和空间优化,但我(通常)为了简单而优化。

    关键字是“十”:这意味着最简单的方法是在每个单词前面用两个嵌套循环检查每个单词,这样做很好。如果这个数字是10000000,那么使用哈希表、堆或排序数组的方法是有保证的。不过,只需十个字,您就不需要构建任何复杂的东西—只需要基本的C字符串读取/比较知识。

    对于更大的实现,您可以使用哈希表并检查冲突

    对于较小的n(例如n=10),我们可以遍历元素并将它们添加到数组中。对于每个元素,检查数组是否重复


    检查数组是否在O(n)中,并检查10个元素中的每个元素是否在O(n)中。因为我们可以通过嵌套循环简单地实现这一点,所以我们可以在O(n^2)时间复杂度下执行这一点。这就足够了,因为对于如此小的n值,性能影响可以忽略不计。

    由于单个单词的长度可能是“小”的,我将从一个基数排序开始,它需要O(nk)时间,其中k是最大单词长度。在这种情况下,您肯定希望首先根据长度将单词排序到单独的列表中(最多n个)

    因为您只对副本感兴趣,所以可以抛出任何长度为1的列表(在本步骤或任何后续步骤中)

    对于每个列表,比较每个列表成员的最后一个字符,为看到的每个不同字符创建一个新的单词列表(最多26个,假设单词都是ASCII字符),截断最后一个字符。再次抛出长度为1的列表,并对新列表进行递归排序


    在最坏的情况下(假设LSD基数排序,所有单词的长度相同,并且只在第一个字符上不同),您将得到O(nk)时间。在最好的情况下(所有单词都有不同的长度),你会得到O(n)时间。在现实世界中,你可能会比O(nk)时间获得显著的进步,因此解决方案应该扩展到更长的单词列表。

    像这样的理论面试问题总是以较小的数量处理(如10个单词)。然而,这个数字毫无意义;它将那些真正能够以一般形式思考问题的应聘者与那些仅仅对他们在互联网上找到的固定面试问题给出固定答案的应聘者区分开来

    最好的软件公司只支持可扩展的解决方案。因此,如果你的答案很简单,但也可以扩展到任何大小的问题(或者,在本例中是文档),那么你将在面试中获得高分。因此,排序,循环中的循环,O(n^2)复杂性,把它们都忘掉。如果你在面试中向一家领先的软件公司提出任何类似的解决方案,你都会失败

    您的具体问题是检查您是否了解哈希表。此问题的最有效解决方案可以用伪代码编写,如下所示:


    上述解决方案最重要的好处是只需对文档进行一次扫描。无需将单词读入内存并进行处理(两次扫描),无需循环中的循环(多次扫描),无需排序(甚至更多次扫描)。在文档经过一次之后,如果您读取了哈希表中的键,则每个单词的计数会准确地告诉您每个单词在文档中出现的次数。任何计数大于1的单词都是重复的

    这个解决方案的秘密在于它使用了哈希表。散列密钥的生成(步骤2)、密钥查找(步骤3)和密钥存储(步骤5)可以实现为近似恒定的时间操作。这意味着这些步骤所用的时间几乎不会随着输入集的大小(即字数)的增加而改变。这意味着,无论是文档中的第10个单词,还是第1000万个单词,将该单词插入哈希表(或查找该单词)所需的时间大致相同。在本例中,我们在第5步中另外记录每个单词的频率。增加一个值是非常有效的固定时间操作


    此问题的任何解决方案都必须至少扫描文档中的所有单词一次。由于我们的解决方案只对每个单词进行一次处理,而所有单词的处理时间几乎相同,因此我们认为我们的解决方案的性能最佳,可以线性扩展,产生O(n)性能(简单地说,处理1000000个单词所需的时间大约是处理1000个单词所需时间的1000倍)。总之,一个可扩展且高效的问题解决方案

    如果这是一个家庭作业,你应该将其标记为“家庭作业”,是吗?不,事实上我几天前在一次面试中被问到了这个问题,但从来没有得到答案……我甚至不需要有人来写代码,只是对他们将如何做感兴趣……什么数据结构等等……整理一下!然后就可以很容易地计算出重复项了。有趣的问题-当你去的时候会变成一堆其他的附加项。“100字怎么样?100000000字?您的解决方案有多复杂?您能做得更好吗?”诸如此类的东西。下面是一个在ideone上实现非常简单的例子。为字符串生成哈希键不是固定时间,除非您使用的哈希算法非常糟糕,不能查看整个字符串。@Jeremy P:如上所述,
    1. Initialise a new hash table.
       For each word in the document...
    2.     Generate a hash key for the word.
    3.     Lookup the word in the hash table using the key. If it is found,
    4.         Increment the count for the word.
           Otherwise,
    5.         Store the new word in table and set its count to one.