编码脑筋急转弯来更新数组(语言不可知)

时间:2009-09-04 12:29:01

标签: algorithm puzzle code-golf

所有

我需要一种聪明的方法来尽可能快速,干净地实现此算法(用于工作): 我想我已经删除了所有语言特定的问题并将其归结为:

我有两个数组: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];
}

从记忆中做到这一点,希望我没有搞砸索引...

4 个答案:

答案 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++;
    }
}