yup
Lv 5
yup 發問時間: 電腦與網際網路程式設計 · 1 0 年前

徵求優雅的演算法,不限程式語言。

設計一個method,輸入1個int,輸出1個string。

滿足以下的條件

0->"A",1->"B",.......................,25->"Z"

26->"AA",27->"AB",.............,51->"AZ"

52->"BA",53->"BB"...............,77->"BZ"

702->"AAA",728->"ABA"

已更新項目:

To:9527

不好意思,可能是我表達的不清楚。"ABA"是retrun值。也就是說可能要用char[]或是string把字母串接起來。

也就是說可能是需要一個像char[] decode(int val)或string decode(int val)的method。

在此非常感覺你的解答。

2 個已更新項目:

public string IndexToLabel(int index)

{

return GetLabel("", index);

}

3 個已更新項目:

string GetLabel(string label, int index)

{

label = Convert.ToChar('A' + index % 26).ToString() + label;

if (index / 26 == 0)

{ return label; }

else

{ return GetLabel(label, index / 26 - 1); }

}

4 個已更新項目:

依各位的解答及自己的淺見所歸納的邏輯為:

Label的最右邊一個字母在此稱為個位數。

個位數:

0,1,2~25

A,B,C~Z

個位數以外:

1,2,3~26

A,B,C~Z

5 個已更新項目:

To:忘記人

改寫你的程式。得到了一個Method

public String NumToString(int val)

{

StringBuffer sb = new StringBuffer();

do {

sb.insert(0, (char)((val%26+65) - (sb.length() > 0 ? 1 : 0)));

}

while ((val /= 26) > 0);

return sb.toString();

}

6 個已更新項目:

To:忘記人

Method沒辦法通過測試喔!

Method會發生676->"A@A"

7 個已更新項目:

To:9527

Method無法通過測試

676->"A@A"

8 個已更新項目:

public string IndexToLabel(int index)

string GetLabel(string label, int index)

這2個Method是我自己寫的

通過測試沒問題

不過我覺得有點髒,不甚優雅

9 個已更新項目:

To:TC9876

Python我是第一次接觸到。

我建制了Python的環境。

也幫您的程式作了UnitTest。

有通過測試。

在此想請教一下。您用了遞迴還有全域變數嗎?

10 個已更新項目:

To:耗呆小綿羊

您的程式無法通過測試。

676->"A@A"

1352->"B@A"

5 個解答

評分
  • 1 0 年前
    最佳解答

    以下是Python程式。請注意 indentations 被自動移除了,請自行加入;indentations 在 python 程式裡不可忽略。

    import string

    base = list(string.uppercase)

    def _indices(idx):

    div, mod = divmod(idx, 26)

    while True:

    yield base[mod]

    if div == 0:

    break

    div, mod = divmod(div, 26)

    mod -= 1

    def alpha(idx):

    l = list(_indices(idx))

    l.reverse()

    return ''.join(l)

    print [alpha(i) for i in (0, 25, 26, 51, 52, 77, 702, 728)]

    2007-09-28 22:53:11 補充:

    `base` 是定義在module scope 的 global,所以 `_indices` 可以直接使用。請參照

    a. "Naming and Binding" http://docs.python.org/ref/naming.html

    b. "Python Scopes and Name Spaces": http://docs.python.org/tut/node11.html#SECTION0011...

    2007-09-28 22:53:51 補充:

    Function `_indices(idx)` 在此使用的是 "generator" 語法 (keyword: yield)。請參照

    a. "Generators" http://docs.python.org/tut/node11.html#SECTION0011...

    2007-09-28 22:54:11 補充:

    並參照

    "Dive into Python" http://www.diveintopython.org/dynamic_functions/st...

    http://www.woodpecker.org.cn/diveintopython/dynami...

    2007-09-29 01:25:45 補充:

    !!!!!!!

    對不起,程式有錯,忽略了邊際問題,請在

    mod -= 1

    之前加上

    if mod == 0: div -= 1

  • 1 0 年前

    To yup:

    個人在最近和 Jacob大討論了你所提迴文質數的問題,

    歷經一大串的意見溝通後,總認為你非常的「自私」!

    是個不值得與之討論問題的人!

    至於本例的問題,你不用明知故問!

    我可以用 5 行短短的程式碼便搞定這個函式(已實作驗證),

    但實在找不出一個可以令人爽快的理由提供給你!

    記住:以後不要太自私!

  • yup
    Lv 5
    1 0 年前

    To looping:

    我並不以為自己的想法是最好的。

    相信人外有人

    還是感謝指教

  • ?
    Lv 4
    1 0 年前

    偶然間看到這問題

    這整串討論 在下並無高見 不過依在下看來

    yup大只不過是明知故問罷了 想必你心中已經有解

    何必煞費眾人的時間 您說是不是呀

  • 您覺得這個回答如何?您可以登入為回答投票。
  • 1 0 年前

    嗯..下面是我寫的, 以JAVA語言完成, 沒有使用一個像char[] decode(int val)或string decode(int val)的method。不知是否有符合題意

    import java.util.Scanner;

    public class NumberToWord {

    public static void main(String[] args) {

    Scanner scan = new Scanner(System.in);

    System.out.print("請輸入整數值 : ");

    int val = scan.nextInt();

    StringBuffer sb = new StringBuffer();

    do {

    sb.insert(0, (char)((val%26+65) - (sb.length() > 0 ? 1 : 0)));

    }

    while ((val /= 26) > 0);

    System.out.println("轉換成文字表示 : " + sb.toString());

    }

    }

    2007-09-28 12:16:36 補充:

    嗯..調整了一下以符合題意 : 使用一個像 String decode(int val)的method。

    private static String decode(int val) {

    StringBuffer sb = new StringBuffer();

    boolean hasNext = false;

    do {

    sb.insert(0, (char) (val % 26 + 65 - (hasNext ? 1 : 0)));

    hasNext = (val /= 26) > 0;

    } while (hasNext);

    return sb.toString();

    }

    2007-09-28 12:26:51 補充:

    呵呵..因為我掛網開著這一頁, 想到就回, 抱歉沒看到你已經將演算部份修改成方法了

    意思差不多了, 只是個人覺得在迴圈裡使用 sb.length() > 0 做為判斷式而捨棄 (val /= 26) > 0 不用, 感覺有點笨, 所以就自行修改了.

    2007-09-28 13:40:23 補充:

    嗯..題目不是單純的26進位表示法, 所以發生了邏輯錯誤

    重新參考規則

    個位數:0,1,2~25 A,B,C~Z

    個位數以外:1,2,3~26 A,B,C~Z

    2007-09-28 13:40:44 補充:

    private static String decode(int val) {

    StringBuffer sb = new StringBuffer();

    //處理個位數

    sb.insert(0, (char) (val % 26 + 65));

    //個位數以外

    while ((val /= 26) > 0) {

    int modVal = val % 26;

    if (modVal == 0) modVal = 26;

    sb.insert(0, (char) (modVal + 64));

    }

    return sb.toString();

    }

    但這樣寫好像就不優雅了...呵呵...再研究研究

    2007-09-28 14:30:50 補充:

    private static String decode(int val) {

    StringBuffer sb = new StringBuffer();

    boolean hasNext = false;

    do {

    int modVal = val % 26;

    sb.insert(0, (char) (hasNext ? ((modVal == 0 ? 26 : modVal) + 64) : (modVal + 65)));

    hasNext = (val /= 26) > 0;

    }

    while (hasNext);

    return sb.toString();

    }

    嗯..程式碼是縮短了, 反倒是可讀性大打折扣

    2007-09-29 10:07:55 補充:

    to:9527

    疑....我測我的程式的結果是

    676 <--- AZA

    677 <--- AZB

    1352 <--- BZA

    1353 <--- BZB

    17576 <--- AZZA

    27723 <--- AOZH

    31000 <--- ASVI

    456976 <--- AZZZA

    就 1352 而言, 其除以 26 的餘數分別為 0,0,2 所以算得編碼應為 BZA

    2007-09-29 11:23:59 補充:

    阿!!!

    懂了.....

    感謝 9527 提醒....

    我還是犯了邏輯錯誤....

    2007-09-29 11:51:24 補充:

    感謝 9527 提醒, 修正程式如下

    public static String index2Label(int index) {

    StringBuffer sb = new StringBuffer();

    do {

    sb.insert(0, (char)(index %26 + 65));

    index /= 26;

    }while(index-- > 0);

    return sb.toString();

    }

    676 <--- ZA

    677 <--- ZB

    1000 <--- ALM

    1352 <--- AZA

    1353 <--- AZB

    3456 <--- EBY

    12345 <--- RFV

    14444 <--- UIO

    2007-10-01 10:43:58 補充:

    嗯..還可以改成這樣..

    public static String number2String(int index) {

    StringBuffer sb = new StringBuffer();

    do {

    sb.insert(0, (char)((sb.length() > 0 ? --index : index) %26 + 65));

    }while((index /= 26) > 0);

    return sb.toString();

    }

    不過這也只是把程式碼縮短而已, 了無新意

    2007-10-01 13:15:59 補充:

    嗯...覺得在編解演算法裡, 不管是 +65 還是 +'A' 都有點 Hard Code 的味道, 應該要被提煉出來...

    不然一旦編碼範圍擴大( 如 A-Z 改 0-9A-Za-z), 編解碼的 method 就又得改寫

    2007-10-01 13:20:54 補充:

    加一個數值對照編碼表

    private static char[] _CODE_MAPPING = new char[] {

    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

    如果編碼擴大改這裡就好, 要改成由外部檔案定義編碼也很方便

    2007-10-01 13:21:10 補充:

    public static String encode(int index) {

    StringBuffer sb = new StringBuffer();

    do {

    sb.insert(0, _CODE_MAPPING[(sb.length() > 0 ? --index : index) % _CODE_MAPPING.length]);

    }while((index /= _CODE_MAPPING.length) > 0);

    return sb.toString();

    }

    參考資料: me
還有問題?馬上發問,尋求解答。