423. Reconstruct Original Digits from English(Medium)
Given a non-empty string containing an out-of-order English representation of digits 0-9
, output the digits in ascending order.
Note:
- Input contains only lowercase English letters.
- 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.
- 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)