#c# #count #frequency #find-occurrences
Вопрос:
Примеры Входных данных:
- питер предупреждает Пита, чтобы он не ходил на море
- альфреду следует отправиться на море
- альберт предупреждает Пита
- я же говорил тебе не ходить в Диснейленд
Примеры Результатов:
- 3: перейдите к
- 2: отправляйтесь к морю
- 2: не ходить в
Необязательный:
- Не учитывайте случаи ниже 2.
Мой подход
public void zähleHäufigkeitWorte(string[] arr, int n)
{
bool[] visited = new bool[n];
// Traverse through array elements and
// count frequencies
for (int i = 0; i < n; i )
{
// Skip this element if already processed
if (visited[i] == true)
continue;
// Count frequency
int count = 1;
for (int j = i 1; j < n; j )
{
if (arr[i] == arr[j])
{
visited[j] = true;
count ;
}
}
wort.Add(arr[i],count);
}
}
Как мне расширить, чтобы подсчитать количество вхождений фраз?
Комментарии:
1. Возможно, вам понадобится
Dictionary<string, int>
, где ключом является фраза, а значением-счетчик вхождений.2. @PeterCsala Спасибо за редактирование.
Ответ №1:
Это должно сработать:
using System;
using System.Collections.Generic;
namespace SO68666232
{
public class PhraseCounter
{
public static Dictionary<string, int> countWordAndPhraseFrequencies(string input)
{
var phraseDic = new Dictionary<string, int>();
string[] tokens = input.Split(' ');
int ntokens = tokens.Length;
for (int start = 0; start < ntokens; start )
{
for (int nwords = 1; nwords <= (ntokens- start) ; nwords )
{
ArraySegment<string> phraseTokens = new ArraySegment<string>(tokens, start, nwords);
string phrase = string.Join(" ", phraseTokens);
if (phraseDic.ContainsKey(phrase))
{
phraseDic[phrase] ;
}
else
{
phraseDic[phrase] = 1;
}
}
}
// Remove elements with only 1 occurrence
IEnumerable<string> keys = new List<string>(phraseDic.Keys);
foreach (string key in keys)
{
if (phraseDic[key] <= 1)
{
phraseDic.Remove(key);
}
}
return phraseDic;
}
}
}
Возможно, это не самый эффективный способ, так как время увеличивается с увеличением количества слов в квадрате, но он работает.
Испытательная программа:
class Program
{
const string sampleInput = "peter warns pete to not go to the sea alfred should go to the sea albert warns pete i told you to not go to disneyland";
static void Main(string[] args)
{
var res = PhraseCounter.countWordAndPhraseFrequencies(sampleInput);
foreach (string key in res.Keys)
{
Console.WriteLine("{0}: {1}", key, res[key]);
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
Результаты:
warns: 2
warns pete: 2
pete: 2
to: 5
to not: 2
to not go: 2
to not go to: 2
not: 2
not go: 2
not go to: 2
go: 3
go to: 3
go to the: 2
go to the sea: 2
to the: 2
to the sea: 2
the: 2
the sea: 2
sea: 2
Комментарии:
1. Привет. Я получаю
System.OutOfMemoryException
string phrase = string.Join(" ", phraseTokens);
ответ .2. Вы используете приведенную здесь тестовую строку или больший ввод? Каков размер вашего вклада? Алгоритм в основном составляет список всех возможных фраз, поэтому, если у вас есть n слов во входных данных, будет O(n^2) возможных фраз средней длины O(n), поэтому требования к памяти увеличиваются по мере увеличения O(n^3). Алгоритм можно было бы легко изменить, чтобы обеспечить максимальную длину фразы, скажем, в 10 слов, тогда требования к памяти были бы значительно снижены.
3. Другой альтернативой было бы изменить алгоритм для немедленного подсчета количества вхождений фразы и сохранения только в том случае, если > 1, вместо накопления каждой фразы и фильтрации в конце.