统计字符串中连续出现多次的元素的个数

引出:

网上可能有类似的问题,二进制串也是一种,比如统计“1100110011110001010”连续出现多次的元素个数:

连续出现两次或两次以上的元素的个数

"1"为3次,“0”为3次

我一般喜欢用自己的思路去想出解决问题的方法,所以也没细查。数据结构与算法这种问题,我建议程序员如果想打牢基础的话最好自己动手去敲代码实现,做的多了,逻辑清晰了,问题自然就处理了

思路:

看似简单,就输入子串嘛:“1001110”,“1”为1,“0”为1,肉眼看似容易,但要做的就是在程序中加一些语句和判断让计算机去识别。第一个冒出来的想法就是循环遍历,逐个比较,这个方法貌似可行,但想了并试着做了很久都没有清晰的思路,因为元素的下标都是固定的,很难有灵活的操作,看似简单的问题常规方法不可行。于是就想到排序算法中的插入排序,类似的做法就是将元素拆分,将元素分为两部分,对拆分的一端去操作。

步骤详解:

在这个例子中,要使得程序实现,在这为了简单,我们仅仅考虑某一种元素,指定一个key(比如'1')出现多次的情况,首先还是遍历,我们可以用pop()方法(转str为list),首先判断pop(0)是否为'1',然后再做其他判断操作,首先在之外有一个大循环控制,while alist,即当我一个个循环取出时,取完为止,可写出这两行代码

while alist:
        if alist.pop(0) == '1':

还拿“1001110”为例,当满足第一个元素为'1'时,可以初始化num=0,为统计连续出现元素的个数,既有num+=1,

当第二个元素不满足为'1'时,将num重置为0,于是:

num = 0
while alist:
    if alist.pop(0) == '1':
        num += 1
    else:
        num = 0

理所当然,在判断为某个元素的值时,连续出现两次以上给个统计,用count计数。

拿“110”为例,pop(0)多次循环过后,第一次取到'1',此时alist=[1,0],第二次是'1',此时alist=[0],第三次为0,alist=[],故当下一个元素不为我当前的元素时,即满足num>=2并且alist[0] != ‘1’,count+=1

这里有一些特殊情况,拿“111”为例,第一次取到'1',alist=[1,1],第二次取到‘1’,alist=[1],第三次取到‘1’,alist=[],此时alist没有元素,alist[0]为false,但他满足连续的定义,故在满足num>=2并且len(alist)==0,count+=1

故当满足 alist[0] != ‘1’,len(alist)==0其中的一种,并且num >= 2,统计一次个数。当然,统计过后,num需要置为0

num = 0
count = 0
while alist:
    if alist.pop(0) == '1':
        num += 1
        if (len(alist) == 0 or alist[0] != '1') and num >= 2:
            count += 1
            num = 0
    else:
        num = 0

基本的框架形成,封装成函数

def count_(alist,a_key):
    count = 0
    num = 0
    while alist:
        if alist.pop(0) == a_key:
            num += 1
            if (len(alist) == 0 or alist[0] != a_key) and num >= 2:
                count += 1
                num = 0
        else:
            num = 0
    return count

注意,在重复调用函数时,所处理的对象会改变,如果想统计其他元素连续多次出现的次数,需要重新给定一个对象,如

def count_(alist,a_key):
    count = 0
    num = 0
    while alist:
        if alist.pop(0) == a_key:
            num += 1
            if (len(alist) == 0 or alist[0] != a_key) and num >= 2:
                count += 1
                num = 0
        else:
            num = 0
    return count

s = '101010010010011011'
print(count_(list(s),'1'))

s = '101010010010011011'
print(count_(list(s),'0'))

得到的结果为

扩展:

从键盘输入任意整数n,表示有多少行接下来的输入;比如输入n=4,再继续输入4行0和1用空格表示的字串如1 1 1 0、1 1 0 0、0 1 1 0、1 0 1 0,可以看做为一个矩阵;其中横纵连续的0表示海洋,连续的1表示大陆,判别出这片土地(矩阵)有多少个大陆多少个海洋

这个问题就相当于我们之前的扩展,如上述的输入

棕色部分表示大陆,蓝色部分表示海洋,可见有6个大陆,2个海洋。

无非就是循环遍历每一行和每一列,统计相邻多元素的总和

首先定义一个对象,返回的是用户输入的结果,转换成我们想要的形式,最后返回一个用户输入的二维列表和转置的二维列表

n = int(input())
all_ = []
for i in range(n):
    all_.append([int(i) for i in input().split(' ')])
all_T = list(map(list,zip(*all_)))
print(all_,all_T)

可以把这段代码封装成一个函数,方便调用

def get_object():
    n = int(input())
    all_ = []
    for i in range(n):
        all_.append([int(i) for i in input().split(' ')])
    all_T = list(map(list,zip(*all_)))
    return all_,all_T

接下来定义一个在二维列表中统计的函数,传入的是二维列表与转置的二维列表(横纵遍历)以及key,返回的是在二维列表中,key连续出现的次数

def count_all(all_,all_T,a_key):
    count = 0
    for item in all_:
        count += count_(item,a_key)
    for item in all_T:
        count += count_(item,a_key)
    return count

对于count_()这个函数来说,每次执行的时候,列表会发生改变,故在统计1和0之前,先拷贝一份原对象

import copy
all_1,all_T_1 = get_object()
all_0,all_T_0 = copy.deepcopy(all_1),copy.deepcopy(all_T_1)

调用统计函数count_all

print('大陆数量:',count_all(all_1,all_T_1,1))
print('海洋数量:',count_all(all_0,all_T_0,0))

全部python3代码

import copy

def get_object():
    n = int(input())
    all_ = []
    for i in range(n):
        all_.append([int(i) for i in input().split(' ')])
    all_T = list(map(list,zip(*all_)))
    return all_,all_T

def count_(alist,a_key):
    count = 0
    num = 0
    while alist:
        if alist.pop(0) == a_key:
            num += 1
            if (len(alist) == 0 or alist[0] != a_key) and num >= 2:
                count += 1
                num = 0
        else:
            num = 0
    return count

def count_all(all_,all_T,a_key):
    count = 0
    for item in all_:
        count += count_(item,a_key)
    for item in all_T:
        count += count_(item,a_key)
    return count

all_1,all_T_1 = get_object()
all_0,all_T_0 = copy.deepcopy(all_1),copy.deepcopy(all_T_1)

print('大陆数量:',count_all(all_1,all_T_1,1))
print('海洋数量:',count_all(all_0,all_T_0,0))

输入测试,得到结果:

猜你喜欢

转载自blog.csdn.net/weixin_39631030/article/details/82821407