从输入列表创建树,然后在有 child 的任何时候递增计数器并检索 parent 节点的 ID?
Creating tree from list of input and then increment a counter anytime there is a child and retrieve the id of the parent node?
我有一个这样的输入文本文件:
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-match 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
由于 Bunny vs Dog 相互比赛了 3 次,这就是为什么他们在这种格式下得到 1-1 或 1-2 的原因(“原始比赛 ID - 到目前为止他们相遇的次数”)。我最初想有一个 Dictionary 但是在字典中找到重复似乎是一件很奇怪的事情。
我应该如何实现一棵树,其中每个 parent 根是具有相应 ID 的原始匹配项,然后添加与子字符串 Corners 或 Penalty 匹配的 child,它们将具有与 parent 相同的匹配 ID,但 child 的任何更多出现都会增加一个计数器?
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
。 Here is a link to the current regex.
主要代码:
//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:
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 -vs- Dog
Bunny Corners -vs- Dog Corners
Bunny Penalty -vs- Dog Penalty
Duck -vs- Cat
Tiger -vs- Lion
Tiger Corners -vs Lion Corners
我需要生成一个输出文本文件,为这些匹配分配(原始 id-match 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
由于 Bunny vs Dog 相互比赛了 3 次,这就是为什么他们在这种格式下得到 1-1 或 1-2 的原因(“原始比赛 ID - 到目前为止他们相遇的次数”)。我最初想有一个 Dictionary
我应该如何实现一棵树,其中每个 parent 根是具有相应 ID 的原始匹配项,然后添加与子字符串 Corners 或 Penalty 匹配的 child,它们将具有与 parent 相同的匹配 ID,但 child 的任何更多出现都会增加一个计数器?
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
。 Here is a link to the current regex.
主要代码:
//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:
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;