Skip to content

Commit d9e89ad

Browse files
Refactor TranslationMapping class
- Always add index to mapping rather than only Chinese characters - Simplify mapping algorithm - Add unit test for TranslationMapping
1 parent 100f753 commit d9e89ad

File tree

3 files changed

+66
-68
lines changed

3 files changed

+66
-68
lines changed

Flow.Launcher.Infrastructure/PinyinAlphabet.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ public bool ShouldTranslate(string stringToTranslate)
107107
if (previousIsChinese)
108108
{
109109
resultBuilder.Append(' ');
110-
map.AddNewIndex(i, resultBuilder.Length, translated.Length);
110+
map.AddNewIndex(resultBuilder.Length, translated.Length);
111111
resultBuilder.Append(translated);
112112
}
113113
else
114114
{
115-
map.AddNewIndex(i, resultBuilder.Length, translated.Length);
115+
map.AddNewIndex(resultBuilder.Length, translated.Length);
116116
resultBuilder.Append(translated);
117117
previousIsChinese = true;
118118
}
@@ -124,6 +124,7 @@ public bool ShouldTranslate(string stringToTranslate)
124124
previousIsChinese = false;
125125
resultBuilder.Append(' ');
126126
}
127+
map.AddNewIndex(resultBuilder.Length, resultList[i].Length);
127128
resultBuilder.Append(resultList[i]);
128129
}
129130
}

Flow.Launcher.Infrastructure/TranslationMapping.cs

Lines changed: 7 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -8,82 +8,23 @@ public class TranslationMapping
88
{
99
private bool constructed;
1010

11-
private readonly List<int> originalIndexes = new();
12-
private readonly List<int> translatedIndexes = new();
11+
// Asssuming one original item maps to multi translated items
12+
// list[i] is the last translated index + 1 of original index i
13+
private readonly List<int> originalToTranslated = [];
1314

14-
private int translatedLength = 0;
15-
16-
public void AddNewIndex(int originalIndex, int translatedIndex, int length)
15+
public void AddNewIndex(int translatedIndex, int length)
1716
{
1817
if (constructed)
1918
throw new InvalidOperationException("Mapping shouldn't be changed after constructed");
2019

21-
originalIndexes.Add(originalIndex);
22-
translatedIndexes.Add(translatedIndex);
23-
translatedIndexes.Add(translatedIndex + length);
24-
translatedLength += length - 1;
20+
originalToTranslated.Add(translatedIndex + length);
2521
}
2622

2723
public int MapToOriginalIndex(int translatedIndex)
2824
{
29-
if (translatedIndex > translatedIndexes.Last())
30-
return translatedIndex - translatedLength - 1;
31-
32-
int lowerBound = 0;
33-
int upperBound = originalIndexes.Count - 1;
34-
35-
int count = 0;
36-
37-
// Corner case handle
38-
if (translatedIndex < translatedIndexes[0])
39-
return translatedIndex;
40-
41-
if (translatedIndex > translatedIndexes.Last())
42-
{
43-
int indexDef = 0;
44-
for (int k = 0; k < originalIndexes.Count; k++)
45-
{
46-
indexDef += translatedIndexes[k * 2 + 1] - translatedIndexes[k * 2];
47-
}
48-
49-
return translatedIndex - indexDef - 1;
50-
}
51-
52-
// Binary Search with Range
53-
for (int i = originalIndexes.Count / 2;; count++)
54-
{
55-
if (translatedIndex < translatedIndexes[i * 2])
56-
{
57-
// move to lower middle
58-
upperBound = i;
59-
i = (i + lowerBound) / 2;
60-
}
61-
else if (translatedIndex > translatedIndexes[i * 2 + 1] - 1)
62-
{
63-
lowerBound = i;
64-
// move to upper middle
65-
// due to floor of integer division, move one up on corner case
66-
i = (i + upperBound + 1) / 2;
67-
}
68-
else
69-
{
70-
return originalIndexes[i];
71-
}
72-
73-
if (upperBound - lowerBound <= 1 &&
74-
translatedIndex > translatedIndexes[lowerBound * 2 + 1] &&
75-
translatedIndex < translatedIndexes[upperBound * 2])
76-
{
77-
int indexDef = 0;
78-
79-
for (int j = 0; j < upperBound; j++)
80-
{
81-
indexDef += translatedIndexes[j * 2 + 1] - translatedIndexes[j * 2];
82-
}
25+
int loc = originalToTranslated.BinarySearch(translatedIndex);
8326

84-
return translatedIndex - indexDef - 1;
85-
}
86-
}
27+
return loc > 0 ? loc : ~loc;
8728
}
8829

8930
public void endConstruct()
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using Flow.Launcher.Infrastructure;
2+
using NUnit.Framework;
3+
using NUnit.Framework.Legacy;
4+
5+
namespace Flow.Launcher.Test
6+
{
7+
[TestFixture]
8+
public class TranslationMappingTest
9+
{
10+
[Test]
11+
public void AddNewIndex_ShouldAddTranslatedIndexPlusLength()
12+
{
13+
var mapping = new TranslationMapping();
14+
mapping.AddNewIndex(5, 3);
15+
mapping.AddNewIndex(8, 2);
16+
17+
// 5+3=8, 8+2=10
18+
ClassicAssert.AreEqual(2, GetOriginalToTranslatedCount(mapping));
19+
ClassicAssert.AreEqual(8, GetOriginalToTranslatedAt(mapping, 0));
20+
ClassicAssert.AreEqual(10, GetOriginalToTranslatedAt(mapping, 1));
21+
}
22+
23+
[TestCase(0, 0)]
24+
[TestCase(2, 1)]
25+
[TestCase(3, 1)]
26+
[TestCase(5, 2)]
27+
[TestCase(6, 2)]
28+
public void MapToOriginalIndex_ShouldReturnExpectedIndex(int translatedIndex, int expectedOriginalIndex)
29+
{
30+
var mapping = new TranslationMapping();
31+
// a测试
32+
// a Ce Shi
33+
mapping.AddNewIndex(0, 1);
34+
mapping.AddNewIndex(2, 2);
35+
mapping.AddNewIndex(5, 3);
36+
37+
38+
var result = mapping.MapToOriginalIndex(translatedIndex);
39+
ClassicAssert.AreEqual(expectedOriginalIndex, result);
40+
}
41+
42+
private int GetOriginalToTranslatedCount(TranslationMapping mapping)
43+
{
44+
var field = typeof(TranslationMapping).GetField("originalToTranslated", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
45+
var list = (System.Collections.Generic.List<int>)field.GetValue(mapping);
46+
return list.Count;
47+
}
48+
49+
private int GetOriginalToTranslatedAt(TranslationMapping mapping, int index)
50+
{
51+
var field = typeof(TranslationMapping).GetField("originalToTranslated", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
52+
var list = (System.Collections.Generic.List<int>)field.GetValue(mapping);
53+
return list[index];
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)