Я пытаюсь повторно реализовать алгоритм для создания списка уточненных ключевых слов. У меня нет оригинального исходного кода, только файл .exe инструмента, поэтому у меня есть только ввод и ожидаемый вывод.

Проблема здесь в том, что вывод моей функции не совпадает с выводом оригинальной. Вот код, который я использую:

string[] inputLines = File.ReadAllLines("Input.txt");
Dictionary<string, int> keywordsCount = new Dictionary<string, int>();
List<string> refineList = new List<string>();

//Get Keywords Count
foreach (string fileName in inputLines)
{
    string[] fileNameSplitted = fileName.Split('_');
    for (int i = 0; i < fileNameSplitted.Length; i++)
    {
        string currentKeyWord = fileNameSplitted[i];
        if (!string.Equals(currentKeyWord, "SFX", StringComparison.OrdinalIgnoreCase))
        {
            if (keywordsCount.ContainsKey(fileNameSplitted[i]))
            {
                keywordsCount[fileNameSplitted[i]] += 1;
            }
            else
            {
                keywordsCount.Add(fileNameSplitted[i], 1);
            }
        }
    }
}

//Get final keywords
foreach (KeyValuePair<string, int> keyword in keywordsCount)
{
    if (keyword.Value > 2 && keyword.Key.Length > 2)
    {
        refineList.Add(keyword.Key);
    }
}

Входной файл:

SFX_AMB_BIRDSONG
SFX_AMB_BIRDSONG_MISC
SFX_AMB_BIRDSONG_SEAGULL
SFX_AMB_BIRDSONG_SEAGULL_BUSY
SFX_AMB_BIRDSONG_VULTURE
SFX_AMB_CAVES_DRIP
SFX_AMB_CAVES_DRIP_AUTO
SFX_AMB_CAVES_LOOP
SFX_AMB_DESERT_CICADAS
SFX_AMB_EARTHQUAKE
SFX_AMB_EARTHQUAKE_SHORT
SFX_AMB_EARTHQUAKE_STREAMED
SFX_AMB_FIRE_BURNING
SFX_AMB_FIRE_CAMP_FIRE
SFX_AMB_FIRE_JET
SFX_AMB_FIRE_LAVA
SFX_AMB_FIRE_LAVA_DEEP
SFX_AMB_FIRE_LAVA_JET1
SFX_AMB_FIRE_LAVA_JET2
SFX_AMB_FIRE_LAVA_JET3
SFX_AMB_FIRE_LAVA_JET_STOP
SFX_AMB_UNDW_BUBBLE_RELEASE
SFX_AMB_UNDW_BUBBLE_RELEASE_AUTO
SFX_AMB_WATER_BEACH1
SFX_AMB_WATER_BEACH2
SFX_AMB_WATER_BEACH3
SFX_AMB_WATER_CANALS
SFX_AMB_WATER_FALL_HUGE
SFX_AMB_WATER_FALL_NORMAL
SFX_AMB_WATER_FALL_NORMAL2
SFX_AMB_WATER_FALL_NORMAL3
SFX_AMB_WATER_FOUNTAIN
SFX_CS_LUX_PORTAL_LIGHTNING
SFX_CS_LUX_PORTAL_LIGHTNING1
SFX_CS_LUX_PORTAL_LIGHTNING2
SFX_CS_LUX_PRIEST_COWER
SFX_CS_LUX_PRIEST_MEDAL
SFX_CS_LUX_PRIEST_MEDITATE
SFX_CS_LUX_PRIEST_SCREAM
SFX_CS_LUX_PRIEST_SNIFF1
SFX_CS_LUX_PRIEST_SNIFF2
SFX_CS_LUX_PRIEST_SPIRITS
SFX_CS_LUX_PRIEST_SPIRITS2
SFX_CS_LUX_PRIEST_SPIRITS3
SFX_CS_LUX_PRIEST_SURPRISE
SFX_MON_BM05_TOO_WALK1
SFX_MON_BM05_TOO_WALK2
SFX_MON_BM06_SQU_WALK1
SFX_MON_BM06_SQU_WALK2
SFX_MON_BR06_HAL_ATTACK1
SFX_MON_BR06_HAL_ATTACK2
SFX_MON_BR06_HAL_DIE
SFX_MON_BR06_HAL_HIT
SFX_MON_BR06_HAL_IDLE
SFX_MON_BR06_HAL_IDLE_EATING
SFX_MON_BR06_HAL_LAND1
SFX_MON_BR06_HAL_LAND2
SFX_MON_BR06_HAL_SCRAPE
SFX_MON_BR06_HAL_SLAM
SFX_MON_BR06_HAL_SURPRISE
SFX_MON_BR06_HAL_WALK1
SFX_MON_BR06_HAL_WALK2
SFX_MON_BU01_MUM_ATTACK1
SFX_MON_BU01_MUM_ATTACK2
SFX_MON_BU01_MUM_DIE
SFX_MON_BU01_MUM_HIT
SFX_MON_BU01_MUM_IDLE_RETRIEVE
SFX_MON_BU01_MUM_IDLE_RETRIEVE_GROW
SFX_MON_BU01_MUM_SURPRISE
SFX_MON_BU01_MUM_WALK1
SFX_MON_BU01_MUM_WALK2
SFX_WATER_SPLASH_BIG
SFX_WATER_SPLASH_BIG1
SFX_WATER_SPLASH_BIG2
SFX_WATER_SPLASH_BIG3
SFX_WATER_SPLASH_MED1
SFX_WATER_SPLASH_MED2
SFX_WATER_SPLASH_MED3
SFX_WATER_SPLASH_MEDIUM
SFX_WATER_SPLASH_OUT
SFX_WATER_SPLASH_OUT1
SFX_WATER_SPLASH_OUT2
SFX_WATER_SPLASH_SMALL

И ожидаемый результат (из исходного инструмента):

AMB
MON
WATER
LUX
BR06
HAL
SPLASH
PRIEST
FIRE
BU01
MUM
LAVA
BIRDSONG
WALK1
WALK2
JET
IDLE
EARTHQUAKE
FALL
SURPRISE
BIG
CAVES

Что я должен изменить, чтобы мой метод соответствовал исходному выводу?

Заранее спасибо!

-1
jms2505 3 Фев 2022 в 22:26
1
Время вырваться из вашего отладчика
 – 
pm100
3 Фев 2022 в 22:32
Ну, мой метод не дает сбоев, просто в моем списке вывода есть слова, которые должны быть, и слова, которых быть не должно. Я не понимаю алгоритм, который использует оригинальный инструмент.
 – 
jms2505
3 Фев 2022 в 22:34
1
Отладчики выясняют, почему работающие программы не делают того, что вы ожидаете.
 – 
pm100
3 Фев 2022 в 22:36
Я имею в виду, если вы не знаете алгоритма, то как вы можете написать программу?
 – 
pm100
3 Фев 2022 в 22:37
Да, это проблема. Я пытался провести некоторые тесты в оригинальном инструменте, изменяя входные данные в надежде найти шаблон для написания моего метода, но мне это не удалось.
 – 
jms2505
3 Фев 2022 в 22:43

2 ответа

Как насчет того, чтобы взять его как блок текста, разделить на окончания строк или символы подчеркивания и получить уникальные остатки:

File.ReadAllText(path)
  .Split(new[]{'\r','\n','_'},StringSplitOptions.RemoveEmptyEntries)
  .Distinct();

Подождите... может быть, это только слова три плюс длина, которые встречаются три или более раз:

File.ReadAllText(path)
  .Split(new[]{'\r','\n','_'},StringSplitOptions.RemoveEmptyEntries)
  .GroupBy(w => w)
  .Where(g => g.Key.Length > 2 && g.Count() > 2)
  .Select(g => g.Key)

Если у вас есть фиксированный список слов для исключения, вы можете сделать, например. .Except(new[]{ "SFX", "..." }) в конце..

0
Caius Jard 3 Фев 2022 в 23:09
Спасибо за ваш ответ, но, к сожалению, он не полностью соответствует исходному выводу.
 – 
jms2505
3 Фев 2022 в 22:53
Привет! Только что я обнаружил, что, кажется, пропускает слова, длина которых меньше 3. И да, я думаю, что, вероятно, порядок также важен. Если вы хотите, я могу добавить больше тестовых случаев в свой вопрос.
 – 
jms2505
3 Фев 2022 в 23:41
порядок также важен - в этом случае, я думаю, вам может понадобиться сначала опубликовать сообщение на puzzling.se, посмотреть, смогут ли они взломать его, а затем прийти сюда, чтобы получить помощь в его реализации. Является ли исходная программа, которая делает вывод, программой C#?
 – 
Caius Jard
3 Фев 2022 в 23:50
Но если мы получим тот же вывод, но в другом порядке, не имеет значения, тоже будет хорошо. Нет, оригинальный инструмент был написан на VB6.
 – 
jms2505
3 Фев 2022 в 23:56

Вы можете сделать это с помощью простого LINQ, использовать GroupBy и преобразовать его в словарь. В этом словаре вы можете добавить дополнительные критерии, где вы, например. проверьте минимальное количество вхождений. Вам не нужно беспокоиться о нескольких условиях if-else, и он остается читабельным:

string[] inputLines = File.ReadAllLines("Input.txt");

var output = inputLines
    .SelectMany(s =>
        s.Split('_')
            .Where(w => w != "SFX")
        )
    .GroupBy(g => g)
    .ToDictionary(s => s.Key, s => s.Count())
    .Where(w => w.Key.Length > 2 && w.Value > 2);

enter image description here

0
321X 3 Фев 2022 в 23:25
Это так же неправильно, как и мое; неправильно имеет PORTAL и не имеет JET/BIG
 – 
Caius Jard
3 Фев 2022 в 23:30
Я понимаю!! Хм…
 – 
321X
3 Фев 2022 в 23:36
Затем я подумал: «Давайте уберем числа с конца слов в конце строки…», но это приносит больше нежелательного, например OUT..
 – 
Caius Jard
3 Фев 2022 в 23:49
Кажется, когда есть предмет типа Jet или Big без номера позади него (версия 0) и есть предмет с более новой версией, всего должно быть как минимум 4… это исключает Out. Может быть, я попробую что-то чуть позже!
 – 
321X
4 Фев 2022 в 00:06
Даже при такой стратегии порядок будет слишком сложно определить. Сначала это количество событий, но при ЗЕМЛЕТРЯСЕНИИ оно отключается.... Слишком мало информации. Прости!
 – 
321X
4 Фев 2022 в 02:44