LeetCode :【Easy】500. Keyboard Row

来源:互联网 发布:淘宝无线端是什么意思 编辑:程序博客网 时间:2024/05/17 06:18

Given a List of words, return the words that can be typed using letters of alphabet on only one row’s of American keyboard like the image below.
Input: [“Hello”, “Alaska”, “Dad”, “Peace”]
Output: [“Alaska”, “Dad”]

- My train of thought:

一开始想就要用三个数组把三行字母存进去(除了数组真是什么都不会),然后就复习了一下字符数组的相关知识,感觉因为基础语法都忘光了,所以遇到不少问题,下面一句一句地分析我的解法吧。

vector<string> words;words.push_back("Hello");words.push_back("Alaska");   words.push_back("Dad");words.push_back("Peace");

首先遇到的第一个问题是C++容器vector的问题,这里的words是一个string类型的容器
words.push_back() //向尾部添加元素
words.pop_back() //删除最后一个元素
words.size() //读取容器大小
words.resize() //改变容器大小

for (vector<string>::iterator iter = words.begin(); iter != words.end(); ++iter)    {        cout<< *iter << endl;    }

容器的遍历有很多种方法,上面是容器特有的迭代器的方法,当然也可以用类似数组下标的方法进行遍历。

for(int i = 0 ; i < 10 ; i ++) /*下标遍历*/{      cout<< words[i] <<endl ;   } 

接下来就是要按照我的既定思路,把每一行的字母按照大小写都存到一个数组里,这里在编译的时候遇到了一些麻烦,先看一下我一开始错误的写法:

char first[]={"Q","q","W","w","E","e","R","r","T","t","Y","y","U","u","I","i","O","o","P","p"};

这样写编译不通过,报错:初始化太多,我由于太渣,不明白什么叫初始化太多,百度半天才明白,是char []存的是一串字符串,比如char a[]=”012345”,虽然没有指明字符串的长度,但是此时系统已经开好了,就是大小为6—–‘0’ ‘1’ ‘2’ ‘3’ ‘4’ ‘5’ ‘\0‘;所以说我的初始化方法完全没脑子hhh

字符数组赋值后会自动在末尾加\0,所以定义数组最小长度长度需要比赋值长度大一,\0’是c/c++语言中的字符串结束符,在ASCII字符集中对应空字符NULL

字符数组有专门的的获取字符串实际长度的函数:strlen(a),该函数求得的是\0之前的字符个数。
另外插一句,看书的时候注意到,字符其实是一种特殊的整数,在ASCII编码表中,每一个字符都有一个整数编码,比如常用的应该要记住的,A-65,a-97,可以直接当整数用,比如int m=’a’-‘A’; m=32。

char *a 与char a[] 的区别

char *a = “hello” 中的a是指向第一个字符‘a’的一个指针
char a[20] = “hello” 中数组名a也是执行数组第一个字符‘h’的指针

但二者并不相同

char *m="777";char s[10]="hello";stract(m,s);

我们使用stract(a,b)(strcat(a,b)是把字符串a的结尾和字符串b的开始相连并存储于字符串a中)分别实现m+s和s+m
发现s+m是没问题的,因为数组是存放在中,是可以修改的。
而m+s就会报错,因为*m存放在常量区,是无法修改的。
所以,char *m只可以通过指针访问,无法修改。

回到之前的问题,其实

char * first[]={"Q","q","W","w","E","e","R","r","T","t","Y","y","U","u","I","i","O","o","P","p"};

也可以编译通过,char *first[]就是一个指针数组,可以存多个字符串。
差不多了,看一下我完整的很蠢的解法吧

- My Solution

class Solution {public:    vector<string> findWords(vector<string>& words) {    string tmp,a,b,c,d;    int num[20000];         vector<string> output;    char first[21]="QWERTYUIOPqwertyuiop";    char second[21]="ASDFGHJKLasdfghjkl";    char third[21]="ZXCVBNMzxcvbnm";    int count=words.size();    for(int i=0;i<count;i++)    {        tmp=words[i];        for(int j=0;j<tmp.size();j++)        {            for(int k=0;k<20;k++)            {                a=tmp[j];                b=first[k];                c=second[k];                d=third[k];                if(a==b)                    num[j]=1;                if(a==c)                    num[j]=2;                if(a==d)                    num[j]=3;            }        }        int m=0;        while(num[m]==num[0]&&m<tmp.size())            m++;        if(m==tmp.size())           output.push_back(tmp);    }    return output;    }};

后面就是涉及到字符与字符相等的问题,只要==两边都是char或者string类型的字符,都是可以直接==的,当然也有一些比较函数,这里还是==最简单啦,其他的以后用到再说(又懒了)。

- Better Solution

class Solution {public:    vector<string> findWords(vector<string>& words) {        vector<int> dict(26);        vector<string> rows = {"QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM"};        for (int i = 0; i < rows.size(); i++) {            for (auto c : rows[i]) dict[c-'A'] = 1 << i;        }        vector<string> res;        for (auto w : words) {            int r = 7;            for (char c : w) {                r &= dict[toupper(c)-'A'];                if (r == 0) break;            }            if (r) res.push_back(w);        }        return res;    }};

其中auto是C++11的新特性,主要有两种用途:自动类型推断返回值占位

 /*自动帮助推导类型*/      auto a = 10;      auto c = 'A';      auto s("hello");  
 for (auto c : rows[i])

这句,c的值其实就是rows[i]的枚举,表示rows[i]里的每一个值,似乎很好用的样子。
总体来说这个解法很取巧,用位运算,其实也没有简单多少,就是看上去很炫吧hhh
对了,就是touppertolower函数转换大小写还是很好用的,下次注意使用一下。

0 0
原创粉丝点击