500. Keyboard Row(c++)及c++ set应用

目录

方法一

解法

知识点

方法二

解法

方法三

解法

知识点



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中的任一字符

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值