link もっと前
   2016年 3月 31日 -
      2016年 3月 22日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

表計算ソフトの列名変換問題

昨日の hdk さんの日記(リンク)を見て、自分も挑戦してみました。

元ネタは 2011年のブログ(リンク)ですね。

列名を数字(atod)と数字を列名(dtoa)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int atod(char *str)
{
        int len = strlen(str);
        int r = 0;
        int i;

        for (i = 0; i < len; i++) {
                r *= 26;
                r += str[i] - 'A' + 1;
        }

        return r;
}

void dtoa(int r, char *buf)
{
        char tmp[256];
        int p = 0;
        int i, len;

        memset(tmp, 0, sizeof(tmp));
        r -= 1;
        while (r >= 0) {
                tmp[p] = 'A' + (r % 26);
                r = r / 26 - 1;
                p++;
        }

        len = strlen(tmp);
        for (i = 0; i < len; i++) {
                buf[len - i - 1] = tmp[i];
        }
}

int main(int argc, char *argv[])
{
        int dir = atoi(argv[1]);
        char *str = argv[2];
        int r;
        char buf[256];

        switch (dir) {
        case 0:
                r = atod(str);
                printf("%d\n", r);
                break;
        case 1:
                memset(buf, 0, strlen(buf));
                dtoa(atoi(str), buf);
                printf("'%s'\n", buf);
                break;
        }

        return 0;
}

掛かった時間は正確に計ってないですが、atod の方が 10分くらいで、dtoa の方が 1時間くらいだったと思います。

2文字目以降を求める式(r = r / 26 - 1)を思いつくのに、予想以上に時間が掛かりました。

動作チェック
$ for i in `seq 1 100` `seq 650 750` `seq 17550 17650`; do echo $i `./a.out 1 $i`; done | egrep "[ABYZ]'"
1 'A'
2 'B'
25 'Y'
26 'Z'
27 'AA'
28 'AB'
51 'AY'
52 'AZ'
53 'BA'
54 'BB'
77 'BY'
78 'BZ'
79 'CA'
80 'CB'
650 'XZ'
651 'YA'
652 'YB'
675 'YY'
676 'YZ'
677 'ZA'
678 'ZB'
701 'ZY'
702 'ZZ'
703 'AAA'
704 'AAB'
727 'AAY'
728 'AAZ'
729 'ABA'
730 'ABB'
17550 'YXZ'
17551 'YYA'
17552 'YYB'
17575 'YYY'
17576 'YYZ'
17577 'YZA'
17578 'YZB'
17601 'YZY'
17602 'YZZ'
17603 'ZAA'
17604 'ZAB'
17627 'ZAY'
17628 'ZAZ'
17629 'ZBA'
17630 'ZBB'

二桁目が A になるとき、二桁目が Z になるとき、三桁目が A になるとき、三桁目が Z になるとき、いずれも特におかしくならないので、他の桁数でもたぶん大丈夫でしょう。

[編集者: すずき]
[更新: 2016年 3月 31日 00:12]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2016年 3月 31日 -
      2016年 3月 22日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 7/4 00:29

カレンダー

<2016>
<<<03>>>
--12345
6789101112
13141516171819
20212223242526
2728293031--

最近のコメント 5件

  • link 14年10月26日
    すずき 「コメントありがとうございます。お役に立て...」
    (更新:07/02 11:40)
  • link 14年10月26日
    通りすがり 「当方外付けサウンドカードorDACの購入...」
    (更新:07/02 02:41)
  • link 17年06月17日
    すずき 「>hdk さん\nApache と cr...」
    (更新:06/18 14:22)
  • link 17年06月17日
    hdk 「Exim は知りませんでしたが conf...」
    (更新:06/18 06:03)
  • link 17年05月03日
    すずき 「>hdk さん\nあー、そうか。やっと言...」
    (更新:05/08 22:55)

最近の記事 3件

link もっとみる
  • link 17年07月03日
    すずき 「[仮想アドレスから物理アドレスへ] ちょっと用事があって、ユーザプ...」
    (更新:07/04 00:29)
  • link 17年07月02日
    すずき 「[いまさら Cocos2d-x を触ってみる その 2] 先日(2...」
    (更新:07/03 01:23)
  • link 17年06月30日
    すずき 「[いまさら Cocos2d-x を触ってみる] そういえばゲームを...」
    (更新:07/02 22:40)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報