Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何使用递归找到出现次数最多的首字母?_Algorithm_Recursion_Linked List - Fatal编程技术网

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

Algorithm 如何使用递归找到出现次数最多的首字母?,algorithm,recursion,linked-list,Algorithm,Recursion,Linked List,给定一个分布在链表中的句子,其中列表中的每个项目都是一个单词,例如: 你好->大家->你好->你->感觉如何->| 鉴于此列表已排序,例如: 是->每个人->感觉->你好->如何->你->| 您将如何编写递归来查找句子中出现最多的首字母(在本例中是来自Hello&How的字母H)?保留一个数组来存储出现次数的计数,并遍历一次链接列表来计数。最后循环遍历数组以找到最高的一个 C语言的草图: int count[26]={0}; While ( head->next != NULL) {

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

你好->大家->你好->你->感觉如何->|

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

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


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

保留一个数组来存储出现次数的计数,并遍历一次链接列表来计数。最后循环遍历数组以找到最高的一个

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];
}
int count[26]={0};
While(head->next!=NULL)
{
count[head->word[0]-'A']++;//假设每个节点中的'word'是字符串
头部=头部->下一步;
}
最大值=计数[0];

对于(i=0;i编辑:我已将代码更新为递归版本

为了运行它,您需要调用

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);
}
公共字符GetMostLetterRecursion(LinkedListNode节点,char currentChar,int currentCount,char maxChar,int maxCount) { 如果(node==null)返回maxChar; char c=node.Value[0]; if(c==currentChar) { 返回GetMostLetterRecursion(node.Next、currentChar、currentCount++、maxChar、maxCount); } 如果(currentCount>maxCount) { 返回GetMostLetterRecursion(node.Next,c,1,currentChar,currentCount); } 返回GetMostLetterRecursion(node.Next、c、1、maxChar、maxCount); }
这是Python中的一个纯递归实现。我没有测试过它,但它应该能够以排版或语法错误的方式工作。我使用了一个字典来存储计数,因此它也可以用于Unicode单词。问题分为两个函数:一个用于计算每个字母的出现次数,另一个用于递归查找最大值

#返回dict[letter]包含字母计数的字典
def count_首字母(单词):
def count_first_letters_rec(单词,count_至今):
如果len(字)==0:
返回到目前为止的计数
首字母=单词[0][0]
#可以使用defaultdict,但这是一个练习:)
尝试:
计数到目前为止[第一个字母]+=1
除KeyError外:
到目前为止的计数[第一个字母]=1
#递归调用
返回count\u first\u letters\u rec(单词[1:],count\u至今)
返回计数首字母(单词,{})
#获取(项,计数)对的列表并返回计数最大的项。
def argmax(项目计数对):
def argmax_rec(项目计数对、最大到目前为止、最大到目前为止):
如果len(项目计数对)=0:
返回到目前为止的argmax\u
项目,计数=项目计数对[0]
如果计数>到目前为止的最大值:
最大到目前为止=计数
argmax\u至今=项目
#递归调用
返回argmax\u rec(项目计数对[1]、max\u至今、argmax\u至今)
返回argmax\u rec(项目计数对,0,无)
定义最常用的首字母(单词);
计数=计数首字母(单词)
#这将返回一个字典,但我们需要将其转换为
#(键、值)元组的列表,因为递归迭代
#翻翻字典可不那么容易
kvpairs=counts.items()
#用于Python 2的counts.iteritems()
返回argmax(kvpairs)
解决方案1 循环单词,记下每个字母开头的单词数量。根据计数返回最常用的字母(如果使用优先级队列进行计数,则很容易)

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

解决方案2 按字母顺序排列单词。把单词圈起来。记录当前信件及其频率,以及目前最流行的信件及其频率。在循环的最后,这是整个列表中最受欢迎的字母


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

我有一个长度为26的数组(作为英文字母,所以索引1表示“a”,索引2表示“b”,依此类推)。每次出现一个字母,我都会增加它在数组中的值。如果该值大于max amount,则更新max并将该字母作为最常出现的字母。然后调用下一个节点的方法

以下是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;
      }


  }
import java.util.LinkedList;
公共级最精确{
炭化;
int最大发生率;
LinkedList=新建LinkedList();
int[]字母=新int[26];
公开作废开始(){
findMostOccuredChar(0,'0',0);
}
public char findMostOccuredChar(int节点、char most、int max){
如果(节点>=list.size())
回报最多;
String=list.get(节点);
if(string.charAt(0)=most)
{max++;
字母[Character.getNumericValue(most)-10]+;
}
否则{
字母[Character.getNumericValue(most)-10]+;
if(字母[Character.getNumericValue(most)-10]++>max){
最大值=字母[Character.getNumericValue(most)-10];
most=string.charAt(0);
}
}
findMostOccuredChar(node++,most,max);
回报最多;
}
}

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

你在纸上会怎么做?是什么让你认为递归是解决这个问题的最好方法,还是这是一个练习/家庭作业?这就是练习:)请澄清“句子中出现最多的第一个字母”
o
的出现远远超过
h
。@japreiss似乎它一定是单词的第一个字母。唯一适用的字母是A、E、F、H、H、Y。但这种说法非常误导人。由于列表已排序,选项2是
O(n)
。你可以在我的答案中看到代码