C++ 通配符字符串比较(空或全部字符)

C++ 通配符字符串比较(空或全部字符),c++,string,compare,wildcard,C++,String,Compare,Wildcard,我试图用C++编写一个函数,可以比较两个字符串s1和s2,其中s2只有'?'字符。 “?”字符表示匹配任何字符的能力, 包括空字符。例如,colo?r同时匹配“颜色”和“颜色”。 这 查询应该报告匹配的每个单词。其他例子: 你好,是吗 hello:h?l?o--true(两者都充当通配符) hllo:h?l?o——true(第一个?用作空,第二个?用作通配符) hlo:h??lo——真(两者都作为空) hello:h?lo--false(?字符只能替换一个字符,不能替换字符串) hello:h?

我试图用C++编写一个函数,可以比较两个字符串s1和s2,其中s2只有'?'字符。 “?”字符表示匹配任何字符的能力, 包括空字符。例如,colo?r同时匹配“颜色”和“颜色”。 这 查询应该报告匹配的每个单词。其他例子:

你好,是吗

hello:h?l?o--true(两者都充当通配符)

hllo:h?l?o——true(第一个?用作空,第二个?用作通配符)

hlo:h??lo——真(两者都作为空)

hello:h?lo--false(?字符只能替换一个字符,不能替换字符串)

hello:h???p--false(p与任何可能的字符选项都匹配)

我尝试使用许多使用循环的函数,但我只能处理所有“?”要么为空,要么为通配符的问题。当一个用作空字符串,另一个用作通配符时,会有太多不同的字符串需要比较,以至于事情失控

我的教授告诉我递归是解决这个问题的关键,但是我们还没有对递归进行太多的讨论。
请帮助我提供一些建议/代码,这些建议/代码可以使用回溯技术来解决此问题。

基本上,您可以使用通配符检查字符串(从现在起我将称之为字符串模式):

如果模式的第一个字符是字符,但是
,则尝试从输入字符串(另一个不带通配符的字符串)中完全使用该字符

如果模式的第一个字符是
,则有两种情况:

  • 应该匹配一个字符(为了匹配完整的模式),所以只需使用输入中的下一个字符,然后继续
  • 不应与字符匹配,在这种情况下,您将继续使用模式中的下一个字符,并保持输入字符串不变
  • 当然,您无法知道在这些情况中选择哪种情况。所以你需要回到那个点,以防你的猜测是错的

    为此,您可以使用递归(或者更准确地说:从递归调用中获得的局部变量等方面的新上下文):

    您只需首先使用剩余的模式和输入字符串调用匹配函数,如果失败,则使用剩余的模式和没有第一个字符的输入字符串调用匹配函数(从而使
    使用一个字符)

    例如:

    pattern: s?y
    input:   say
    
    模式的第一个字符是a
    s
    ,这是正常的非通配符匹配,因此查看此匹配的输入的第一个字符,继续:

    pattern: ?y
    input:   ay
    
    现在有一个通配符需要匹配,所以假设它没有使用任何字符,让我们看看这会让我们得到什么。使用以下命令调用匹配函数:

    pattern: y
    input:   ay
    
    哎哟,这不匹配(
    a!=y
    ),所以此时返回
    false
    。这使我们回到了我们调用匹配函数的地方(在上面的步骤中),留给我们的是:

    pattern: ?y
    input:   ay
    
    我们已经尝试将通配符作为非字符进行匹配,现在尝试将其作为任意字符进行匹配,从而使用
    a

    pattern: y
    input:   y
    
    哇,匹配,下一次运行时两个字符串都是空的,所以我们有一个匹配


    <>这似乎是作业,你可能需要在C++中实现。我不会给你那个密码。相反,我将用另一种语言——Clojure——为您提供一个实现,这将使您能够进一步理解上述算法

    (ns通配符)
    (:参见clojure))
    (defn-dpr)
    “使用穷人的索引调试打印”
    [图案与休息]
    (打印(重复(-6(计数模式))“”)
    (应用println rest)
    (定义通配符匹配[输入模式]
    (println“通配符匹配”输入模式)
    (如果(或(空输入)(空模式))
    一个为空,如果两个都为空,则返回true
    (和(空输入)(空模式))
    其他的
    (如果(=(第一个图案)\?)
    ;通配符,因此使用短循环或:
    (或)
    (dpr模式“尝试不匹配任何字符…”)
    (通配符匹配输入(rest模式)))
    (做
    (dpr模式“好,尝试匹配任何字符…”)
    (重复(静止输入)(静止模式)))
    非通配符,测试是否相等,如果相等,则继续。
    (和(=(第一模式)(第一输入))
    (重复(静止输入)(静止模式(()())))
    (defn testcase[输入模式]
    (印刷印刷商)在现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场现场方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方
    (println“尝试将“输入”与“模式”匹配)
    (println“=>”(通配符匹配(顺序输入)(顺序模式)))
    (打印)
    (doall(map#)(测试用例(第一个%)(第二个%)
    你好,你好
    [“你好”h?l?o“]
    [“hllo”“h?l?o”]
    [“hlo”“h??lo”]
    [“你好”h?lo“]
    [“你好”h???p“]])
    
    您可以在此处看到正在执行此操作:


    由于Clojure是一种功能性语言,它大量使用递归,因此在那里可以看到很多递归。把它转换成一种更为强制的语言,如C++,应该去掉大部分递归,特别是那些可以被循环替换的(这就是所有的代码> ReCurrue/Cuth.Cube,只留下一个递归的必要使用)。我发现了一些非常有用的东西,虽然有些不同,但仍然很有用。