所有
我需要一种聪明的方法来尽可能快速,干净地实现此算法(用于工作): 我想我已经删除了所有语言特定的问题并将其归结为:
我有两个数组:A和B.
A中有一个名单列表{Apple,Apple,Banana,Banana,Banana,Carrot,...}每个第i个值在A中出现的次数没有上限。可以只是一个“苹果”或一个万亿。
A中的每个条目在B中都有匹配的条目(多对多映射)。例如:
A[0] = "Apple" B[0] = "0027"
A[1] = "Apple" B[1] = "0028"
A[2] = "Banana" B[2] = "0073"
A[3] = "Banana" B[3] = "0041"
A[4] = "Banana" B[4] = "0069"
如果A中有100个或更少的条目实例(如果有< = 100个香蕉),则它们必须共享相同的初始“B”值。如果超过100,则前100个必须共享相同的B值,但接下来的100个将具有B [i + 100]值。
示例是否有102个苹果
A[0] = "Apple" B[0] = "0027"
A[1] = "Apple" B[1] = "0028"
...
A[99] = "Apple" B[99] = "0073"
A[100] = "Apple" B[100] = "0041"
A[101] = "Apple" B[101] = "0069"
A[102] = "Banana" B[102] = "0123"
然后我想要的结果就是:
A[0] = "Apple" B[0] = "0027"
A[1] = "Apple" B[1] = "0027"
...
A[99] = "Apple" B[99] = "0027"
A[100] = "Apple" B[100] = "0041"
A[101] = "Apple" B[101] = "0041"
A[102] = "Banana" B[102] = "0123"
我确信那里有一些超级大脑可以提出我设计的蹩脚算法,所以让我们看看吧!
编辑1:我猜我应该指出这个是的工作。我认为这是一个有趣的挑战,有人可能希望看到并可能提出一个比我想出的更好的解决方案。
编辑2:感谢daniel指出我的愚蠢错误。
首先制作B的哈希/字典,称为d其中d [“Apple”] = A中Apple的实例数。
while (i < A.count)
{
string cmp = A[i];
int v = d[cmp];
int j=i;
while (v--) {
B[j++] = B[i];
if (j %100 == 0)
i += j
}
i+= d[cmp];
}
从记忆中做到这一点,希望我没有搞砸索引...
答案 0 :(得分:2)
我在C#中的建议,只要我理解了这个问题并假设数组已经排序。
String[] A = GetAs();
String[] B = GetBs();
Int32 count = 0;
Int32 index = 1;
while (index < A.Length)
{
if (A[index] != A[index - 1])
{
count = 0;
}
currentCount++;
if ((A[index] == A[index - 1]) && (count % 100 != 1))
{
B[index] = B[index - 1];
}
index++;
}
如果一个人喜欢紧凑(并且基于零的计数)。
String[] A = GetAs();
String[] B = GetBs();
Int32 c = 0, i = 1;
while (i < A.Length)
{
c = (A[i] == A[i - 1]) ? c + 1 : 0;
B[i] = ((A[i] == A[i - 1]) && (c % 100 != 0)) ? B[i - 1] : B[i];
i++;
}
答案 1 :(得分:0)
我想建立一个字典/哈希表,比如
{'Apple':
{'NumberSeen':102,
'BValues':['0027','0041']
},
'Banana':
{'NumberSeen':1,
'BValues':['0123']
}
}
然后你循环遍历这个,如果NumberSeen%100 = 1则添加一个新的b值,然后从这个字典中重新创建B数组。
编辑:这为您提供了一个处理未排序列表的可读解决方案。我刚看到你的'list is sorted'注释,这意味着你可以在O(1)空间中做得更简单,但我不确定代码有多清楚。
答案 2 :(得分:0)
String curFruit = A[0];
int curFruitCount = 0;
for (int i = 1; i < A.length; i++) {
if (A[i].equals(curFruit) && curFruitCount < 100) {
B[i] = B[i-1];
curFruitCount++;
}else{
curFruit = A[i];
curFruitCount = 1;
}
}
答案 3 :(得分:0)
我非常喜欢DanielBrückner的解决方案,但我认为您可以对其进行一次改进。假设'A'已被排序并且连续100个相同的水果突然出现,那么您可以通过添加以下检查来利用它:
String[] A = GetAs();
String[] B = GetBs();
Int32 c = 0, i = 1;
while (i < A.Length)
{
if(i+99 < A.Length && A[i] == A[i+99])
{
for(int j=1;j<100;j++) b[i+j] = b[i];
i = i+99;
}
else
{
B[i] = (A[i] == A[i - 1]) ? B[i - 1] : B[i];
i++;
}
}