编写脑筋急转弯来更新数组(与语言无关)

发布于 2024-08-03 09:49:25 字数 1796 浏览 3 评论 0原文

总之,

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

我有两个数组:A和B。A

中有一个名称列表{Apple,Apple,Banana,Banana,Banana,Carrot,.. .} 每个第 i 个值在 A 中出现的次数没有上限。可以只有一个“Apple”,也可以有无数个。

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:感谢丹尼尔指出我的愚蠢错误。

我的解决方案只是为了比较(伪代码):

首先制作 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];
}

从记忆中执行此操作,希望我没有搞砸索引...

All,

I need a clever way to implement this algorithm (for work) as quickly and cleanly as possible:
I think I've removed all the language specific issues and boiled it down to this:

I have two arrays: A and B.

A has a list of names in it {Apple, Apple, Banana, Banana, Banana, Carrot, ...} each i-th value has no upper limit on the number of times it can appear in A. There can be just one "Apple" or a zillion.

Each entry in A has a matching entry in B. (many to many mapping). For example:

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"

If there are 100 or fewer instances of an entry in A, (if there are <= 100 Bananas) then they must all share the same initial "B" value. If there are more than 100, then the first 100 must share the same B values, but the next 100 will have the B[i + 100] th value.

Example if there are 102 apples

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"

Then the result that I want is this:

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"

I'm sure there are some super brains out there that can come up with the crappy algorithm I've devised, so let's see it!

Edit 1: Guess I should point out that this was for work. I thought this was a fun challenge that someone might want to look at and possibly come up with a better solution than the one I came up with.

Edit 2: Thanks to daniel for pointing out my dumb mistakes.

My solution just for comparison (pseudo code):

first make a hash/dictionary of B, called d where d[ "Apple" ] = number of instances of Apple in A.

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];
}

doing this from memory, hope I didn't screw up an indexes...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

紅太極 2024-08-10 09:49:25

据我理解问题并假设数组已排序,我在 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++;
}

My suggestion in C# as far as I unterstood the question and assuming the arrays are sorted.

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

If one likes it compact (and a zero based count).

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++;
}
心头的小情儿 2024-08-10 09:49:25

我想建立一个字典/哈希表,比如

{'Apple':
    {'NumberSeen':102,
     'BValues':['0027','0041']
    },
 'Banana':
    {'NumberSeen':1,
     'BValues':['0123']
    }
}

然后你循环它,如果 NumberSeen%100 = 1 添加一个新的 b 值,然后从这个字典重新创建 B 数组。

编辑:这将为您提供一个处理未排序列表的可读解决方案。我刚刚看到你的“列表已排序”评论,这意味着你可以在 O(1) 空间内做得更简单,但我不确定代码有多清晰。

I'd want to build up a dictionary/hashtable, something like

{'Apple':
    {'NumberSeen':102,
     'BValues':['0027','0041']
    },
 'Banana':
    {'NumberSeen':1,
     'BValues':['0123']
    }
}

Then you loop over this, adding a new b value if NumberSeen%100 = 1, then recreate the B-array from this dictionary.

EDIT: This gets you a readable solution which handles an unsorted list. I just saw your 'list is sorted' comment, which means you can do it a lot simpler, in O(1) space, but I'm not sure how clear the code would be.

毁梦 2024-08-10 09:49:25
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;
    }
}
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;
    }
}
久隐师 2024-08-10 09:49:25

我真的很喜欢 Daniel Brü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++;
    }
}

I really like Daniel Brückner's solution but I think you might be able to make one enhancement on it. Assuming the 'A's are sorted and spurts of 100 consecutive identical fruits are common, then you could take advantage of that by adding the following check:

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++;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文