如何在数组中检测被1包围的2? (Python)

huangapple go评论65阅读模式
英文:

How do I detect a 2 surrounded by 1's in an array? (Python)

问题

让我们假设我有一个包含1和2的数组。我想检测被1包围的2,并返回数组中完全被1包围的2的组数。例如,假设我有一个20乘5的数组:

[ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2
  2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2
  2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 2
  1 1 2 2 1 1 1 1 2 2 2 1 1 1 2 2 1 1 1 2
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ]

所以上述组中,最终的计数应该是"3",因为有3组完全被1包围的2。边缘上的2组不应包括在内,因为它们没有完全被1包围。

我对处理数组不太熟悉,所以我不知道如何解决这个问题。我该如何编写这样的代码?

英文:

Let's say I have an array containing 1's and 2's. I want to detect the 2's surrounded by 1's and return a count of how many groups of 2's completely surrounded by 1's are present in the array. For example, let's say I have a 20 by 5 array

[ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2
  2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2
  2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 2
  1 1 2 2 1 1 1 1 2 2 2 1 1 1 2 2 1 1 1 2
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ]

So, in the above group, the final count should be "3" because there are 3 groups of 2's that are completely surrounded by 1's Here is the groups of 2's that I would want included. The groups of 2's on the edges should not be included because they are not completely surrounded by 1's.

I'm new to working with arrays, so I'm not sure how to handle this problem. How could I go about coding something like this?

答案1

得分: 0

你可以使用正则表达式轻松解决这个问题。

  1. 将每一行转换为一个字符串,
  2. 匹配 '1(2){2,}1' - #2个或更多 "2" 被 "1" 包围
  3. 将匹配数量添加到总数中
  4. 返回
def groups(data: list, cols: int, wrap: str = '1', find: str = '2') -> int:
    expr = __import__('re').compile(fr'{wrap}({find}){{2,}}{wrap}').finditer
    cnt = 0

    for row in range(0, len(data), cols):
        cmp = ''.join(map(str, data[row:row+cols]))  # 将行转换为字符串
        cnt += sum(1 for _ in expr(cmp))  # 计算正则表达式匹配次数

    return cnt

data = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
        2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
        2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
        1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ]

print(groups(data, 20))  # 4
英文:

You can easily solve this with regex.

  1. convert each row to a string,
  2. match '1(2){2,}1' - #2 or more "2" surrounded by "1"
  3. add match count to total count
  4. return
def groups(data:list, cols:int, wrap:str='1', find:str='2') -> int:
    expr = __import__('re').compile(fr'{wrap}({find}){{2,}}{wrap}').finditer
    cnt  = 0
    
    for row in range(0, len(data), cols):
        cmp  = ''.join(map(str, data[row:row+cols])) #convert row to string
        cnt += sum(1 for _ in expr(cmp))             #count regex matches
        
    return cnt
    
data = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
        2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
        2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
        1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ]
    
print(groups(data, 20)) #4

答案2

得分: 0

这是代码的翻译:

# 将行转换为字符串,去除末尾的2,并计算“122”的出现次数(对应于一个组的开头)
L = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2],
      [2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2],
      [2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2],
      [1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ]

sum( "".join(map(str,r)).rstrip("2").count("122") for r in L)

# 3
英文:

It is not stated in your question but, since you are expecting the result to be 3 (not 4), we have to assume that you only want groups of 2s that have more than one 2 (i.e. 1,2,1 doesn't count).

You can convert the rows to strings, strip the trailing 2s and count the occurrences of "122" (which corresponds to the start of a group)

L = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2],
      [2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2],
      [2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2],
      [1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ]

sum( "".join(map(str,r)).rstrip("2").count("122") for r in L)

# 3

答案3

得分: 0

尤其是如果您的数组很大,您可以将其视为一个由1组成的海洋中的岛屿图像(2s)。

现在您可以使用“Connected Components Analysis”来查找这些岛屿 - 请参阅scikit-image label

然后,您可以执行“EdgeOut”(也称为“External Gradient”)形态学操作,以查找受膨胀影响的岛屿周围的像素,并检查它们是否都为1。

英文:

Especially if your array is large, you can treat it as an image of islands (2s) in an ocean of 1s.

Now you can use "Connected Components Analysis" to find the islands - see scikit-image label.

Then you can do an "EdgeOut" a.k.a. "External Gradient" morphology to find the pixels around the islands that would be affected by a dilation and check they are all 1s.

huangapple
  • 本文由 发表于 2023年7月11日 03:42:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76656844.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定