如何使用递归找到出现次数最多的首字母?

时间:2013-05-27 18:05:20

标签: algorithm recursion linked-list

给定一个遍布链表的句子,其中列表中的每个项目都是单词,例如:

您好 - >每个人 - >如何 - >是 - >你 - >感觉 - > |

鉴于此列表已排序,例如:

是 - >每个人 - >感觉 - >您好 - >如何 - >你 - > |

你会如何编写递归来找到句子中出现最多的首字母(在本例中是来自Hello& How的字母H)?

5 个答案:

答案 0 :(得分:1)

编辑:我已将代码更新为递归版本。

要运行它,请致电

GetMostLetterRecursion(rootNode , '0', 0, '0', 0)

代码本身如下:

public char GetMostLetterRecursion(LinkedListNode<String> node, char currentChar, int currentCount, char maxChar, int maxCount)
{
    if (node == null) return maxChar;

    char c = node.Value[0];
    if (c == currentChar)
    {
        return GetMostLetterRecursion(node.Next, currentChar, currentCount++, maxChar, maxCount);
    }

    if(currentCount > maxCount)
    {
        return GetMostLetterRecursion(node.Next, c, 1, currentChar, currentCount);
    }

    return GetMostLetterRecursion(node.Next, c, 1, maxChar, maxCount);
}

答案 1 :(得分:1)

解决方案1 ​​

循环显示单词,记录每个字母开头的单词数。根据计数返回最受欢迎的字母(如果您使用计数器的优先级队列,则很容易)。

这需要O(n)时间(单词数)和O(26)内存(字母表中的字母数)。

解决方案2

按字母顺序对单词进行排序。循环过来的话。记录当前字母及其频率,以及迄今为止最受欢迎的字母及其频率。在循环结束时,这是整个列表中最受欢迎的字母。

这需要O(n log n)时间和O(1)内存。

答案 2 :(得分:0)

保留一个数组来存储发生的次数,并通过链表一次计算它。最后循环遍历数组以找到最高的一个。

C中的粗略草图:

int count[26]={0};

While ( head->next != NULL)
{
  count[head->word[0] - 'A']++; // Assuming 'word' is string in each node
  head = head->next;
}

max = count[0];
for (i=0;i<26;i++)
{
  if(max<a[i])
    max = a[i];
}

您可以修改它以使用递归并处理小写字母。

答案 3 :(得分:0)

这是Python中的纯递归实现。我没有测试它,但它应该模拟拼写错误或语法错误。我使用Dictionary来存储计数,因此它也可以使用Unicode字。问题分为两个函数:一个用于计算每个字母的出现次数,另一个用于递归查找最大值。

# returns a dictionary where dict[letter] contains the count of letter
def count_first_letters(words):

    def count_first_letters_rec(words, count_so_far):

        if len(words) == 0:
            return count_so_far

        first_letter = words[0][0]

        # could use defaultdict but this is an exercise :)
        try:
            count_so_far[first_letter] += 1
        except KeyError:
            count_so_far[first_letter] = 1

        # recursive call
        return count_first_letters_rec(words[1:], count_so_far)

    return count_first_letters(words, {})


# takes a list of (item, count) pairs and returns the item with largest count.
def argmax(item_count_pairs):

    def argmax_rec(item_count_pairs, max_so_far, argmax_so_far):

        if len(item_count_pairs) == 0:
            return argmax_so_far

        item, count = item_count_pairs[0]

        if count > max_so_far:
            max_so_far = count
            argmax_so_far = item

        # recursive call
        return argmax_rec(item_count_pairs[1:], max_so_far, argmax_so_far)

    return argmax_rec(item_count_pairs, 0, None)


def most_common_first_letter(words);

    counts = count_first_letters(words)

    # this returns a dictionary, but we need to convert to
    # a list of (key, value) tuples because recursively iterating
    # over a dictionary is not so easy

    kvpairs = counts.items()
    # counts.iteritems() for Python 2

    return argmax(kvpairs)

答案 4 :(得分:0)

我有一个长度为26的数组(英文字母,因此索引1代表'a',2代表'b',依此类推。)。每次出现一个字母时,我都会在数组中增加它的值。如果该值超过最大值,那么我更新最大值并将该字母作为大多数发生的一个。然后我为下一个节点调用该方法。

这是Java中的代码:

import java.util.LinkedList;


public class MostOccurance {
    char mostOccured;
    int maxOccurance;
    LinkedList<String> list= new LinkedList<String>();
    int[] letters= new int[26];


 public void start(){
     findMostOccuredChar( 0, '0', 0);
 }

 public char findMostOccuredChar ( int node, char most, int max){
     if(node>=list.size())
         return most;
     String string=list.get(node);
     if (string.charAt(0)== most)
         {max++;
         letters[Character.getNumericValue(most)-10]++; 
         }
     else{
         letters[Character.getNumericValue(most)-10]++;
         if (letters[Character.getNumericValue(most)-10]++>max){
             max=letters[Character.getNumericValue(most)-10];
             most=string.charAt(0);
         }
     }
     findMostOccuredChar( node++, most, max);

     return most;
      }


  }

当然,您必须将每个单词添加到链接列表中。我没有这样做,因为我只是在展示一个例子。