Long Pressed Name

本文介绍了一种算法,用于判断给定的两个字符串中,第二个字符串是否可以通过第一个字符串的字符长按输入得到。通过使用双指针技巧,确保name中的字符频率不超过typed中的频率,从而实现对长按输入的有效判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Your friend is typing his name into a keyboard.  Sometimes, when typing a character c, the key might get long pressed, and the character will be typed 1 or more times.

You examine the typed characters of the keyboard.  Return True if it is possible that it was your friends name, with some characters (possibly none) being long pressed.

 

Example 1:

Input: name = "alex", typed = "aaleex"
Output: true
Explanation: 'a' and 'e' in 'alex' were long pressed.

Example 2:

Input: name = "saeed", typed = "ssaaedd"
Output: false
Explanation: 'e' must have been pressed twice, but it wasn't in the typed output.

Example 3:

Input: name = "leelee", typed = "lleeelee"
Output: true

思路:双指针,这里比较巧妙的是,用了count,也就是说,name里面的char频率必须小于typed里面的频率。最后记得i,j都必须同时到达最后的length;

class Solution {
    public boolean isLongPressedName(String name, String typed) {
        int i = 0, j = 0;
        while (i < name.length()) {
            if (j == typed.length() || name.charAt(i) != typed.charAt(j)) {
                return false;
            }
            int count = 0;
            while (i < name.length() - 1 && name.charAt(i) == name.charAt(i + 1)) {
                i++;
                count++;
            }
            while (j < typed.length() - 1 && typed.charAt(j) == typed.charAt(j + 1)) {
                j++;
                count--;
            }
            if (count > 0) {
                return false;
            }
            i++;
            j++;
        }
        return i == name.length() && j == typed.length();
    }
}

 

好的,以下是一个使用状态机方式运行的,能够识别5个独立按键并且能够识别双按键同时按下、长按、短按、单按键双击、单按键长按的程序。这个程序使用了STM32G030为硬件平台,使用了HAL库进行编程。 ```c #include "stm32g0xx_hal.h" #include <stdbool.h> // 定义按键名称 #define KEY_UP 0x01 #define KEY_DOWN 0x02 #define KEY_LEFT 0x04 #define KEY_RIGHT 0x08 #define KEY_CENTER 0x10 // 定义按键状态 typedef enum { KEY_RELEASED = 0, // 按键释放状态 KEY_PRESSED = 1 // 按键按下状态 } KeyState; // 定义按键信息结构体 typedef struct { GPIO_TypeDef* port; // GPIO端口 uint16_t pin; // GPIO引脚 bool inverted; // 是否反相 KeyState state; // 按键状态 uint32_t time; // 按键按下的时间 uint8_t name; // 按键名称 } KeyInfo; // 初始化按键 void KeyInit(KeyInfo* key, GPIO_TypeDef* port, uint16_t pin, bool inverted, uint8_t name) { key->port = port; key->pin = pin; key->inverted = inverted; key->state = KEY_RELEASED; key->time = 0; key->name = name; GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(port, &GPIO_InitStruct); } // 获取按键状态 KeyState GetKeyState(KeyInfo* key) { bool isPressed = HAL_GPIO_ReadPin(key->port, key->pin) ^ key->inverted; if (isPressed && (key->state == KEY_RELEASED)) { key->state = KEY_PRESSED; key->time = HAL_GetTick(); } else if (!isPressed && (key->state == KEY_PRESSED)) { key->state = KEY_RELEASED; } return key->state; } // 判断是否为长按事件 bool IsLongPress(KeyInfo* key) { if (GetKeyState(key) == KEY_PRESSED) { uint32_t timeDiff = HAL_GetTick() - key->time; if (timeDiff >= 1000) { return true; } } return false; } // 判断是否为短按事件 bool IsShortPress(KeyInfo* key) { if (GetKeyState(key) == KEY_RELEASED) { uint32_t timeDiff = HAL_GetTick() - key->time; if (timeDiff < 1000) { return true; } } return false; } // 判断是否为双击事件 bool IsDoubleClick(KeyInfo* key) { if (GetKeyState(key) == KEY_RELEASED) { uint32_t timeDiff = HAL_GetTick() - key->time; if ((timeDiff > 100) && (timeDiff < 300)) { return true; } } return false; } // 判断是否为双键同时按下事件 bool IsKeyCombination(KeyInfo* key1, KeyInfo* key2) { if ((GetKeyState(key1) == KEY_PRESSED) && (GetKeyState(key2) == KEY_PRESSED)) { return true; } return false; } int main(void) { // 初始化GPIO HAL_Init(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); // 初始化按键 KeyInfo key_up, key_down, key_left, key_right, key_center; KeyInit(&key_up, GPIOA, GPIO_PIN_0, false, KEY_UP); KeyInit(&key_down, GPIOA, GPIO_PIN_1, false, KEY_DOWN); KeyInit(&key_left, GPIOA, GPIO_PIN_2, false, KEY_LEFT); KeyInit(&key_right, GPIOA, GPIO_PIN_3, false, KEY_RIGHT); KeyInit(&key_center, GPIOB, GPIO_PIN_4, false, KEY_CENTER); // 进入状态机 KeyState state = KEY_RELEASED; uint8_t curKey = 0, prevKey = 0; uint32_t curTime = 0, prevTime = 0; while (1) { switch (state) { case KEY_RELEASED: if (IsKeyCombination(&key_up, &key_down)) { state = KEY_UP_DOWN; } else if (IsKeyCombination(&key_left, &key_right)) { state = KEY_LEFT_RIGHT; } else if (IsLongPress(&key_center)) { state = KEY_CENTER_LONG; } else if (IsShortPress(&key_center)) { state = KEY_CENTER_SHORT; } else if (IsDoubleClick(&key_center)) { state = KEY_CENTER_DOUBLE; } else if (GetKeyState(&key_up) == KEY_PRESSED) { state = KEY_UP; } else if (GetKeyState(&key_down) == KEY_PRESSED) { state = KEY_DOWN; } else if (GetKeyState(&key_left) == KEY_PRESSED) { state = KEY_LEFT; } else if (GetKeyState(&key_right) == KEY_PRESSED) { state = KEY_RIGHT; } break; case KEY_UP: curKey = KEY_UP; curTime = HAL_GetTick(); if (IsShortPress(&key_up)) { printf("Key Up Short Pressed\n"); state = KEY_RELEASED; } else if (IsLongPress(&key_up)) { printf("Key Up Long Pressed\n"); state = KEY_RELEASED; } else if (IsDoubleClick(&key_up)) { printf("Key Up Double Clicked\n"); state = KEY_RELEASED; } break; case KEY_DOWN: curKey = KEY_DOWN; curTime = HAL_GetTick(); if (IsShortPress(&key_down)) { printf("Key Down Short Pressed\n"); state = KEY_RELEASED; } else if (IsLongPress(&key_down)) { printf("Key Down Long Pressed\n"); state = KEY_RELEASED; } else if (IsDoubleClick(&key_down)) { printf("Key Down Double Clicked\n"); state = KEY_RELEASED; } break; case KEY_LEFT: curKey = KEY_LEFT; curTime = HAL_GetTick(); if (IsShortPress(&key_left)) { printf("Key Left Short Pressed\n"); state = KEY_RELEASED; } else if (IsLongPress(&key_left)) { printf("Key Left Long Pressed\n"); state = KEY_RELEASED; } else if (IsDoubleClick(&key_left)) { printf("Key Left Double Clicked\n"); state = KEY_RELEASED; } break; case KEY_RIGHT: curKey = KEY_RIGHT; curTime = HAL_GetTick(); if (IsShortPress(&key_right)) { printf("Key Right Short Pressed\n"); state = KEY_RELEASED; } else if (IsLongPress(&key_right)) { printf("Key Right Long Pressed\n"); state = KEY_RELEASED; } else if (IsDoubleClick(&key_right)) { printf("Key Right Double Clicked\n"); state = KEY_RELEASED; } break; case KEY_CENTER_SHORT: printf("Key Center Short Pressed\n"); state = KEY_RELEASED; break; case KEY_CENTER_LONG: printf("Key Center Long Pressed\n"); state = KEY_RELEASED; break; case KEY_CENTER_DOUBLE: printf("Key Center Double Clicked\n"); state = KEY_RELEASED; break; case KEY_UP_DOWN: printf("Key Up and Down Pressed\n"); state = KEY_RELEASED; break; case KEY_LEFT_RIGHT: printf("Key Left and Right Pressed\n"); state = KEY_RELEASED; break; } // 判断单按键双击 if ((curKey != 0) && (curKey == prevKey)) { uint32_t timeDiff = curTime - prevTime; if ((timeDiff > 100) && (timeDiff < 300)) { printf("Key %d Double Clicked\n", curKey); curKey = 0; } } // 记录上一个按下的按键和时间 if (curKey != 0) { prevKey = curKey; prevTime = curTime; } } } ``` 在这个程序中,我们首先定义了按键名称以及按键状态枚举类型。然后我们定义了包含按键信息的结构体`KeyInfo`,包含GPIO端口、引脚、状态、按下时间以及按键名称等信息。接着我们定义了一些函数,包括初始化按键、获取按键状态、判断是否为长按事件、短按事件、双击事件以及双键同时按下事件等。最后我们通过状态机的方式来处理按键事件,包括单按键短按、长按、双击事件以及双键同时按下事件等。同时我们还记录了上一个按下的按键以及时间,以便判断单按键双击事件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值