Создание дерева из списка ввода, а затем увеличение счетчика в любое время, когда есть дочерний элемент, и получение идентификатора родительского узла?

У меня есть входной текстовый файл следующим образом:

Bunny -vs- Dog
Bunny Corners -vs- Dog Corners
Bunny Penalty -vs- Dog Penalty
Duck -vs- Cat
Tiger -vs- Lion
Tiger Corners -vs Lion Corners

Мне нужно создать выходной текстовый файл, который назначает (исходный идентификатор совпадения id) для этих совпадений, поэтому ожидаемый результат будет таким:

1: Bunny -vs- Dog
1-1: Bunny Corners -vs- Dog Corners
1-2: Bunny Penalty -vs- Dog Penalty
2: Duck -vs- Cat
3: Tiger -vs- Lion
3-1: Tiger Corners -vs Lion Corners

Поскольку Банни против Пса играют друг с другом три раза, поэтому они получили 1-1 или 1-2 в этом формате («исходный идентификатор матча - количество раз, которые они встречались до сих пор»). Первоначально я думал о Dictionary<int,string>, но поиск дублирования в словаре кажется странным.

Как мне реализовать дерево, в котором каждый родительский корень является исходным совпадением с соответствующим идентификатором, а затем добавить дочерний элемент, который соответствует подстроке Corners или Penalty, и они будут иметь тот же идентификатор совпадения, что и родители, но любые другие вхождения ребенок будет увеличивать счетчик?

Ex: 
"Bunny -vs- Dog" => parent node
"Bunny Corners -vs- Dog Corners => child of "Bunny -vs- Dog"
"Bunny Penalty -vs- Dog Penalty => another child of "Bunny -vs- Dog"
Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
1
0
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эта версия ответа учитывает оба момента, поднятые в комментариях.

Имейте в виду, что если вы измените формат текста, вам может потребоваться настроить Regex, чтобы получить secondWord. Вот ссылка на текущее регулярное выражение.

Основной код:

//Path of the file you want to reading
const string readPath = @"C:\Users\ak\Desktop\testInput.txt";
//Path of the file you want to save to
const string writePath = @"C:\Users\ak\Desktop\testOutput.txt";

//Get the content of readPath
string[] lines = File.ReadAllLines(readPath);

//Create new List for firstWords
List<string> firstWords = new List<string>();
//Create new List for secondWords
List<string> secondWords = new List<string>();
//Create New List for Parents
List<Parent> parents = new List<Parent>();


//Go through each line of your file
int firstDigit = 1;
foreach (string line in lines)
{
    //Get the first word of the line
    string firstWord = line.Split(' ')[0];
    //Get the second word of the line
    Regex regex = new Regex(@"-vs-\s(\S+)"); 
    string secondWord = regex.Match(line).Groups[1].Value;

    //Add new Parent for the words if it doesn't exist already
    if (!parents.Where(o => o._firstWord == firstWord).Select(o => o._secondWord).Contains(secondWord))
    {
        parents.Add(new Parent(firstWord, secondWord, firstDigit));
        firstDigit++;
    }

    //Add firstWord to List
    firstWords.Add(firstWord);
    //Add secondWord to List
    secondWords.Add(secondWord);
}

//Go through each firstWord
int index = 0;
foreach (string word in firstWords)
{
    //Get the Parent corresponding to the word
    Parent parent = parents.Where(o => o._firstWord == word && o._secondWord == secondWords[index]).FirstOrDefault();

    //Add the numbers to the text lines
    if (parent._firstAppearance)
    {
        //Only one digit => ex: 1
        lines[index] = parent._firstDigit + ": " + lines[index];
        parent._firstAppearance = false;
    }
    else
    {
        //Two digits => ex: 1-2
        lines[index] = parent._firstDigit + "-" + parent._secondDigit + ": " + lines[index];
        parent._secondDigit++;
    }

    index++;
}

//Save text to new file
using (StreamWriter writer = new StreamWriter(writePath, true))
{
    foreach (string line in lines)
    {
        writer.WriteLine(line);
    }
}

Родительский класс:

class Parent
{
    public string _firstWord { get; }
    public string _secondWord { get; }
    public int _firstDigit { get; }
    public int _secondDigit { get; set; }
    public bool _firstAppearance { get; set; }

    public Parent(string firstWord, string secondWord, int firstDigit)
    {
        _firstWord = firstWord;
        _secondWord = secondWord;
        _firstDigit = firstDigit;
        _secondDigit = 1;
        _firstAppearance = true;
    }
}

Не забудьте добавить эти пространства имен:

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

Если вы измените последовательность, ваш ответ не удастся. бывший. Переместите Bunny Penalty -vs- Dog Penalty в последнюю строку

MichaelMao 21.12.2020 12:37

Теперь не будет :)

Ottxr 21.12.2020 14:00

Спасибо @Ottxr, будет ли ваш код работать, если однажды я добавлю, может быть, Bunny -v- Duck? так как я узнаю, вы просто принимаете во внимание первое слово?

CatyCatCat 22.12.2020 08:11

@CatyCatCat Теперь будет :)

Ottxr 22.12.2020 10:14

Другие вопросы по теме