44、 Wildcard Matching (Hard)

本文介绍了一种解决通配符匹配问题的算法实现,重点讨论了如何处理特殊字符'?'和'*',并通过实例展示了算法的工作原理。

Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false
题意就是实现智能匹配,?可以匹配任何一个字符,*可以匹配任何数目的任何字符。关键在于对*的处理。这个题是典型的动态规划题,《算法导论》里有,只要注意*在矩阵中的处理即可。自己当时不想用动态规划实现,想到一种自认为比较绝妙的方法,就是把要匹配的字符串按照*分割,然后按照分割次序依次和待匹配的字符串匹配,匹配成功一个就纪录下当前位置,下一个分割的字符串就从当前位置的下一个位置继续开始匹配。如果待匹配的字符串已经到终点而要匹配的分割字符串还没匹配完,就说明匹配失败了。大概是一种贪心的算法思想,而且感觉实现起来不难。结果,我就掉进了一个大坑,各种奇形怪状的测试用例让我对程序的逻辑进行修补,失败了十几次,眼睁睁的看着1807个测试用例的通过个数从500涨到650,再到700、800、1200、1600、1750、1780........最后终于完全AC,这个时候我几乎已经看不懂我的代码了,而且悲剧的是实现时间也只超过了18%的人,如果用动态规划则肯定能超过一半的人。看来用空间换时间还是对的。总之还是要把自己的看不懂但历尽千辛万苦最后还是通过的代码贴出来,动态规划实现的代码网上到处都是,就不贴了。

import java.util.Scanner;

public class Test {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while (true) {
			String s = in.next();
			String p = in.next();
			System.out.println(isMatch(s, p));
		}
	}

	public static boolean isMatch(String s, String p) {
		if (s.length() == 0 && p.length() == 0) {
			return true;
		}
		char[] a = s.toCharArray();
		int skip = 0;

		String[] mline = p.split("\\*");

		int mlength = 0;
		for (int i = 0; i < mline.length; i++) {
			if (!mline[i].equals("")) {
				mlength++;
			}
		}

		int number = 0;
		char[] c = p.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (c[i] != '*') {
				number++;
			}
		}

		if (number > s.length()) {
			return false;
		}

		if (mline.length == 0) {
			return true;
		}
		if (mlength == 1) {
			boolean flag1 = false;
			boolean seenflag = false;
			boolean fflag = false;
			boolean bflag = false;

			for (char w : p.toCharArray()) {
				if (w == '*') {
					flag1 = true;
					if (!seenflag) {
						fflag = true;
					} else {
						bflag = true;
					}
				} else {
					seenflag = true;
				}
			}

			if (!flag1 && p.length() != s.length()) {
				return false;
			}
			int snumber = 0;
			for (int i = 0; i < mline.length; i++) {
				if (mline[i].length() > 0) {
					snumber = i;
				}
			}

			char[] bb = mline[snumber].toCharArray();

			boolean flag = false;
			if (fflag && bflag) {

				for (int i = 0; i <= a.length - bb.length; i++) {
					for (int j = 0; j < bb.length; j++) {
						if (a[i + j] != bb[j] && bb[j] != '?') {
							break;
						} else {
							if (j == bb.length - 1) {
								flag = true;
								break;
							}
						}
					}
				}

			}

			else if (fflag && !bflag) {
				int i = a.length - 1;
				int j = bb.length - 1;
				while (j >= 0 && i >= 0 && (a[i] == bb[j] || bb[j] == '?')) {
					if (j == 0) {
						flag = true;
					}
					i--;
					j--;
				}
			} else if (!fflag && bflag) {

				System.out.println("4");
				for (int i = 0; i < bb.length; i++) {
					if (bb[i] == a[i] || bb[i] == '?') {
						if (i == bb.length - 1) {
							flag = true;
							break;
						}
					} else {
						break;
					}
				}
			} else {
				for (int i = 0; i < bb.length; i++) {
					if (bb[i] == a[i] || bb[i] == '?') {
						if (i == bb.length - 1 && i == a.length - 1) {
							flag = true;
							break;
						}
					} else {
						break;
					}
				}
			}

			if (!flag) {
				return false;
			}

			if (flag) {
				return true;
			}

		}

		// *分割的第一个字符串和最后一个字符串也必须要判断。
		for (int i = 0; i < mline.length; i++) {
			System.out.println("skip:" + skip);
			char[] b = mline[i].toCharArray();
			if (b.length == 0) {
				continue;
			}
			if (i == 0) {
				System.out.println("0判断");
				boolean temp = false;
				for (int k = 0; k < b.length; k++) {				
					System.out.println("K判断"+k+" ak:"+a[k]+" bk:"+b[k]);
					if (b[k] == a[k] || b[k] == '?') {
						
						if (k == b.length - 1) {
							temp = true;
						}
					}
					else{
						break;
					}
				}
				if (!temp) {
					return false;
				}

			}

			else if (i == mline.length - 1) {
				if (!p.substring(p.length() - 1, p.length()).equals("*")) {
					System.out.println("!!*");
					boolean temp = false;
					for (int k = 0; k < b.length; k++) {
						if ((b[b.length - 1 - k] == a[a.length - 1 - k])
								|| b[b.length - 1 - k] == '?') {
							if (k == b.length - 1) {
								temp = true;
							}
						} else {
							break;
						}
					}
					System.out.println("skiplalal:   "+skip+"   "+s.length());
					if (!temp || skip ==s.length()||(skip<s.length()&&skip+b.length>s.length())) {
						return false;
					} else {
						System.out.println("lallaalwwww");
						return true;
					}
				} else {
					System.out.println("*");
					// 最后一个是*,跳跃skip
					for (int k = skip; k < s.length(); k++) {
						boolean flag = false;
						for (int j = 0; j < b.length; j++) {
							if (j + k < a.length) {
								if (b[j] == a[j + k] || b[j] == '?') {
									if (j == b.length - 1) {
										flag = true;
									}
								} else {
									break;
								}
							} else {
								return false;
							}
						}
						if (flag) {
							skip = k;
							// System.out.println("wen");
							return true;
						}
					}
					return false;

				}
			}

			boolean matchflag = false;
			if (skip < s.length()) {
				for (int k = skip; k < s.length(); k++) {
					// System.out.println("k:" + k);
					boolean flag = false;
					for (int j = 0; j < b.length; j++) {
						if (j + k < a.length) {
							if (b[j] == a[j + k] || b[j] == '?') {
								if (j == b.length - 1) {
									flag = true;
									matchflag = true;
								}
							} else {
								break;
							}
						} else {
							return false;
						}
					}
					if (flag) {
						skip += (k - skip + b.length);
						break;
					}
				}
				if(!matchflag){
					return false;
				}
				
			} else {
				return false;
			}

		}

		/*
		 mississippi 
		 m*i*si*si*si*pi
		 */

		return false;
	}
}


Bridge Counters 10.15.1 Bridge Ingress Counters 10.15.1.1 Bridge Drop Counter The Bridge engine can assign a HARD or SOFT DROP command to packets for many reasons. The Bridge engine maintains a 32-bit counter that can be configured to count all bridge packet drop events, or only count packet drop events due to a specifically configured reason. The specific reasons for a Bridge drop are:  Spanning Tree port state drop (Spanning Tree Filtering)  FDB entry command drop (FDB Entry Command)  MAC SA Moved Event (Moved MAC Command)  ARP CPU code (Router Security Checks for Bridged IPv4/6 and ARP Traffic)  MAC SA is DA (Source Address is destination address)  Source IP Equals Destination IP Event (Source IP (SIP) is Destination IP (DIP))  TCP/UDP Source Port Equals Destination Port (TCP/UDP Source Port is Destination Port)  Invalid SA drop (FDB Source MAC Learning) (FDB Source MAC Learning)  TCP Packet With Fin Flag And Without Ack (TCP Flags with FIN without ACK)  IEEE Reserved Drop (IEEE Reserved Multicast)  ICMP (MLD and Other IPv6 ICMP)  TCP Packet Without Full Header (TCP Without Full Header)  IPv4 RIPv1 (Routing Information Protocol (RIPv1))  IPv6 Neighbor Solicitation (IPv6 Neighbor Solicitation)  Unregistered IPv4 Broadcast drop (Per-eVLAN Unregistered IPv4 Broadcast Filtering)  Unregistered non-IPv4 Broadcast drop (Per-eVLAN Unregistered Non-IPv4 Broadcast Filtering)  Cisco command (Proprietary Layer 2 Control Multicast)  Unregistered Non-IP Multicast drop (Per-eVLAN Unregistered Non-IPv4/6 Multicast Filtering)  Unregistered IPv4 Multicast drop (Per-eVLAN Unregistered IPv4 Multicast Filtering) Unregistered IPv6 Multicast drop (Per-eVLAN Unregistered IPv6 Multicast Filtering)  Unknown Unicast drop (Per-eVLAN Unknown Unicast Filtering)  Secure Automatic Learning Unknown SA drop (Secure Automatic Learning)  eVLAN not valid drop (Invalid eVLAN Filtering)  Physical Port not member in VLAN drop (eVLAN Ingress Filtering)  eVLAN range drop (eVLAN Range Filtering)  Moved static address drop (FDB Static Entries)  MAC Spoof Protection Event (MAC Spoof Protection)  ARP MAC SA Mismatch (ARP MAC SA Mismatch)  Controlled Learning Unknown MAC SA drop (Source MAC Address CPU Controlled Learning)  SYN with data (TCP SYN Packet with Data)  TCP over Multicast (TCP over MAC Multicast/Broadcast)  Bridge Access Matrix (Bridge Access Matrix)  Fragmented ICMPv4 (Fragmented ICMPv4)  TCP Flags Zero (Zero TCP Flags)  TCP Flags FIN, URG and PSH (TCP Flags with FIN-URG-PSH)  TCP Flag SYN and FIN (TCP Flags with SYN-FIN)  TCP Flags SYN and RST (TCP Flags with SYN-RST)  TCP/UDP Port is Zero (Zero TCP/UDP Port)  Bridge Access Matrix Drop (Bridge Access Matrix)  Acceptable Frame Type (Acceptable Frame Type Filtering)  eVLAN MRU (eVLAN Maximum Receive Unit (MRU))  Rate Limiting drop (Ingress Port Storm Rate Limit Enforcement)  Local ePort drop (Bridge Local Switching)  IP Multicast In Iana Range Drop (IP and Non-IP Multicast Filtering)  IP Multicast Not In Iana Range Drop (IP and Non-IP Multicast Filtering)  DSA Tag Source Device is Local Device Drop (Loop Detection) Configuration  To configure the Bridge Drop Counter reason, use the <Bridge Drop Counter Mode> field in the Bridge Global Configuration1 Register (Table 320 p. 2219).  To read/write to the Bridge Drop Counter, read/write to the <BridgeDropCnt> field in the Bridge Filter Counter Register (Table 368 p. 2309) according 10.15.1.2 Bridge Host Counters A set of Host Group counters is maintained for a configured MAC Source Address and MAC Destination Address. These counters correspond to RMON-1 MIB (RFC 2819) Host counters. Configuration  To configure the MAC DA to be used by the host counters, use the MAC Address Count0 Register (Table 373 p. 2311) and the MAC Address Count1 Register (Table 374 p. 2311).  To configure the MAC SA to be used by the host counters, use the MAC Address Count1 Register (Table 374 p. 2311) and the MAC Address Count2 Register (Table 375 p. 2311).  The hostInPkts counter can be read from the Host Incoming Packets Count Register (Table 376 p. 2311). This counter is clear-on-read.  The hostOutPkts counter can be read from Host Outgoing Packets Count Register (Table 377 p. 2311). This counter is clear-on-read.  The hostOutBroadcastPkts counter can be read from Host Outgoing Packets Count Register (Table 377 p. 2311) This counter is clear-on-read.  The hostOutMulticastPkts counter can be read from Host Outgoing Packets Count Register (Table 377 p. 2311). This counter is clear-on-read. 10.15.1.3 Bridge Matrix Group A packet counter is maintained for a single, CPU-configured MAC source/Destination Address pair. These counters correspond to RMON-1 MIB (RFC 2819) Matrix counters. Configuration Read the matrixSDPkts counter from the <MatrixSDPkts> field in the Matrix Source/Destination Packet Count Register (Table 380 p. 2312) accordingly. This counter is clear-on-read. Table 34: Host Counters Counter Name Counter Description hostInPkts The number of good packets1 with a MAC DA matching the CPU-configured MAC DA. hostOutPkts The number of good packets with a MAC SA matching the CPU-configured MAC SA. hostOutBroadcast Pkts The number of good Broadcast packets with a MAC SA matching the configured MAC SA. hostOutMulticastPkts The number of good Multicast Packets with a MAC SA matching the configured MAC SA. 1. Good packets are error-free Ethernet packets that have a valid frame length, per RFC 2819. Table 35: Matrix Source Destination Counters Counter Name Counter Description matrixSDPkts The number of good packets with a MAC SA/DA matching the CPU￾configured MAC SA/DA 10.15.1.4 Bridge ePort/eVLAN/Device Counters There are two sets of Ingress ePort/eVLAN/device bridge counters—Set-0 and Set-1. Each counter-set is applied to a configured packet Ingress stream based on eVLAN and ePort. eVLAN and ePort can be set as a wildcard (traffic from all ePorts for the eVLAN), all traffic for the ePort, and all traffic in the switch. Each counter-set can be configured independently. Each counter-set maintains four counters as described in Table 36. Table 36: Ingress Port/VLAN/Device Counters per Counter-Set Counter Name Counter Description Bridge In Frames Counter Number of packets received by the bridge according to the specified mode criteria. Depending on the mode selected, this counter can be used to satisfy Bridge and SMON MIB objects (RFC 2674 and RFC 2613) such as: • dot1dTpPortInFrames (mode 1). • smonVlanIdStatsTotalPkts (mode 2). • dot1qTpVlanPortInFrames (mode 3). eVLAN Ingress Filtered Packet Counter Number of packets discarded due to invalid eVLAN, eVLAN not in Range, or Ingress physical port not eVLAN member. This counter can be used to satisfy Bridge MIB objectdot1qTpVlanPortInDiscard (mode 3) Security Filtered Packet Counter Number of packets discarded due to Security Filtering measures: • FDB command drop (Section 10.4.4). • Invalid SA drop (Section 10.4.8). • Moved Static address is a Security Breach drop (Section 10.4.9). • Unknown source MAC command drop, and unknown source MAC is Security breach (Section 10.4.8.4). Bridge Filtered Packet Counter Number of packets dropped by the Bridge for reasons other than eVLAN Ingress filtering and Security breach events. This counter counts packets dropped due any of the following reasons: • Rate Limiting drop (Section 10.10, Ingress Port Storm Rate Limit Enforcement) • Local port drop (Section 10.13, Bridge Local Switching) • Spanning Tree state drop (Section 10.3, Spanning Tree Filtering) • IP Multicast drop (Section 10.12, IP and Non-IP Multicast Filtering) • Non-IP Multicast drop (Section 10.12) • Unregistered Non-IPM Multicast drop (Section 10.11.1.2, Per-eVLAN Unregistered Non-IPv4/6 Multicast Filtering) • Unregistered IPv6 Multicast drop (Section 10.11.1.4, Per-eVLAN Unregistered IPv6 Multicast Filtering) • Unregistered IPv4 Multicast drop (Section 10.11.1.3, Per-eVLAN Unregistered IPv4 Multicast Filtering) • Unknown Unicast drop (Section 10.11.1.1, Per-eVLAN Unknown Unicast Filtering) • Unregistered IPv4 Broadcast drop (Section 10.11.1.5, Per-eVLAN Unregistered IPv4 Broadcast Filtering) • Unregistered non-IPv4 Broadcast drop (Section 10.11.1.6, Per-eVLAN Unregistered Non-IPv4 Broadcast Filtering) This counter can be used to satisfy Bridge MIB objects: • dot1dTpPortInDiscards • dot1qTpVlanPortInDiscards Configuration  To configure counter set 0/1 criteria, use the <Set<n>ePort>, and <Set<n>CntMode> fields in the Counters Set<n> Configuration 0 Register (n=0–1) (Table 381 p. 2312) and the <Set<n>eVLAN> field in the Counters Set<n> Configuration 1 Register (n=0–1) (Table 382 p. 2312).  The following counters can be read from their respective registers. These counters are clear on read: • Set<n> VLAN Ingress Filtered Packet Count Register (n=0–1) (Table 384 p. 2313) • Set<n> Security Filtered Packet Count Register (n=0–1) (Table 385 p. 2313) • Set<n> Bridge Filtered Packet Count Register (n=0–1) (Table 386 p. 2313) • Set<n> Incoming Packet Count Register (n=0–1) (Table 383 p. 2313)翻译一下
11-18
<think> 嗯,用户这次要求翻译桥接计数器的技术文档,内容相当专业且密集。从连续三次的文档翻译需求来看,用户可能在研究网络设备的桥接功能实现细节,很可能是交换机芯片的开发者或网络协议工程师。 这份文档的结构很清晰,主要分为四类计数器:丢弃计数器、主机计数器、矩阵计数器、端口/VLAN/设备计数器。技术难点在于准确传达专业术语的层次关系,比如“Bridge Drop Counter”需要拆解为“桥接丢弃计数器”而非直译,同时保持表格数据的可读性。 用户似乎特别关注配置寄存器的位置(如Table 320 p.2219),在翻译时必须严格保留这些原始引用。计数器名称的翻译采用RFC标准术语(如RMON-1 MIB),而像“clear-on-read”这类操作特性译为“读取清零”更符合中文技术文档习惯。 注意到“eVLAN”这个特殊术语在文档中反复出现,结合上下文判断是增强型VLAN的缩写,因此保留英文缩写更准确。对于长列表的丢弃原因(如47项),采用分类合并展示能避免信息过载,但保留所有原始条目编号以确保技术严谨性。 用户连续提交类似文档,可能正在构建芯片数据手册的中文版,后续问题需要侧重配置逻辑的连续性。比如丢弃计数器的模式配置字段<Bridge Drop Counter Mode>和主机计数器的MAC地址寄存器关联性很强,在相关问题设计中要体现这种系统性。 </think> ### 桥接计数器系统 #### **10.15.1 桥接入口计数器** ##### **10.15.1.1 桥接丢弃计数器** **功能**:统计因桥接引擎触发的`HARD/SOFT DROP`事件 **丢弃原因分类**: ```mermaid graph TD A[丢弃原因] --> B[安全类] & C[协议类] & D[拓扑类] & E[过滤类] B --> B1[MAC欺骗保护] & B2[ARP MAC SA不匹配] & B3[静态地址迁移] C --> C1[TCP/UDP异常标志] & C2[ICMP分片] & C3[保留组播] D --> D1[生成树阻塞] & D2[本地端口丢弃] & D3[无效VLAN] E --> E1[未注册组播] & E2[未知单播] & E3[速率限制] ``` **配置方法**: - **选择统计模式**:通过桥接全局配置1寄存器(表320 p.2219)的`<Bridge Drop Counter Mode>`字段 - **读取计数值**:访问桥接过滤计数器寄存器(表368 p.2309)的`<BridgeDropCnt>`字段 --- ##### **10.15.1.2 主机计数器** **RMON-1 MIB兼容计数器组**: | 计数器名称 | 描述 | 寄存器位置(均读取清零) | |-------------------------|--------------------------------------|----------------------------------| | `hostInPkts` | 目标MAC=预设MAC DA的有效报文数 | 主机入向报文计数器(表376 p.2311) | | `hostOutPkts` | 源MAC=预设MAC SA的有效报文数 | 主机出向报文计数器(表377 p.2311) | | `hostOutBroadcastPkts` | 源MAC=预设MAC SA的广播报文数 | 同上 | | `hostOutMulticastPkts` | 源MAC=预设MAC SA的组播报文数 | 同上 | **MAC地址预设方法**: - **MAC DA**:MAC地址计数0/1寄存器(表373-374 p.2311) - **MAC SA**:MAC地址计数1/2寄存器(表374-375 p.2311) --- ##### **10.15.1.3 矩阵组计数器** **功能**:统计特定MAC SA/DA对的有效报文 | 计数器名称 | 描述 | 寄存器位置(读取清零) | |-----------------|--------------------------|--------------------------------------| | `matrixSDPkts` | 匹配预设SA/DA的报文数 | 矩阵源/目的报文计数器(表380 p.2312) | --- ##### **10.15.1.4 ePort/eVLAN/设备计数器** **双计数器集架构**: - **Set-0/Set-1**:独立配置,支持通配符(全端口/VLAN/设备) - **统计维度**:`eVLAN` + `ePort`组合 **计数器类型**: | 计数器名称 | 描述 | 对应MIB对象 | |-------------------------------|----------------------------------------------------------------------|-----------------------------------------------------------------------------| | **桥接入向帧计数器** | 符合筛选条件的接收报文数 | `dot1dTpPortInFrames`<br>`smonVlanIdStatsTotalPkts`<br>`dot1qTpVlanPortInFrames` | | **VLAN入口过滤计数器** | 因无效VLAN/范围/端口成员丢弃的报文数 | `dot1qTpVlanPortInDiscards` | | **安全过滤计数器** | 安全策略丢弃数<br>(FDB命令/无效SA/静态地址迁移/未知源MAC) | - | | **桥接过滤计数器** | 非安全/VLAN过滤的其他丢弃事件<br>(含速率限制/STP/组播过滤等47种场景) | `dot1dTpPortInDiscards`<br>`dot1qTpVlanPortInDiscards` | **配置与读取**: ```mermaid graph LR C[配置] --> D[计数器集n配置0寄存器<br>表381 p.2312] D --> D1[<Set<n>ePort>] & D2[<Set<n>CntMode>] C --> E[计数器集n配置1寄存器<br>表382 p.2312] E --> E1[<Set<n>eVLAN>] R[读取] --> F1[Set<n>入口过滤计数器 表384] & F2[安全过滤计数器 表385] & F3[桥接过滤计数器 表386] & F4[入向帧计数器 表383] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值