cari

Rumah  >  Soal Jawab  >  teks badan

python实现 1-26=A-Z, then AA-AZ, BA-BZ...ZZA-ZZZ, AAAA, etc.

网上看到类似的算法,不过实现是C++.

private static void alphaseq0(int n, String alphabet, StringBuffer buf) {
        int len = alphabet.length();
        
        if (n >= len) {
               alphaseq0(n/len - 1,alphabet,buf);
               n = n % len;
        }
        
        buf.append(alphabet.charAt(n));
}

本题的题意是: 给定一个 整数 n字元集 alphabet,return 一个对应的 string

对应的规则 如下:

(假设我们的字元集是英文字母 A-Z,也就是说这些字元是可以用来代表给定的整数的)

 1  ->    A
 2  ->    B
 3  ->    C
    ...
26  ->    Z
27  ->   AA
    ...
52  ->   AZ
    ...
 m  ->  ZZA
    ...
 n  ->  ZZZ
n+1 -> AAAA
高洛峰高洛峰2806 hari yang lalu1464

membalas semua(1)saya akan balas

  • 阿神

    阿神2017-04-18 09:05:30

    Soalan ini nampak mudah pada pandangan pertama, tetapi sebenarnya saya mengambil banyak masa untuk mengkajinya dengan teliti (mungkin saya berfikiran sederhana...)

    Maksud soalan ini ialah: diberi integer dan set aksara, kembalikan rentetan

    yang sepadan

    dan peraturan yang sepadan untuk adalah seperti berikut:

    (假設我們的字元集是英文字母 A-Z,也就是說這些字元是可以用來代表給定的整數的)
    
     1  ->    A
     2  ->    B
     3  ->    C
        ...
    26  ->    Z
    27  ->   AA
        ...
    52  ->   AZ
        ...
     m  ->  ZZA
        ...
     n  ->  ZZZ
    n+1 -> AAAA

    Saya serta-merta memikirkan itertools.product Saya boleh menjana rentetan yang mencukupi dan memilih nyang:

    from itertools import product
    
    def get_alphaseqs(n, alphabet):
        """ get first n alphaseq """
        results = []
        for l in range(1, len(alphabet)+1):
            results.extend([''.join(p) for p in product(alphabet, repeat=l)])
            if len(results) >= n:
                return results[:n]
        return None
    Jika bilangan perubahan dalam

    alphabet tidak mencukupi, return None

    Jadi jika saya ingin mendapatkan rentetan yang sepadan dengan n=3000;

    alphabet = 'abcdefghijklmnopqrstuvwxyz' 
    string = get_alphaseqs(3000, alphabet)[-1]

    Tetapi masalahnya ialah: ia sangat memakan masa, atas sebab mudah saya menjana terlalu banyak barangan yang tidak perlu. Membandingkan contoh C yang diberikan oleh poster, saya harus terus menjana rentetan yang sepadan

    Jadi apa yang perlu kita lakukan? Saya terfikir untuk membawa penukaran Bukankah masalah ini membawa kepada penukaran?

    Sebagai contoh, mari lihat contoh menukar perpuluhan kepada perenambelasan:

    10進位            分解            16進位
    ---------------------------------------
      1    = 0*(16**1) +  1*(16**0) =     1
     16    = 1*(16**1) +  0*(16**0) =    10
     31    = 1*(16**1) + 15*(16**0) =    1F

    Mengambil 31 sebagai contoh, mula-mula kita bahagikan 16 sekali untuk mendapatkan baki 15, kemudian kita boleh mengetahui simbol pertamanya F, dan kemudian bahagikannya untuk kali kedua untuk mendapatkan baki 1 dan kita juga boleh ketahui simbol keduanya Simbol bit 1.

    Bukankah masalah penukaran semasa kami yang sepadan: memerlukan penukaran perpuluhan (10 simbol 0-9) kepada perenambelasan (26 simbol A-Z)?

    Itu tidak mudah mengikut kaedah penukaran bawa, saya hanya perlu terus membahagikan panjang set aksara len(alphabet) (len(alphabet) bawa) untuk menanyakan simbol yang sepadan bagi setiap bit.

    Malangnya, masalahnya tidak semudah itu. Adakah anda perasan? Surat-menyurat ini akan bermula dari 1 dan bukannya 0. Tanpa surat-menyurat 0, semua peraturan nampaknya banyak terganggu digit perpuluhan 26 sepatutnya dibawa, tetapi ia bukan di sini 26 sepadan dengan satu simbol Z Kita mesti mengetahui peraturan untuk mengendalikan situasi bahagi dengan 26 dan meninggalkan 0.

    Jadi saya mula mematuhi peraturan:

    十進位整數      1   2   ...  26   27  ...  52
    對應字串        A   B   ...  Z    AA  ...  AZ
    除以 26 之商    0   0   ...  1    1   ...   2
    除以 26 之餘    1   2   ...  0    1   ...   0

    Kami akan dapati:

    1. Jika ia bukan integer boleh bahagi (bakinya bukan sifar), maka peraturannya adalah sama dengan penukaran bit Anda boleh terus menggunakan baki untuk menanyakan simbol yang sepadan, dan menggunakan sebagai dividen untuk melakukan bahagian seterusnya

    2. Jika ia adalah bahagian integer (baki sifar), kita mesti mengambil tanda terakhir, dan bahagian seterusnya mesti menggunakan (商-1) sebagai dividen untuk bahagian seterusnya

    Mengikut peraturan ini, saya menulis dua versi fungsi Satu ialah menggunakan rekursif seperti kod sampel C :

    def int2alphaseq(n, alphbet):
        """ change int to alphaseq """
        buf = ''
        if n==0:
            return buf
        if n >= len(alphbet):
            k =  n % len(alphbet)
            if k==0:
                buf = int2alphaseq(n//len(alphbet)-1, alphbet)
            else:
                buf = int2alphaseq(n//len(alphbet), alphbet)
            n = k
        return buf + alphbet[n-1]

    Cara lain ialah menggunakan iterate:

    def int2alphaseqiter(n, alphbet):
        """ change int to alphaseq """
        buf = ''
        while n >= len(alphabet):
            n, k = pmod(n, len(alphabet))
            if k==0:
                n -= 1
            buf = alphabet[k-1] + buf
        if n==0:
            return buf
        else:
            return alphabet[n-1] + buf

    Selagi rentetan yang ditukar oleh ketiga-tiga fungsi ini dibandingkan, ketepatannya boleh disahkan.

    Jika poster menemui sesuatu yang berbeza daripada soalan asal yang dikehendaki atau jika anda mempunyai sebarang ulasan, sila beritahu saya dalam ulasan!


    Soalan yang saya jawab: Python-QA

    balas
    0
  • Batalbalas