У меня есть входной текстовый файл следующим образом:
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"
Эта версия ответа учитывает оба момента, поднятые в комментариях.
Имейте в виду, что если вы измените формат текста, вам может потребоваться настроить 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;
Теперь не будет :)
Спасибо @Ottxr, будет ли ваш код работать, если однажды я добавлю, может быть, Bunny -v- Duck? так как я узнаю, вы просто принимаете во внимание первое слово?
@CatyCatCat Теперь будет :)
Если вы измените последовательность, ваш ответ не удастся. бывший. Переместите
Bunny Penalty -vs- Dog Penalty
в последнюю строку