Viết chương trình tìm nhãn cột Excel theo số cột cho trước bằng Python

Các cột của Microsoft Excel được gắn nhãn theo kiểu A, B, C,..., Z, AA, AB, AC,..., AZ, BA, BB, ... ZZ, AAA, AAB... Nói cách khác, cột 1 sẽ có nhãn là A, cột 2 có nhãn là B và cột 27 sẽ có nhãn là AA.

Đề bài: Cho số cột, hãy tìm nhãn cột tương ứng trong Excel.

Ví dụ:

Input          Output
 26             Z
 51             AY
 52             AZ
 80             CB
 676            YZ
 702            ZZ
 705            AAC

Trong bài viết này, Quản Trị Mạng sẽ cùng các bạn tìm hiểu cách viết chương trình tìm nhãn cột Excel theo số cột cho trước bằng Python.

Cách 1:

Giả sử chúng ta có một số n, giả sử tiếp n = 28. Chúng ta cần tìm nhãn cột trong Excel tương ứng với n. Chúng ta cần xét số dư của phép toán n chia cho 26.

Nếu n chia hết cho 26 và số dư là 0 (có nghĩa n là 26, 52,...) thì chúng ta đặt Z trong chuỗi output và n mới trở thành n/26-1 bởi vì ở đây chúng ta đang coi 26 là Z trong khi trên thực tế nó đứng thứ 25 đối với A.

Tương tự, nếu số dư khác 0 (ví dụ 1, 2, 3,...) thì chúng ta chỉ cần chèn ký tự phù hợp vào chuỗi và thực hiện n = n/26.

Cuối cùng, chúng ta đảo ngược chuỗi và trả về kết quả.

Ví dụ:

n = 700

Số dư của phép toán (n%26) là 24. Do đó, chúng ta đưa X vào trong chuỗi output và n trở thành n/26 với kết quả là 26.

Số dư của phép toán 26%26 là 0. Do đó, chúng ta đưa Z vào trong chuỗi output và n trở thành n/26-1 với kết quả là 0.

Dưới đây là code mẫu để bạn tham khảo:

# Python program to find Excel column name from a
# given column number
 
MAX = 50
 
# Function to print Excel column name
# for a given column number
def printString(n):
 
    # To store result (Excel column name)
    string = ["\0"] * MAX
 
    # To store current index in str which is result
    i = 0
 
    while n > 0:
        # Find remainder
        rem = n % 26
 
        # if remainder is 0, then a
        # 'Z' must be there in output
        if rem == 0:
            string[i] = 'Z'
            i += 1
            n = (n / 26) - 1
        else:
            string[i] = chr((rem - 1) + ord('A'))
            i += 1
            n = n / 26
    string[i] = '\0'
 
    # Reverse the string and print result
    string = string[::-1]
    print "".join(string)
 
# Driver program to test the above Function
printString(26)
printString(51)
printString(52)
printString(80)
printString(676)
printString(702)
printString(705)
 
# This code is contributed by BHAVYA JAIN

Kết quả trả về là:

Z
AY
AZ
CB
YZ
ZZ
AAC

Cách 2:

Bài toàn này tương tự bài toán đổi hệ số thập phân sang hệ số nhị phân nhưng thay vì hệ số nhị phân với chỉ 2 con số 0 và 1 thì ở đây chúng ta có 26 ký tự từ A tới Z. Do đó, chúng ta sẽ thực hiện bài toán chuyển đổi với hệ số 26 thay vì hệ số nhị phân.

Đây là một bài toán thú vị bởi chúng ta sẽ không có số 0 trong hệ thống số này bởi A đại diện cho 1, B đại diện cho 2 và cuối cùng là Z đại diện cho 26.

Để dễ nắm bắt được vấn đề hơn, chúng ta sẽ tiếp cận nó theo hai bước:

1. Chuyển đổi số sang hệ số 26 với giả sử là 0 vẫn có trong hệ thống.

2. Thay đổi hệ số sang một hệ thống không có số 0.

Dưới đây là một ví dụ:

Bước 1:

Giả sử chúng ta có số 676, làm thế nào để chuyển nó sang hệ số 26? Chúng ta vẫn làm theo cách mà chúng ta làm với hệ cơ số nhị phân, thay vì chia cho 2 và thống kê số dư, chúng ta thực hiện phép chia cho 26 và thống kê số dư.

Số 676 trong hệ số 26 là 100 

Bước 2:

Nhưng chúng ta không có số 0 trong hệ cơ số của mình. Làm thế nào để chúng ta loại bỏ số 0?

  • Trong hệ thống số thập phân, để xử lý số 0, chúng ta mượn 10 và trừ 1 từ số có nghĩa tiếp theo.
  • Trong hệ có sớ 26, để xử lý số 0, chúng ta mượn 26 và trừ 1 trong số có nghĩa tiếp theo.

Do vậy, để chuyển 100 trong hệ số 26 sang hệ số 26 nhưng không có số 0, chúng ta nhận được số (25 26).

Biểu diễn dạng ký tự của con số này là: YZ.

Dưới đây là code mẫu để bạn có thể tham khảo:

def printString(n):
     
    arr = [0] * 10000
    i = 0
 
    # Step 1: Converting to number
    # assuming 0 in number system
    while (n > 0):
        arr[i] = n % 26
        n = int(n // 26)
        i += 1
         
    #Step 2: Getting rid of 0, as 0 is
    # not part of number system
    for j in range(0, i - 1):
        if (arr[j] <= 0):
            arr[j] += 26
            arr[j + 1] = arr[j + 1] - 1
 
    for j in range(i, -1, -1):
        if (arr[j] > 0):
            print(chr(ord('A') +
                  (arr[j] - 1)), end = "");
 
    print();
 
# Driver code
if __name__ == '__main__':
     
    printString(26);
    printString(51);
    printString(52);
    printString(80);
    printString(676);
    printString(702);
    printString(705);
 
# This code is contributed by Princi Singh

Kết quả trả về là:

Z
AY
AZ
CB
YZ
ZZ
AAC

Cách 3:

Chúng ta có thể sử dụng một hàm đệ quy để giải quyết bài toán này nhanh chóng và hiệu quả hơn.

Các bảng chữ cái được sắp xếp theo thứ tự là "ABCDEFGHIJKLMNOPQRSTUVWXYZ" và cách ghi nhãn cột của Excel bạn đã biết ở trên.

Vì thế, chúng ta có thể áp dụng logic sau để tìm ra câu trả lời.

Theo thuật ngữ toán học [a,b] có nghĩa là từ a tới b. [1,26] = [A,Z] được hiểu là A đại diện cho A và Z đại diện cho 26. Với [27,52] sẽ bằng với [AA,AZ] và [57,78] sẽ bằng với [BA,BZ].

Logic là chúng ta sẽ nối thêm một bảng chữ cái Alphabet theo đúng tuần tự mỗi khi nó kết thúc bằng 26.

Ví dụ: Nếu số n là 27 thì chúng ta chỉ cần chia cho 26 và chúng ta nhận thấy số dư là 1. Chúng ta thấy 1 là A và có thể được thực hiện theo cách đệ quy.

Thuật toán cụ thể là:

1. Lấy một mảng và sắp xếp các chữ cái từ A đến Z.

2. Nếu số n nhỏ hơn hoặc bằng 26 thì chỉ cần lấy ra chữ cái tương ứng từ mảng và trả về.

3. Nếu nó lớn hơn 26, hãy sử dụng quy tắc Phần dư Thương số, nếu phần dư bằng 0, có 2 cách khả thi, nếu thương số là 1, chỉ cần băm chữ cái từ chỉ số [r-1] (r là số dư), nếu không hãy gọi hàm từ num = (q-1) và thêm ở phía trước vào chỉ mục chữ cái [r-1].

4. Nếu số dư khác 0, hãy gọi hàm cho num = (q) và thêm ở phía trước vào chỉ mục chữ cái [r-1].

Dưới đây là code mẫu để các bạn tham khảo:

# Or you can simply take a string and perform this logic ,no issue i found in here.
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
# defined a recursive function here.
# if number is less than "26", simply hash out (index-1)
# There are sub possibilities in possibilities,
# 1.if remainder is zero(if quotient is 1 or not 1) and
# 2. if remainder is not zero
 
def num_hash(num):
    if num < 26:
        return alpha[num-1]
    else:
        q, r = num//26, num % 26
        if r == 0:
            if q == 1:
                return alpha[r-1]
            else:
                return num_hash(q-1) + alpha[r-1]
        else:
            return num_hash(q) + alpha[r-1]
 
 
# Calling the function out here and printing the ALphabets
# This code is robust ,work for any positive integer only.
# You can try as much as you want
print(num_hash(26))
print(num_hash(51))
print(num_hash(52))
print(num_hash(80))
print(num_hash(676))
print(num_hash(702))
print(num_hash(705))

Kết quả trả về là:

Z
AY
AZ
CB
YZ
ZZ
AAC

Quản Trị Mạng mong rằng bài viết này sẽ có ích đối với các bạn.

Thứ Năm, 24/11/2022 15:40
53 👨 344
0 Bình luận
Sắp xếp theo
    ❖ Học Python