如何只匹配一次使用给定字符的单词
本文关键字:字符 单词 一次 | 更新日期: 2023-09-27 17:50:33
我试图找到一个正则表达式模式来匹配一个单词与一些给定的字符。但是每个字符只能使用一次。例如,如果我给"yrarbil"(库向后),它应该匹配这些:
- 图书馆
- rar 自由
- rarlib
但是它不应该匹配下面的
- 库("y"被使用的次数多于给定的次数)
- 库("i"的使用次数比给定的多,而且"es"根本没有给出)
我已经到处搜索了,但我能找到的最好的是匹配一个单词的代码,但相同的字符使用的次数超过了给定的次数。谢谢你。
p。S:如果这不能在正则表达式中完成(正如你所看到的,我是一个新手),那么用编程方式匹配这样一个单词的最佳方法是什么?
"library"是令人困惑的,因为它有两个字母r。但从我的观点来看,它是可以解决的。
轻松创建一个map<char, int>
,它将存储模式中每个字符的计数。然后,我们将生成一个map<char, int>
用于单词检查,它也将包含每个字符的计数,然后迭代映射,如果任何字符的计数比它不匹配的模式映射中的相同字符的计数多,如果它根本没有找到,那么它也不匹配。
按要求用c#编写代码使用系统;使用System.Collections.Generic;使用来;使用text;使用System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static bool Match(string pattern, string toMatch)
{
Dictionary<char, int> patternMap = new Dictionary<char, int>();
Dictionary<char, int> toMatchMap = new Dictionary<char, int>();
foreach (char ch in pattern)
{
if (patternMap.ContainsKey(ch))
++patternMap[ch];
else
patternMap[ch] = 1;
}
foreach (char ch in toMatch)
{
if (toMatchMap.ContainsKey(ch))
++toMatchMap[ch];
else
toMatchMap[ch] = 1;
}
foreach (var item in toMatchMap)
{
if (!patternMap.ContainsKey(item.Key) || patternMap[item.Key] < item.Value)
return false;
}
return true;
}
static void Main(string[] args)
{
string pattern = "library";
string[] test = { "lib", "rarlib", "rarrlib", "ll" };
foreach (var item in test)
{
if(Match(pattern, item))
Console.WriteLine("Match item : {0}", item);
else
Console.WriteLine("Failed item : {0}", item);
}
Console.ReadKey();
/*
Match item : lib
Match item : rarlib
Failed item : rarrlib
Failed item : ll
*/
}
}
}
一个正则表达式将不起作用。一个解决方案是简单地计算列表中的字符。
例如在JavaScript中:
function count(str){
return str.split('').reduce(function(m,c){
m[c] = (m[c]||0)+1;
return m;
},{})
}
function check(str, reference){
var ms = count(str), mr = count(reference);
for (var k in ms) {
if (!(ms[k]<=mr[k])) return false;
}
return true;
}
// what follows is only for demonstration in a snippet
$('button').click(function(){
$('#r').text(check($('#a').val(), "library") ? "OK":"NOT OK");
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id=a value="rarlib">
<button>CHECK</button>
<div id=r></div>
我不明白为什么当一个非常简单和直接的解决方案可用时,你要使用regexp来做这个。
你只需要计算每个字母在给定单词中出现的次数,在你测试的单词中。然后检查被测单词中的每个字母出现的次数不超过给定单词。
for ch in given_word
cnt[ch]++
for ch in test_word
cnt[ch]--
for ch='a'..'z'
if cnt[ch]<0
answer is no
if for all leters cnt[ch]>=0
answer is yes