目录
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.
Example:
Input: ["Hello", "Alaska", "Dad", "Peace"]
Output: ["Alaska", "Dad"]
给出单词列表,查找出哪些单词包含的字母仅分布在美式键盘的一行中。
方法一
解法
将每行保存在set中
对每个单词,通过第一个字母确定是哪一行,假设为n
对从第二个开始的所有字母挨个确定是否在第n行
如果所有字母都在第n行,那么将该单词加入result里
这个方法比较笨,主要练习了vector和set的使用。
class Solution {
public:
vector<string> findWords(vector<string>& words) {
char alphabet1[] = {'z', 'x', 'c', 'v', 'b', 'n', 'm', 'Z', 'X', 'C', 'V', 'B', 'N', 'M'};
set<char> myset1(alphabet1, alphabet1 + 14);//set初始化
char alphabet2[] = {'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'};
set<char> myset2(alphabet2, alphabet2 + 18);
char alphabet3[] = {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'};
set<char> myset3(alphabet3, alphabet3 + 20);
string tempWord;
int symbol = 0;
vector<string> result;
for (vector<string>::iterator it = words.begin(); it != words.end(); ++it)//遍历vector
{
tempWord = *it;
if (tempWord.size() > 0)
{
if (myset1.find(tempWord[0]) != myset1.end())//set查找
symbol = 1;
else
{
if (myset2.find(tempWord[0]) != myset2.end())
symbol = 2;
else
symbol = 3;
}
}
for (int num = 1; num < tempWord.size();num++)
{
switch (symbol)
{
case 1:
if (myset1.find(tempWord[num]) != myset1.end())
continue;
else
{
symbol = 4;
break;
}
case 2:
if (myset2.find(tempWord[num]) != myset2.end()){
continue;
}
else
{
symbol = 4;
break;
}
case 3:
if (myset3.find(tempWord[num]) != myset3.end())
continue;
else
{
symbol = 4;
break;
}
default:
break;
}
}
if (symbol != 4)
result.push_back(tempWord);//vector 添加元素
}
for (vector<string>::iterator it = result.begin(); it != result.end(); ++it)
{
cout << *it<<endl;
}
return result;
}
};
知识点
在c++11里,有五种方法初始化set(集合)
(1)构造一个空的集合(默认构造器):构造一个空的集合,里面没有任何元素
例:
std::set<int> first;
(2) 序列构造器
从序列[开始,结束)构建集合,集合中每个元素来源于序列中的对应元素。
例:
int myints[]= {10,20,30,40,50};
std::set<int> second (myints,myints+5);//其中5表示拷贝前5个元素到set中
(3) 拷贝构造器(and copying with allocator)
拷贝X(类型一样的set)中的每个元素,构建一个set。
std::set<int> third (second);//拷贝上面创建的set second创建新的set third。
(4) 移动构造器 (and moving with allocator)
创建一个容器,获取x(类型一样的set)中的元素。如果该容器的分配器已经指定且不同于x的分配器,元素会移动。否则,不构建元素(它们的ownership直接转移)。x在一种非指定但是有效的状态。
(5) 构造函数初始化列表
构造一个容器,拷贝il中的每个元素。il指初始化器列表。
方法二
用到了map
解法
#include "pch.h"
#include <iostream>
#include <map>
#include <vector>
#include <string>
using namespace std;
int main() {
vector<string> findWords(vector<string> & words);
vector<string> myVector;
myVector.push_back("Hello");
myVector.push_back("Alaska");
myVector.push_back("Dad");
myVector.push_back("Peace");
myVector.push_back("adfs");
findWords(myVector);
return 0;
}
vector<string> findWords(vector<string> &words)
{
string tempWord;
int row;
bool ifOneRow = true;
map<char, int> myMap;//map初始化
myMap['z'] = 1;
myMap['x'] = 1;
myMap['c'] = 1;
myMap['v'] = 1;
myMap['b'] = 1;
myMap['n'] = 1;
myMap['m'] = 1;
myMap['Z'] = 1;
myMap['X'] = 1;
myMap['C'] = 1;
myMap['V'] = 1;
myMap['B'] = 1;
myMap['N'] = 1;
myMap['M'] = 1;
myMap['a'] = 2;
myMap['s'] = 2;
myMap['d'] = 2;
myMap['f'] = 2;
myMap['g'] = 2;
myMap['h'] = 2;
myMap['j'] = 2;
myMap['k'] = 2;
myMap['l'] = 2;
myMap['A'] = 2;
myMap['S'] = 2;
myMap['D'] = 2;
myMap['F'] = 2;
myMap['G'] = 2;
myMap['H'] = 2;
myMap['J'] = 2;
myMap['K'] = 2;
myMap['L'] = 2;
myMap['q'] = 3;
myMap['w'] = 3;
myMap['e'] = 3;
myMap['r'] = 3;
myMap['t'] = 3;
myMap['y'] = 3;
myMap['u'] = 3;
myMap['i'] = 3;
myMap['o'] = 3;
myMap['p'] = 3;
myMap['Q'] = 3;
myMap['W'] = 3;
myMap['E'] = 3;
myMap['R'] = 3;
myMap['T'] = 3;
myMap['Y'] = 3;
myMap['U'] = 3;
myMap['I'] = 3;
myMap['O'] = 3;
myMap['P'] = 3;
for (vector<string>::iterator it = words.begin();it != words.end();) {
tempWord = *it;
ifOneRow = true;
if (tempWord.size() > 0)
row = myMap[tempWord[0]];
for (int num = 1;num < tempWord.size();num++) {
if (myMap[tempWord[num]] != row) {
ifOneRow = false;
break;
}
}
if (!ifOneRow)
it=words.erase(it);//vector删除
else
it++;
}
return words;
}
方法三
解法
public String[] findWords(String[] words) {
return Stream.of(words).filter(s -> s.toLowerCase().matches("[qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*")).toArray(String[]::new);
}
知识点
用到了java中的stream。如下的博客里详细讲解了stream的用法
https://www.cnblogs.com/andywithu/p/7404101.html
另外用到了正则表达式
x|y | 匹配 x 或 y。例如,'z|food' 匹配"z"或"food"。'(z|f)ood' 匹配"zood"或"food"。 |
因此[qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*是指匹配[qwertyuiop]*或[asdfghjkl]*或[zxcvbnm]*
[xyz] | 字符集。匹配包含的任一字符。例如,[abc]"匹配"plain"中的"a"。 |
因此[qwertyuiop]是指匹配qwertyuiop中的任一字符
* | 零次或多次匹配前面的字符或子表达式。例如,zo* 匹配"z"和"zoo"。* 等效于 {0,}。 |
因此[qwertyuiop]*是指零次或多次匹配qwertyuiop中的任一字符