V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
hellogitooxx
V2EX  ›  Python

急急急,小白弱弱请教一个关于字符串的大问题

  •  1
     
  •   hellogitooxx · 2021-03-20 09:54:39 +08:00 · 2432 次点击
    这是一个创建于 1342 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有一个字符数组(可自增),如:AAAABAAABBABBBABBBBCABDBABCABBAAAAACAAAACBCAAAAAABBBCCACBABBABAAABAE....,将它切成 6 行(暂定)输出,切法如下:
    A, A, B, B, A, A, A, C, A, A, A, A
    A, A, B, C, B, A, A, A, B, C, B, E
    A, B, A, A, C, A, A, A, B, B, A, .
    A, B, B, B, A, A, A, A, B, A, A, .
    B, A, B, D, B, A, C, A, C, B, A, .
    A, B, B, B, B, C, B, A, C, B, B, .
    即每 6 个元素为一组,向竖输出,请给出互相行之间不断比较,有三个以上(暂定)相同的元素开始计算,一直计算出每行之间都不存在(四个,五个。。。)相同的元素为止,注意提示第几行和第几行有相同并统计出现次数。


    刚开始我看着也有点迷糊,按题目的意思是,先把字符串格式输出先,然后再取每行前面三个元素相互比较,然后再统计,后面要是还有相同的元素,不断比较和统计。

    我的代码如下:

    def get_str(str1):
    # 字符串转换成列表,方便观看
    list_ = list(str1)
    # print(list_)

    # 生成 6 个空列表
    b1, b2, b3, b4, b5, b6 = ([] for i in range(6))
    # 等待间隔数,利用方差
    c1 = 6
    # 统计相同次数
    num = 0
    # 相同行次统计
    sum_tong = 0

    for index, value in enumerate(list_):
    index = index + 1

    if index % c1 == 1:
    b1.append(value)
    # print(b1)
    if index % c1 == 2:
    b2.append(value)

    if index % c1 == 3:
    b3.append(value)

    if index % c1 == 4:
    b4.append(value)

    if index % c1 == 5:
    b5.append(value)

    if index % c1 == 0:
    b6.append(value)

    if index <= 18 and len(b1) == 3:

    if b1 == b2 and (index % c1 == 2):
    sum_tong = sum_tong + 1
    print("第一行和第二行相同----次数::" + str(sum_tong))
    elif b1 == b3 and (index % c1 == 3):
    sum_tong = sum_tong + 1
    print("第一行和第三行相同----次数::" + str(sum_tong))

    elif b1 == b4 and (index % c1 == 4):

    sum_tong = sum_tong + 1
    print("第一行和第四行相同----次数::" + str(sum_tong))
    elif b1 == b5 and (index % c1 == 5):

    sum_tong = sum_tong + 1
    print("第一行和第五行相同----次数::" + str(sum_tong))
    elif b1 == b6 and (index % c1 == 0):

    sum_tong = sum_tong + 1
    print("第一行和第六行相同----次数::" + str(sum_tong))

    elif b2 == b3 and (index % c1 == 3):

    sum_tong = sum_tong + 1
    print("第二行和第三行相同----次数::" + str(sum_tong))
    elif b2 == b4 and (index % c1 == 4):

    sum_tong = sum_tong + 1
    print("第二行和第四行相同----次数::" + str(sum_tong))
    elif b2 == b5 and (index % c1 == 5):

    sum_tong = sum_tong + 1
    print("第二行和第五行相同----次数::" + str(sum_tong))
    elif b2 == b6 and index % c1 == 0:

    sum_tong = sum_tong + 1
    print("第二行和第六行相同----次数::" + str(sum_tong))

    elif b3 == b4 and (index % c1 == 4):

    sum_tong = sum_tong + 1
    print("第三行和第四行相同----次数::" + str(sum_tong))
    elif b3 == b5 and (index % c1 == 5):

    sum_tong = sum_tong + 1
    print("第三行和第五行相同----次数::" + str(sum_tong))
    elif b3 == b6 and index % c1 == 0:

    sum_tong = sum_tong + 1
    print("第三行和第六行相同----次数::" + str(sum_tong))

    elif b4 == b5 and (index % c1 == 5):

    sum_tong = sum_tong + 1
    print("第四行和第五行相同----次数::" + str(sum_tong))
    elif b4 == b6 and index % c1 == 0:

    sum_tong = sum_tong + 1
    print("第四行和第六行相同----次数::" + str(sum_tong))

    elif b5 == b6 and index % c1 == 0:
    sum_tong = sum_tong + 1
    print("第五行和第六行相同----次数::" + str(sum_tong))

    elif index > 18 and sum_tong >= 2:

    if b1 == b2 and (index % c1 == 2):
    num = num + 1
    print("第一行和第二行有对应相同的----次数:" + str(num))
    elif b1 == b3 and (index % c1 == 3):
    num = num + 1
    print("第一行和第三行有对应相同的----次数:" + str(num))

    elif b1 == b4 and (index % c1 == 4):

    num = num + 1
    print("第一行和第四行有对应相同的----次数:" + str(num))
    elif b1 == b5 and (index % c1 == 5):

    num = num + 1
    print("第一行和第五行有对应相同的----次数:" + str(num))
    elif b1 == b6 and (index % c1 == 0):

    num = num + 1
    print("第一行和第六行有对应相同的----次数:" + str(num))

    elif b2 == b3 and (index % c1 == 3):

    num = num + 1
    print("第二行和第三行有对应相同的----次数:" + str(num))
    elif b2 == b4 and (index % c1 == 4):

    num = num + 1
    print("第二行和第四行有对应相同的----次数:" + str(num))
    elif b2 == b5 and (index % c1 == 5):

    num = num + 1
    print("第二行和第五行有对应相同的----次数:" + str(num))
    elif b2 == b6 and index % c1 == 0:

    num = num + 1
    print("第二行和第六行有对应相同的----次数:" + str(num))

    elif b3 == b4 and (index % c1 == 4):

    num = num + 1
    print("第三行和第四行有对应相同的----次数:" + str(num))
    elif b3 == b5 and (index % c1 == 5):

    num = num + 1
    print("第三行和第五行有对应相同的----次数:" + str(num))
    elif b3 == b6 and index % c1 == 0:

    num = num + 1
    print("第三行和第六行有对应相同的----次数:" + str(num))

    elif b4 == b5 and (index % c1 == 5):

    num = num + 1
    print("第四行和第五行有对应相同的----次数:" + str(num))
    elif b4 == b6 and index % c1 == 0:

    num = num + 1
    print("第四行和第六行有对应相同的----次数:" + str(num))

    elif b5 == b6 and index % c1 == 0:
    num = num + 1
    print("第五行和第六行有对应相同的----次数:" + str(num))

    print("相同总行数" + str(sum_tong))
    # 打印
    print(b1)
    print(b2)
    print(b3)
    print(b4)
    print(b5)
    print(b6)
    print("--------------------------------------------------------------------")
    # print("总共出现相同次数" + str(num))


    data1=get_str("AAACDAAAACDABAABBAAABBAABAABBAACCBAA....")


    我卡住了,思路有了,解题方法有点问题,求高手赐教
    22 条回复    2021-03-21 21:57:38 +08:00
    Enying
        1
    Enying  
       2021-03-20 10:16:46 +08:00 via Android   ❤️ 2
    说实话,看不下去…
    Pagliacii
        2
    Pagliacii  
       2021-03-20 10:58:05 +08:00
    没看懂想比较啥,但是竖向输出可以简单写成这样: https://i.loli.net/2021/03/20/BRiEovm5lsdFjV9.png
    Pagliacii
        3
    Pagliacii  
       2021-03-20 11:01:07 +08:00
    @Pagliacii #2 后面的循环应该是 `for row in rows.values()` 才对,写少了
    hellogitooxx
        4
    hellogitooxx  
    OP
       2021-03-20 15:03:14 +08:00
    hellogitooxx
        5
    hellogitooxx  
    OP
       2021-03-20 15:04:54 +08:00
    首先感谢 @Pagliacii 的回答,按他的代码,已经完成了编排,
    前面是我表达不清,不好意思,如下
    A,A,B,B,A,A,A,C,A,A,A,A
    A,A,B,C,B,A,A,A,B,C,B,E
    A,B,A,A,C,A,A,A,B,B,A
    A,B,B,B,A,A,A,A,B,A,A
    B,A,B,D,B,A,C,A,C,B,A
    A,B,B,B,B,C,B,A,C,B,B
    需求:
    元素已经编排好了,然后选择第一行前面的 3 个元素,和后面 5 行前面三个元素对比,有相同的+1,如第一行和第二行有相同的,则+1,行与行之间相互不断比较,到第 4 行和第 6 行也有相同的,也+1,不过这个+1 不是在第一行和第二行的前提上+1,因为它们的内部元素不相等的,然后继续循环,又回到第一行,取前面 4 个元素,相互比较,第 4 行和第 6 行也有相同的相同元素出现+1,循环,后面取前面 5 个元素,又一次循环,发现没有相同元素,程序结束。

    想得到的信息:
    第一和第二行,有相同的,出现一次
    第四和第六行,有相同的,出现二次

    恳请赐教。
    Pagliacii
        6
    Pagliacii  
       2021-03-20 18:37:09 +08:00   ❤️ 1
    @hellogitooxx #5 有三个问题。

    1. 相同元素是指字符相同即可,还是要位置相符?
    2. 是每行都和其他行比较一次,还是相邻的两行作比较?
    3. 取前面的元素作比较,元素的个数是从 3 到 5 即可,还是要到行尾?
    drinkeroftea
        7
    drinkeroftea  
       2021-03-20 19:38:07 +08:00   ❤️ 1
    result = dict()
    for i in range(len(str_list)):
    for j in range(i+1, len(str_list)):
    count = 0
    for p in range(3, len(str_list[i])):
    if str_list[i][:p] == str_list[j][:p]:
    count += 1
    else:
    break
    result[str(i)+'_'+str(j)] = count

    也不知道有没有读懂你的题干
    hellogitooxx
        8
    hellogitooxx  
    OP
       2021-03-20 20:20:28 +08:00
    @Pagliacii 感谢你的回复,
    1.就是相同的元素字符即可,比如第一行 AAB,第二行也是 AAB,第四行 A,B,B 和第 6 行 A,B,B,
    2.是每行都和其他行比较一次,存在相同就+1,
    3.取前面的元素作比较(从第 3 个元素开始),每循环一次就增加一个元素进行相互比较,直到不存在相同的两行为止。

    暂时还发不了图片网址,见谅。


    @drinkeroftea
    感谢你的热心回复,你可以看看 5 楼我的回复。
    hellogitooxx
        9
    hellogitooxx  
    OP
       2021-03-20 20:22:11 +08:00
    @drinkeroftea 你可以贴张图你的代码运行后的结果么,我再详细描述一下
    Pagliacii
        10
    Pagliacii  
       2021-03-20 20:35:18 +08:00   ❤️ 1
    @hellogitooxx #8 也就是说是每行相同位置的字符要相同才计算是吧?

    “从第 3 个元素开始” 是指前两个元素不用管吗?
    hellogitooxx
        11
    hellogitooxx  
    OP
       2021-03-20 23:59:49 +08:00
    @Pagliacii 是的,每行相同位置的字符要相同。
    “从第 3 个元素开始” 是指前两个元素不用管。
    Pagliacii
        12
    Pagliacii  
       2021-03-21 00:04:43 +08:00
    @hellogitooxx 如果我没理解错的话,大概就是这样的:

    https://i.loli.net/2021/03/21/DGe4xAXUSzBr7oZ.png
    Pagliacii
        13
    Pagliacii  
       2021-03-21 00:06:53 +08:00   ❤️ 1
    @Pagliacii #12 贴错图了,应该是这张: https://i.loli.net/2021/03/21/XxYQLNKiWzylmTa.png
    hellogitooxx
        14
    hellogitooxx  
    OP
       2021-03-21 09:45:57 +08:00
    @Pagliacii 感谢你在百忙之中回复,
    然后选择第一行前面的 3 个元素,去后面 5 行查找是否存在前面三个元素相同的,有相同的+1,如第一行和第二行有相同的,则+1 (绿色条),程序向下循环查找,AAB 已经后面行已经没有,然后,(第二行,前面的 3 个元素,去后面 4 行查找是否存在前面三个元素相同的,有则+1,第三行同样,以此类推,比较存在就+1,)
    到第 4 行和第 6 行也有相同的,也+1,不过这个+1 不是在第一行和第二行的前提上+1,因为它们的内部元素不相等的,然后继续循环,又回到第一行,开始取前面 4 个元素(因为之前是 3 个元素,现在元素内部也自增+1,循环一次,蓝色箭头),相互比较(查找),第 4 行和第 6 行也有相同的相同元素出现+1 (黄色条),面取前面 5 个元素,又一次循环,发现没有相同元素,程序结束。

    思维是,先将字符串转换成 6 行,向竖输出,然后,第一次,先取第一行前面 3 个元素,去查找后面行前面 3 个元素是否有相同的,存在则+1,循环一次过后,再取第二行前面 3 个元素,去后面 4 行查找是否存在前面三个元素相同的,有则+1,第三行同样,以此类推,像比较存在就+1 )

    截图我也发你邮箱了,再次感谢你。
    Pagliacii
        15
    Pagliacii  
       2021-03-21 10:02:52 +08:00   ❤️ 1
    @hellogitooxx #14 那就是我原来的理解才是对的,是从取 3 个元素开始各行之间作比较。但是你在 #11 又说“从第 3 个元素开始” 是指前两个元素不用管,我就改了代码不比较前两个元素了。

    https://i.loli.net/2021/03/21/FZNhU1kb56RivY9.png

    其实你只要改动比较字符的长度范围即可,即将 [i:i + 1] 改成 [:i + 1]
    hellogitooxx
        16
    hellogitooxx  
    OP
       2021-03-21 12:00:11 +08:00
    @Pagliacii 太感谢你了。刚学编程不久,能够遇到你这样热心回答,向你学习。
    Pagliacii
        17
    Pagliacii  
       2021-03-21 12:09:30 +08:00
    @hellogitooxx #16 不客气。其实你只要把问题拆解成一个个小问题,然后把小问题一个个解决就能够解决大问题了。另外清晰地表达出问题也有助于思考
    hellogitooxx
        18
    hellogitooxx  
    OP
       2021-03-21 19:33:51 +08:00
    @Pagliacii

    def detect_paired(rows):
    paired_rows = list(combinations(rows.keys(), 2))
    # 你把 paired 这个变量换成一个字典来存储比较结果就好了。
    # 比如以行数组成的元组作为 key,而 value 则是相同的次数。
    # 这样只要每次发现相同的两行,就把 value 加一,就可以得到你想要的结果了。
    paired = {}
    value =1
    i = 2
    longest_column = max(rows.values(), key=lambda row: len(row))
    while paired_rows and i < len(longest_column):
    for pair in paired_rows[:]:
    # print(pair)
    if rows[pair[0]][:i + 1] == rows[pair[1]][:i + 1]:
    # 以行数组成元组:pair
    #print(paired.keys())
    # 你应该先判断这两行是否已经记录过了,即是否存在于
    # paired 这个字典里。如果字典里已有记录,那么就更新这个记录。
    # 如果没有,那么就新增一个记录到字典里去。
    if pair in paired.keys():
    #if pair==paired[pair]:
    value += 1
    paired[pair]=value # 更新

    elif pair not in paired.keys():
    paired.update({pair: value})

    print(f"L{pair[0]}==L{pair[1]}:{rows[pair[0]][:i + 1]}")

    else:
    paired_rows.remove(pair)
    i += 1

    return paired


    添加了判断行数组是否存在,
    我另外换了一串字符串,如下:
    AAAAAABBBBBBABAABAABBBBABAAAAABABBAABBABABAAABBABAABAABDEFABBF

    为什么达不到我想要的效果的,请问问题还出在哪里呢

    按理说( 1,4 ),( 2,3 )不会有这么多呢?

    我遇到的问题是怎么更新对应的字典里的键的值。

    恳请你指点一下
    Pagliacii
        19
    Pagliacii  
       2021-03-21 19:54:33 +08:00   ❤️ 1
    @hellogitooxx #18 判断一个 key 是否已存在字典里和更新字典项其实可以写成一行,如下:

    paired[pair] = paired.get(pair, 0) + 1

    上面这一行的代码是使用了字典的 get 方法。它的作用是如果字典里存在对应的 key,则返回它的 value 给调用方;如果不存在则返回第二个参数。

    至于如何更新字典项,就是用赋值符号把值赋给对应项,如上面的 paired[pair] = ...
    hellogitooxx
        20
    hellogitooxx  
    OP
       2021-03-21 21:42:40 +08:00
    @Pagliacii 感谢你。
    hellogitooxx
        21
    hellogitooxx  
    OP
       2021-03-21 21:50:56 +08:00
    @Pagliacii 我想问下,我还需要在哪方面进修,我对编程很感兴趣。像你回答题中,类似 defaultdict,combinations,我都没有学习到,没想到是 python 就自带的,很是惭愧。
    Pagliacii
        22
    Pagliacii  
       2021-03-21 21:57:38 +08:00
    @hellogitooxx #21 多看看 Python 官方文档 https://docs.python.org/3/,多了解 Python 的标准库
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   969 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 21:40 · PVG 05:40 · LAX 13:40 · JFK 16:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.