2013-06-27 25 views
1

我正在使用Excel電子表格,而且我只能使用一種類型的公式來處理大量數據。由於在公式中唯一必要的修改涉及字母,所以我想知道是否有辦法讓一個程序按照Excel列順序(A,B,C ... Z; AA,AB,AC ... AZ; BA,BB,BC ... BZ)。如何增加超過'z'的C++中的字母組合?

以我爲例,我需要五,每次遞增字母,所以這裏的代碼我試圖獲得的那種:

#include <iostream> 

using namespace std; 

int main() { 

char x = 'B'; 
char y = 'E'; 
for (int z = 1; z < 2255; z++) { 
    cout << "=SUMPRODUCT(SUBTOTAL(4,OFFSET(" << x << "1:" << y << "1,ROW(" << x << "1:" << x << "100)-ROW(" << x << "1),)))" << endl; 
    x = x + 5; 
    y= y + 5; 
    } 
    return 0; 
} 

當然它不會工作,因爲它去'z',但仍然有辦法做到這一點?

回答

0

這樣做:

x = (x + 5 > 'Z' ? x + 5 - 'Z' + 'A' : x + 5); 
y = (y + 5 > 'Z' ? y + 5 - 'Z' + 'A' : y + 5); 
0

你能做到這一點在兩個嵌套的循環,無論是從'A''Z',然後只需兩個字符追加在一起。將結果放入向量中。

要獲得單字母'A''Z',請將它們添加到嵌套循環之前的向量中。

1

通用的解決方案描述

解決方案1:創建基礎-26系統本身:

假設你有26個字母。所以首先讓我們製作26個數字系統。我們每個數字使用1個字節。我們創建一組數字,然後當添加超過26時,我們有時需要調整。

假設您的當前數字是25.我們將7添加到它,然後我們需要處理溢出,假設256(1字節)作爲最大值,並且我們的數字限制爲26.因此,調整將爲256-26=230。 (我們在短(16位)上做這個計算,所以我們在26+7=33 -> 33+230=263上溢出,所以,高位字節將是1,低位字節將是7.)

計算出溢出閾值(高於1 ),然後我們可以將它添加到下一個數字中,並在發生溢出時執行相同操作。

最後,爲了顯示,我們只給兩個字節中的每一個添加65('A')。我們的最後一個字節將是'\ 0'null終止,所以我們可以把它變成一個字符串。

解決方案2執行所有的計算,然後將其轉換爲26-基數:

在這種情況下,

number/26 = x 

remainder r1 = (number%26) 

我們存儲R1到字節。

x/26 = x1 

remainder r2 = (x%26) 

我們店裏R2到下一個字節。

x1/26 = x2 

remainder r3 = (x%26) 

我們店裏R3到下一個字節。我們得到一個字符串r3 r2 r1 '\0',然後爲每個字節添加65'A'。

+0

爲什麼這種尷尬的格式?爲什麼要阻止普通文本的報價?我很樂意編輯這個,但我想知道這個格式背後是否有任何意圖。 – jogojapan

+0

這是你想要的格式嗎?如果沒有,只需將其回滾。 – jogojapan

+0

@jogojapan謝謝。現在看起來很正常 – qwr

0

你可以作爲一個選項,創建一個包含兩個字符(像std::pair<char,char>一個新的數據類型,並定義算術這一點。

不過,我認爲這將是更簡單的使用int(或unsigned int保持)爲計數和算術,和定義一個函數to_col_heading其轉化的整數成Excel中的一個/兩個字符的列標題:

#include <string> 
#include <iostream> 
#include <stdexcept> 
#include <iterator> 

/* This is the function that performs 
    the transformation. */  
std::string to_col_heading(unsigned i) 
{ 
    if (i > 26+26*26) 
    throw std::overflow_error 
     ("Value too large for transformation into Excel column heading."); 

    char char1 = 'A' + (i/26) - 1; 
    char char2 = 'A' + (i % 26); 

    if (char1 < 'A') 
    return std::string(&char2,&char2 + 1); 
    else 
    return std::string(&char1,&char1 + 1) + char2; 
} 

int main() 
{ 
    std::ostream_iterator<std::string> out(std::cout,", "); 
    for (unsigned i = 0 ; i < 26+26*26 ; i += 5) 
    *out = to_col_heading(i); 

    std::cout << std::endl; 
    return 0; 
} 

輸出:

A, F, K, P, U, Z, AE, AJ, AO, AT, AY, BD, BI, BN, BS, BX, CC, CH, CM, CR, CW, DB, DG, DL, DQ, DV, EA, EF, EK, EP, EU, EZ, FE, FJ, FO, FT, FY, GD, GI, GN, GS, GX, HC, HH, HM, HR, HW, IB, IG, IL, IQ, IV, JA, JF, JK, JP, JU, JZ, KE, KJ, KO, KT, KY, LD, LI, LN, LS, LX, MC, MH, MM, MR, MW, NB, NG, NL, NQ, NV, OA, OF, OK, OP, OU, OZ, PE, PJ, PO, PT, PY, QD, QI, QN, QS, QX, RC, RH, RM, RR, RW, SB, SG, SL, SQ, SV, TA, TF, TK, TP, TU, TZ, UE, UJ, UO, UT, UY, VD, VI, VN, VS, VX, WC, WH, WM, WR, WW, XB, XG, XL, XQ, XV, YA, YF, YK, YP, YU, YZ, ZE, ZJ, ZO, ZT, ZY, 

要支持最多3個(按字母順序)列標題的數字,下面的函數可以工作。它完全分開處理前26個值,以簡化其餘的計算。我還介紹了一些靜態常量,以更加一致的方式處理26的冪數。對於三位數字,您需要26 ,,和26 ,但是系統可以擴展到覆蓋任何數字的數字。

我確定有一種方法可以優化速度;這不是這裏的重點。

std::string to_col_heading(unsigned i) 
{ 
    const static unsigned pow1 = 26; 
    const static unsigned pow2 = 26*26; 
    const static unsigned max = pow1 + pow2 + 26 * pow2; 

    if (i < pow1) 
    { 
     char c = 'A' + i % pow1; 
     return std::string(&c,&c+1); 
    } 

    if (i > max) 
    throw std::overflow_error 
     ("Value too large for transformation into Excel column heading."); 

    i -= pow1; 
    char char1 = 'A' + (i/pow2) - 1; 
    char char2 = 'A' + (i%pow2)/pow1; 
    char char3 = 'A' + i % pow1; 

    if (char1 < 'A') 
    return std::string(&char2,&char2 + 1) + char3; 
    else 
    return std::string(&char1,&char1 + 1) + char2 + char3; 
} 
+0

謝謝你的回答。我需要3位數字,這是可能的這種方法? – user2499266

+0

因爲我有的最後一欄是在字母'PQL'下面。 – user2499266

+0

是的,當然。相同的邏輯可以擴展爲任意數量的字符。 – jogojapan

0

您試圖生成的結果可以視爲基數爲27的數字,使用字符'A'到'Z'作爲26位數。這是一個不尋常的,因爲'A'真的是'0',但是當你得到一個兩位數的數字,它是'AA',(正常的兩位數是BA - 即,像9之後的下一個數字是10)。我們必須做一個相當小的調整來彌補這種怪異。

您可以使用正常的int(或其他)進行計數,然後在需要時轉換爲基準值27。由於我認爲它不支持更多的列,所以我將此版本限制爲2位數,儘管延伸到更多將是相當無足輕重的:

std::string to_excel_column(int input) { 
    int digit1 = input % 26; 
    int digit2 = input/26; 

    std::string result; 
    if (input > 26) 
     result.push_back(digit2 + 'A' - 1); 
    result.push_back(digit1 + 'A'); 
    return result; 
} 
相關問題