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:

  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;

}




原文地址:https://www.cnblogs.com/simplepaul/p/7747894.html