1. 程式人生 > >423. Reconstruct Original Digits from English(Medium)

423. Reconstruct Original Digits from English(Medium)

length ini sce lis fur size ica 必須 間接

Given a non-empty string containing an out-of-order English representation of digits 0-9, output the digits in ascending order.

Note:

  1. Input contains only lowercase English letters.
  2. Input is guaranteed to be valid and can be transformed to its original digits. That means invalid inputs such as "abc" or "zerone" are not permitted.
  3. Input length is less than 50,000.

Example 1:

Input: "owoztneoer"

Output: "012"

Example 2:

Input: "fviefuro"

Output: "45"


這道題給了我們一串英文字符串,是由表示數字的英文單詞組成的,不過字符順序是打亂的,讓我們重建出數字。那麽這道題的思路是先要統計出各個字符出現的次數,然後算出每個單詞
出現的次數,然後就可以重建了。由於題目中限定了輸入的字符串一定是有效的,那麽不會出現無法成功重建的情況,這裏需要用個trick。我們仔細觀察這些表示數字的單詞"zero",
"one", "two", "three", "four", "five", "six", "seven", "eight", "nine",我們可以發現有些的單詞的字符是獨一無二的,比如z,只出現在zero中,還有w,u,x,g這
四個單詞,分別只出現在two,four,six,eight中,那麽這五個數字的個數就可以被確定了,由於含有o的單詞有zero,two,four,one,其中前三個都被確定了,那麽one的個數也就知道了;
由於含有h的單詞有eight,three,其中eight個數已知,那麽three的個數就知道了;由於含有f的單詞有four,five,其中four個數已知,那麽five的個數就知道了;由於含有s的單詞有six,seven,
其中six個數已知,那麽seven的個數就知道了;由於含有i的單詞有six,eight,five,nine,其中前三個都被確定了,那麽nine的個數就知道了,知道了這些問題就變的容易多了,我們按這個
順序"zero", "two", "four", "six", "eight", "one", "three", "five", "seven", "nine"就能找出所有的個數了,參見代碼如下:

/*  首先進行一下分析過程
           代表字符      可能出現在的數字
zero  ->      z                0      
one   ->      o                0, 1, 2, 4
two   ->      w                2
three ->      r                3, 4,0
four  ->      u                4
five  ->      f                4, 5
six   ->      x                6
seven ->      s                6, 7
eight ->      g                8
nine  ->      i                5, 6, 8, 9


*/ class Solution { public: string originalDigits(string s) { int* digit = new int [10](); // 註意後邊的括號,是全部初始化為0,如果不初始化的話,會有問題,??? string res; for (int i = 0; i < s.size(); i++){ char c = s[i]; if (c == z) digit[0]++; if (c == w) digit[2]++; if (c == u) digit[4]++; if (c == x) digit[6]++; if (c == g) digit[8]++; if (c == o) digit[1]++; if (c == r) digit[3]++; if (c == f) digit[5]++; if (c == s) digit[7]++; if (c == i) digit[9]++; } digit[1] = digit[1] - digit[0] - digit[2] - digit[4]; digit[3] = digit[3] - digit[4] - digit[0]; digit[5] = digit[5] - digit[4]; digit[7] = digit[7] - digit[6]; digit[9] = digit[9] - digit[5] -digit[6] - digit[8]; for (int i = 0; i <= 9; i++){ for (int j = 0; j < digit[i]; j++){ res.append(to_string(i)); } } return res; } };

註意的一個問題:

int *pia = new int[10]; // array of 10 uninitialized ints
new 表達式分配了一個含有 10 個 int 型元素的數組,並返回指向該數組第一個元素的指針,此返回值初始化了指針 pia

在自由存儲區中創建的數組對象是沒有名字的,只能通過其地址間接地訪問堆中的對象。

註意:C++使用new和delete在堆(自由存儲區)上分配和釋放動態數組。

動態數組初始化:

1.元素只能初始化為元素類型的默認值,而不能像數組變量一樣,用初始化列表為數組元素提供各不相同的初值。

2.對於內置數據類型元素的數組,必須使用()來顯示指定程序執行初始化操作,否則程序不執行初始化操作:

int *pia = new int[10]; // 每個元素都沒有初始化

int *pia2 = new int[10] (); // 每個元素初始化為0

3.類類型元素的數組,則無論是否使用(),都會自動調用其默認構造函數來初始化:

string *psa = new string[10]; // 每個元素調用默認構造函數初始化

// 每個元素調用默認構造函數初始化

動態分配空數組:

char *cp = new char[0];

之後,可以動態改變cp的維數。

動態釋放:

delete [] pia;

典型使用示例:

// 處理C風格字符串時使用const指針

const size_t len = strlen(pc) +1; // size_t用於數組的大小和下標

for (size_t ix = 0; ix != 1000000; ++ix) {

char *pc2 = new char[len]; // pc2指向的存儲空間的內容會動態改變,因此不使用const

strncpy (pc2, pc, len); // 使用strncpy比使用strcpy安全

// do something;

delete [] pc2;

}




423. Reconstruct Original Digits from English(Medium)