如何只匹配一次使用给定字符的单词

本文关键字:字符 单词 一次 | 更新日期: 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