精华内容
下载资源
问答
  • SSM项目搭建的主要步骤

    千次阅读 多人点赞 2018-10-06 17:41:25
    SSM项目搭建的主要步骤一、说明二、配置springMVC1、前端控制器(DispatcherServlet)2、拦截器(HandlerInterceptor)3、视图解析器(ViewResolver,全称为InternalResourceViewResolver(内部资源的视图解析器))...

    一、说明

    因本人个人习惯,一般将项目的核心的配置分为如下几个配置文件配置(名字也是本人的个人爱好,不喜别喷),下文说到配置文件时就不会再进行解释。
    spring-mybatis.xml:springMybatis配置文件,主要用来配置与mybatis有关的配置,如数据源等。
    spring-mvc.xml:springMVC配置文件,主要用来配置与springMVC有关的配置,如视图解析器等。
    spring.xml:spring配置文件,主要用来配置其他的配置,如包扫描,事务管理等。
    spring-configs.xml:核心配置文件,主要用来引入其他的配置文件和配置一些共用的配置,如引入springMybatis配置文件和配置包扫描等。
    

    二、配置springMVC

    springMVC的五大组件,包括“前端控制器”、“后端控制器”、“视图解析器”、“拦截器”和“url映射处理器”。
    

    1、前端控制器(DispatcherServlet)

    1.1 在web.xml文件中配置
    1.2 给“contextConfigLocation”变量指定核心配置文件的路径(如:classpath:/spring-configs.xml)。在前端控制器启动的时候会使用其来加载核心配置文件。
    1.3 设置优先级,一般设置为1(数字越小优先级越高)。如果没有设置,服务器启动时不会启动前端控制器。
    1.4 具体代码配置如下:
    
    	<!-- 配置前端控制器 -->
    	<servlet>
    		<servlet-name>dispatcherServlet</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<init-param>
    			<!-- 指定核心配置文件路径 -->
    			<param-name>ContextConfigLocation</param-name>
    			<param-value>classpath:/spring-configs.xml</param-value>
    		</init-param>
    		<load-on-startup>1</load-on-startup> <!-- 配置优先级,数字越小越高 -->
    	</servlet>
    	
    	<!-- 
    		.do  .action    以前的规范,现在不常用了
    		路径描述:
    			前缀型: /service/*    只要请求以service开头被前端控制器拦截
    			后缀型: .do		   请求拦截以.do结尾
    			全路径: /service/*.do 以service开头以.do结尾请求
    		
    		/*	不管请求是什么路径统统拦截
    		/	拦截请求和静态资源,放行jsp等动态资源(静态资源一般会在核心配置文件中配置放行,具体配置看扩展8)
    		为restFul格式做准备
    	-->
    	<servlet-mapping>
    		<servlet-name>dispatcherServlet</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>
    

    2、拦截器(HandlerInterceptor)

    本人没有配置
    

    3、视图解析器(ViewResolver,全称为InternalResourceViewResolver(内部资源的视图解析器))

    3.1 在springMVC配置文件中配置
    3.2 给“Prefix”变量指定前缀,在解析视图时和后缀一起与传入的字符串拼接成完整的url路径
    3.3 给“Suffix”变量指定后缀,同上
    3.4 具体代码配置如下:
    
    <!-- 配置视图解析器,具体实现类为:InternalResourceViewResolver(内部资源视图解析器) -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        	<property name="Prefix" value="/WEB-INF/views/"/>
        	<property name="Suffix" value=".jsp"/>
    </bean>
    

    4、后端控制器(Controller)

    4.1 可以配置也可以不配置。
    4.2 如果想配置就使用bean标签在springMVC配置文件中配置(一般不建议使用)
    4.3 如果不想配置就使用注解的方式。在类前面添加后端控制器注解(@Controller),然后在spring配置文件中配置扫描就行了。(建议使用)
    4.4 具体代码实现:
    
    @Controller //后端控制器注解
    @RequestMapping("/") //url映射路径注解
    public class PageController {
    	@RequestMapping("doTestPage")
    	public String doTestPage(){
    		return "test_page";
    	}
    }
    

    5、url映射处理器(HanlderMapping)

    5.1 不需要配置URL映射处理器,但需要使用注解方式配置url映射路径。在后端控制器类或方法的前面加上url映射路径的注解(@ RequestMapping)。(建议使用,本人表示只会注解方式,其他方式不会)
    5.2 具体代码实现:
    
    @Controller //后端控制器注解
    @RequestMapping("/") //url映射路径注解
    public class PageController {
    	@RequestMapping("doTestPage")
    	public String doTestPage(){
    		return "test_page";
    	}
    }
    

    扩展配置

    6、全站乱码处理过滤器(CharacterEncodingFilter)

    6.1 在web.xml文件中配置
    6.2 给“encoding”变量指定编码格式(一般为UTF-8)
    6.3 具体代码配置如下:
    
    	<!-- 为了解决中文乱码问题(POST乱码),配置过滤器 -->
    	<filter>
    		<filter-name>characterEncodingFilter</filter-name>
    		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    		<init-param>
    			<param-name>Encoding</param-name>
    			<param-value>UTF-8</param-value>
    		</init-param>
    	</filter>
    	<filter-mapping>
    		<filter-name>characterEncodingFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    

    注:该过滤器只针对POST请求,其他请求无效。请求参数中包含中文的,建议使用POST请求

    7、开启springMVC注解

    7.1 在springMVC配置文件中配置
    7.2 具体代码配置如下:
    
    <!-- 开启mvc注解 -->
    <mvc:annotation-driven/>
    
    7.3 扩展
    	7.3.1 配置阿里巴巴的fashjson对象,主要用于高并发时的数据传输格式转化
    	7.3.2 具体代码配置如下:
    
    	<!-- 配置阿里巴巴的fashjson对象,主要用于高并发时的数据传输格式转化 --> 
    	<mvc:annotation-driven>
    		<mvc:message-converters register-defaults="true">
    			<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
    				<property name="SupportedMediaTypes">
    					<list>
    						<value>text/html;charset=utf-8</value>
    						<value>application/json;charset=utf-8</value>
    					</list>
    				</property>
    			</bean>
    		</mvc:message-converters>
    	</mvc:annotation-driven>
    

    注:如果不开启springMVC注解,会出现一些意想不到的问题。例如:@GetMapping注解无效,@DateTimeFormat注解无效等

    8、放行静态资源文件

    8.1 在springMVC配置文件中配置
    8.2 具体代码配置如下:
    
    <!-- 放行静态资源文件 -->
    <mvc:default-servlet-handler/>
    

    注:放行后,过滤器和前端控制器将不会再进行拦截

    三、配置Mybatis

    1、数据源(使用druid连接池,DruidDataSource)

    1.1 在springMybatis配置文件配置
    1.2 给“DriverClassName”变量指定驱动
    1.3 给“Url”变量指定数据库的url
    1.4 给“Username”变量指定数据库的用户名
    1.5 给“Password”变量指定数据库的密码
    1.6 具体代码配置如下:
    
        <!-- 配置数据源 -->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        	<!-- 驱动的类全名 -->
        	<property name="DriverClassName" value="#{jdbc.jdbcDriver}"/>
        	<!-- 数据库的url -->
        	<property name="Url" value="#{jdbc.jdbcUrl}"/>
        	<!-- 数据库的用户名 -->
        	<property name="Username" value="#{jdbc.jdbcUsername}"/>
        	<!-- 数据库的密码 -->
        	<property name="Password" value="#{jdbc.jdbcPassword}"/>
        </bean>
    

    2、会话工厂(SqlSessionFactoryBean)

    2.1 在springMybatis配置文件配置
    2.2 给“DataSource”变量指定一个数据源(这里为druid连接池)
    2.3 给“ConfigLocation”变量指定mybatis自身的配置文件(mybatis-config.xml),用于加载mybatis自身的配置
    2.4 给“MapperLocations”变量指定mapper文件的路径,为后面的生成动态代理对象做准备
    2.5 给“TypeAliasesPackage”变量指定扫描路径,相当于给指定包下的pojo对象起别名。typeAliasesPackage 默认只能扫描某一个路径下,或以逗号等分割的 几个路径下的内容,不支持通配符和正则
    2.6 具体代码配置如下:
    
    	<!-- 配置会化工厂 -->
    	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    		<!-- 指定数据源 -->
    		<property name="DataSource" ref="dataSource"/>
    		<!-- 指定mybatis自身的配置文件 -->
    		<property name="ConfigLocation" value="classpath:/mybatis/mybatis-config.xml"/>
    		<!-- 指定mapper文件路径 -->
    		<property name="MapperLocations" value="classpath*:/mybatis/mapper/*Mapper.xml"/>
    		<!-- 指定扫描路径 -->
    		<property name="TypeAliasesPackage" value="com.jt.manage.pojo"/>
    	</bean>
    

    注:会话工厂(SqlSessionFactory)是通过SqlSessionFactoryBean创建的,所有配置的是SqlSessionFactoryBean,而不是SqlSessionFactory

    3、Mapper扫描(MapperScannerConfigurer)

    3.1 在springMybatis配置文件配置
    3.2 给“SqlSessionFactoryBeanName”变量指定一个会话工厂类,也可以不写,spring默认注入
    3.3 给“”变量指定dao接口的包路径,主要用于扫描并生成对应的动态代理对象
    3.4 具体代码配置如下:
    
    <!-- 配置mapper扫描 -->
    	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    		<!-- 注入会化工厂 -->
    		<property name="SqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    		<!-- 注入dao接口包路径 -->
    		<property name="BasePackage" value="com.jt.**.dao"/>
    	</bean>
    

    注:MapperScannerConfigurer类会扫描指定的dao包下的接口,并关联对应的mapper动态生成代理对象,代理对象的“BeanId”默认为接口名(首字母小写)

    4、Mybatis自身的配置(主要用来配置mybatis自身的某些功能,最后使用会话工厂来加载)

    4.1 配置时需要注意标签的配置顺序,如果顺序颠倒会出现问题。可能配置无效或报错。将鼠标放在configuration标签上面会提示其他标签的配置顺序,具体如下:
    	配置顺序	(properties?, settings?,typeAliases?,typeHandlers?,objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)
    
    4.2 开启驼峰自动映射
    	具体代码配置如下:
    
    	<settings>
    		<!-- 开启驼峰自动映射 -->
    		<setting name="mapUnderscoreToCamelCase" value="true" />
    	</settings>
    

    四、配置Spring

    1、事务控制

    1.1 配置事务控制
    具体配置如下:
    
    <!-- 配置事务控制 -->
    <tx:annotation-driven/>
    
    1.2 定义事务管理器
    具体配置如下:
    
    	<!-- 定义事务管理器 -->
    	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="DataSource" ref="dataSource"></property>
    	</bean>
    
    1.3 定义事务策略
    具体配置如下:
    
    	<!-- 定义事务策略
    		propagation="REQUIRED"  表示执行该方法必须添加事务
    		propagation="SUPPORTS"  表示之前操作添加了事务,该方法也添加事务,否则该操作没有添加事务
    		read-only="true"  表示该方法中只允许查询操作,如果其中存在增删改操作则会报错
    	 -->
    	<tx:advice id="txAdvice" transaction-manager="transactionManager">
    		<tx:attributes>
    			<tx:method name="save*"   propagation="REQUIRED"/>
    			<tx:method name="delete*" propagation="REQUIRED"/>
    			<tx:method name="update*" propagation="REQUIRED"/>
    			<tx:method name="find*"   propagation="SUPPORTS" read-only="true"/>
    			<tx:method name="*" 	  propagation="SUPPORTS" read-only="true"/>
    		</tx:attributes>
    	</tx:advice>
    
    1.4	定义事务切面
    具体配置如下:
    
    	<!-- 定义事务切面
    		pointcut*, advisor*, aspect*
    		expression 切入点表达式
    			within(包名.类名)	按类匹配,粗粒度
    			execution(返回值的类型 包名.类名.方法名(参数列表))	细粒度
    	 -->
    	<aop:config>
    		<!--  切入点 -->
    		<aop:pointcut expression="execution(* com.jt.manage.service..*.*(..))" id="pc"/>
    		<!-- 指定事务策略和切入点 -->
    		<aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
    	</aop:config>
    

    2、导入properties配置文件的三种方式

    2.1 使用util:properties标签引入

    2.1.1 这种引入只能同时引入一个或一批命名有规律并在同一个目录下的properties配置文件
    2.1.2 具体代码配置如下:
    
    <context:property-placeholder location="classpath:/property/*.properties"/>
    

    2.2 使用context:property-placeholder标签引入

    2.2.1 这种引入只能同时引入一个或一批命名有规律并在同一个目录下的properties配置文件
    2.2.2 具体代码配置如下:
    
    <context:property-placeholder location="classpath:/property/*.properties"/>
    

    2.3 使用PropertyPlaceholderConfigurer类引入

    2.3.1 这种引入可以同时引入一个或一批properties配置文件,其中配置文件不需命名有规律,路径也可以有不同。
    2.3.2 具体代码配置如下:
    
    <bean id="jdbc" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    	<property name="Locations">
    		<list>
    			<value>classpath:/property/jdbc.properties</value>
    		</list>
    	</property>
    </bean>
    

    五、整体搭建

    1、核心配置文件中引入其他的配置文件

    1.1 核心配置文件中引入其他的配置文件,在服务器启动后由前端控制器一起加载
    1.2 具体代码配置如下:
    
    <!-- 引入其他的配置文件 -->
    <import resource="classpath:/spring/spring-mybatis.xml"/>
    <import resource="classpath:/spring/spring-mvc.xml"/>
    <import resource="classpath:/spring/spring.xml"/>
    

    2、包路径的创建

    2.1 包括service、dao、controller等包。
    

    3、配置Tomcat服务器插件,并配置tomcat启动。

    3.1 在pom配置文件中添加Tomcat服务器插件配置
    3.1.1 具体代码配置如下:
    
    	<build>
    		<plugins>
    			<!-- 配置tomcat7服务器插件 -->
    			<plugin>
    				<groupId>org.apache.tomcat.maven</groupId>
    				<artifactId>tomcat7-maven-plugin</artifactId>
    				<version>2.2</version>
    				<configuration>
    					<port>80</port> <!-- 服务器端口号 -->
    					<path>/</path> <!-- 工程访问路径,默认为项目名称 -->
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    
    3.2 配置Tomcat启动
    3.2.1 具体操作如下:
    

    Tomcat插件配置第1步
    Tomcat插件配置第2步
    Tomcat插件配置第3步

    六、附录

    1、spring-mybatis.xml、spring-mvc.xml、spring.xml和spring-configs.xml的引用配置

    1.1 spring-mybatis.xml、spring-mvc.xml、spring.xml和spring-configs.xml这些配置文件需要配置相应的引用(如:xmlns="http://www.springframework.org/schema/beans")
    1.2 为了方便,上面的四个配置文件都使用相同的引用配置,这些引用包含了这些配置文件所有可能使用到的引用。
    1.3 事实上对于某个配置文件来说,某些配置其实是不需要的。如在spring.xml文件中,mvc的引入没有使用到,可以去掉。
    1.4 下面是spring-configs.xml的配置:
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- 
    default-lazy-init   表示是否延迟加载bean对象,true表示延迟加载,false表示立即加载
     -->
    <beans default-lazy-init="true" 
        xmlns="http://www.springframework.org/schema/beans" 
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop" 
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa"
        xsi:schemaLocation="  
           http://www.springframework.org/schema/beans   
           http://www.springframework.org/schema/beans/spring-beans-4.3.xsd  
           http://www.springframework.org/schema/mvc   
           http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd   
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-4.3.xsd   
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
           http://www.springframework.org/schema/util 
           http://www.springframework.org/schema/util/spring-util-4.3.xsd
           http://www.springframework.org/schema/data/jpa 
           http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-4.3.xsd" >
     	
     	<!-- ====================具体配置开始======================= -->
     	<!--配置组件扫描 -->
    	<context:component-scan base-package="com.jt" />
    	<!-- 引入其他的配置文件 -->
    	<import resource="classpath:spring-mvc.xml"/>
    	<import resource="classpath:spring-mybatis.xml"/>
    	<!-- ====================具体配置结束======================= -->
     </beans>
    

    2、mybatis-config.xml的dtd配置

    2.1 mybatis-config.xml需要引入mybatis-3-config.dtd这个约束文件
    2.2 具体配置如下:
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
      PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    	<!-- 
    	配置顺序	(properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, 
     objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)
     	如果配置顺序不对,会出现一些意想不到的错误
    	 -->
    	<settings>
    		<!-- 开启驼峰自动映射 -->
    		<setting name="mapUnderscoreToCamelCase" value="true" />
    		<!-- 二级缓存的总开关,被redis替代 -->
    		<setting name="cacheEnabled" value="false" />
    	</settings>
    </configuration>
    

    3、mapper文件的dtd配置

    3.1 mapper文件需要引入mybatis-3-mapper.dtd这个约束文件
    3.2 具体配置如下:
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.jt.manage.mapper.UserMapper">
    	<select id="findUserList" resultType="User">
    		select * from user
    	</select>
    </mapper>
    
    展开全文
  • Java数据结构和算法——动态规划做题步骤详细总结

    千次阅读 多人点赞 2020-07-11 18:19:48
    文章目录动态规划题目类型动态规划解题步骤动态规划实例讲解硬币问题机器人路径问题青蛙跳石头问题 动态规划题目类型 1、计数: 有多少种方式走到右下角 有多少种方法选出k个数使得和为Sum 2、求最大最小值: 从左上...

    动态规划题目类型

    1、计数:
    有多少种方式走到右下角
    有多少种方法选出k个数使得和为Sum
    2、求最大最小值:
    从左上角走到右下角路径的最大数字和
    最长上升子序列长度
    3、求存在性:
    取石子游戏,先手是否必胜
    能不能选出k个数使得和是Sum

    动态规划解题步骤

    1、确定状态
    简单的说,就是解动态规划时需要开一个数组,数组的每个元素f[i]或者f[i][j]代表什么,类似解数学题中,xyz代表什么一样,具体分为下面两个步骤:
    -------研究最优策略的最后一步
    -------化为子问题
    2、转移方程
    根据子问题定义直接得到
    3、初始条件和边界情况
    初始条件一般都是a[0]、a[1]这种,多看看
    边界条件主要是看数组的边界,数组越不越界
    4、计算顺序
    利用之前的计算结果

    动态规划实例讲解

    硬币问题

    题目:有三种硬币,面值2.5.7,买一本书需要27元,如何用最少的硬币整好付清。

    首先经过分析,这是一个求最大最小值问题,可用动态规划来求解。
    1、确定状态
    (1)最后一步
    虽然我们不知道最优策略是什么,但是最优策略一定是k枚硬币a1,a2…ak加起来等于27
    所以一定有一枚最后的硬币:ak
    除掉这枚硬币,前面硬币的面值相加起来是27-ak,如图
    在这里插入图片描述(2)化为子问题
    所以就将原问题转化为了子问题:
    原问题是最少用多少枚硬币拼出27(k枚)
    子问题是最少用多少枚硬币拼出27-ak(k-1枚)

    经过这两歩,得出状态:f[X]=最少用多少枚硬币拼出X

    2、转移方程
    设状态f[X]=最少用多少枚硬币拼出X
    转移方程如下
    在这里插入图片描述这时,可以用递归进行解题,大致如下
    在这里插入图片描述但是有一个问题,递归是从上到下进行计算的,这样的话会产生大量的重复运算
    在这里插入图片描述所以说,这不是一个好的解法,解决方法就是将计算结果保存下来,改变计算顺序,我们接着来看。

    3、初始条件和边界情况
    边界条件X-2,X-5,X-7小于0时,应该进行处理,这种情况其实就是拼不出来的情况,定义为正无穷

    初始条件一般就是根据转移方程计算不出来的值,从转移方程变量为0或1来选,根据题目进行分析,这个题目的初始条件就是f[0]=1,代入公式的话应该f[0]为正无穷,显然错误,所以自己定义f[0]=0

    4、计算顺序
    这个题目应该是正序的,当我们计算到f[X]时,f[X-2],f[X-5],f[X-7]都已经得到结果了

    在这里插入图片描述

    在这里插入图片描述
    代码:

    	//A数组存储硬币金额,M代表商品价值
    	public static int coinChange(int[] A, int M) {
            int[] f = new int[M + 1];
            f[0] = 0;
    
            for (int i = 1; i <= M; i++) {
                f[i] = Integer.MAX_VALUE;
                for (int j = 0; j < A.length; j++) {
                	//第一个条件是防止数组越界;第二个条件是防止MAX_VALUE+1越界
                    if (i >= A[j] && f[i - A[j]] != Integer.MAX_VALUE) {
                        f[i] = Math.min(f[i], f[i - A[j]] + 1);
                    }
                }
            }
    
            if (f[M] == Integer.MAX_VALUE) {
                f[M] = -1;
            }
    
            return f[M];
        }
    

    机器人路径问题

    题目:给定m行n列的网格,有一个机器人从左上角(0,0)出发,每一步可以向下或者向右走一步,问有多少种不同的方式走到右下角。

    可用计数型动态规划来求解。

    1、确定状态
    (1)最后一步
    聚焦机器人最后挪动的一歩,右下角坐标为(m-1,n-1),那么前一步机器人一定在(m-2,n-1)或者(m-1,n-2)

    (2)子问题
    轻易可得,机器人走到(m-1,n-1)的方式等于机器人走到(m-2,n-1)加上机器人走到(m-1,n-2)
    原问题是有多少种方式从左上角走到(m-1,n-1)
    子问题是有多少种方式从左上角走到(m-2,n-1)和(m-1,n-2)

    经过这两歩,得出状态:f[i][j]为机器人有多少种方式从左上角走到(i,j)

    2、转移方程
    在这里插入图片描述
    3、初始条件和边界情况
    边界条件:i=0或者j=0时前一步只能从一个方向过来,所以f[i][j]=1

    初始条件:f[0][0]=1,机器人只有一种方式到左上角

    4、计算顺序
    计算第0行
    计算第1行

    计算第m-1行
    在这里插入图片描述

    代码:

    	public static int uniquePaths(int m, int n) {
            int[][] f = new int[m][n];
            int i, j;
            for (i = 0; i < m; i++) {
                for (j = 0; j < n; j++) {
                    if (i == 0 || j == 0) {
                        f[i][j] = 1;
                    } else {
                        f[i][j] = f[i - 1][j] + f[i][j - 1];
                    }
                }
            }
            return f[m - 1][n - 1];
        }
    

    青蛙跳石头问题

    题目:有n块石头分别放在x轴的0,1,…,n-1位置,一只青蛙在石头0,想要跳到石头n-1,若青蛙在第i块石头上,他最多可以向右跳距离ai,问青蛙能否跳到石头n-1。
    在这里插入图片描述

    经过分析,这是一个存在型动态规划问题
    1、确定状态
    (1)最后一步
    最后一步是从i跳过来的,i<n-1
    需要满足两个条件:
    青蛙可以跳到石头i;最后一步不能超过跳跃的最大距离,即n-1-i<=ai
    在这里插入图片描述
    (2)化为子问题
    所以就将原问题转化为了子问题:
    原问题是青蛙能不能跳到石头n-1
    子问题是青蛙能不能跳到石头i

    经过这两歩,得出状态:f[j]表示青蛙能不能跳到石头j

    2、转移方程
    f[j]表示青蛙能不能跳到石头j
    转移方程如下
    在这里插入图片描述

    3、初始条件和边界情况
    边界条件:枚举的i和j都不会越界,所以没有边界条件

    初始条件:f[0]=true,因为青蛙一开始就在石头0上

    4、计算顺序
    在这里插入图片描述
    代码:

    	public static boolean canJump(int[] A) {
            boolean[] f = new boolean[A.length];
            f[0] = true;
    
            for (int j = 1; j < A.length; j++) {
                f[j] = false;
                for (int i = 0; i < j; i++) {
                    if (f[i] && i + A[i] >= j) {
                        f[j] = true;
                        break;
                    }
                }
            }
            return f[A.length - 1];
        }
    

    剪绳子问题

    题目:给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],…,k[m]。请问k[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。(2 <= n <= 60)

    可用最值型动态规划来求解。

    1、确定状态
    (1)最后一步
    假设绳子剪得最后一下的长度为j,只需要满足j<i即可

    (2)子问题
    相当于从1开始遍历j,找出 j*(i-j部分的乘积最大值)的最大值
    原问题是长度为i的乘积最大值
    子问题是长度为i-j的乘积最大值

    经过这两歩,得出状态:f[i]表示长度为i的绳子的乘积最大值

    2、转移方程
    f[i] = max( f[i] , j * f[i-j] )
    f[i]初始值可以不动,设置为0
    (其中要注意一个问题,这个式子f[i-j]会把绳子至少分为两段,但是当i-j < 4时, 不分割的情况下是最大的,(大于4就很明显不是了,比如5分为2和3,乘积大于5)显然back_track(n) = n,所以说这个i要从4开始,做子运算时i-j < 4时就按照i - j来计算)

    3、初始条件和边界情况
    边界条件:遍历自己控制不会越界,没有边界情况

    初始条件:由于f[2],f[3]都要至少分为两段,结果不是2和3,而是1和2,所以要单独计算

    4、计算顺序
    从f[4]开始往后计算

    代码:

    	public int cutRope(int target) {
            if(target == 2){
                return 1;
            }else if(target == 3){
                return 2;
            }
            
            int[] f = new int[target+1];
            for(int i=1;i<=3;i++){
                f[i] = i;
            }
            for(int i=4;i<=target;i++){
                for(int j=1;j<i;j++){
                    f[i] = Math.max(f[i],j*f[i-j]);
                }
            }
            
            return f[target];
        }
    

    连续子数组的最大和

    题目:HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)

    可用最值型动态规划来求解。

    1、确定状态
    (1)最后一步
    假设当前要判断的是数组第i个,最后一步就是i,数组下标是i-1

    (2)子问题
    找出到第i-1个为止的连续子数组最大和,看其是否为正或为负,再判断
    原问题是到数组第i个的连续子数组的最大和
    子问题是到数组第i-1个的连续子数组的最大和

    经过这两歩,得出状态:f[i]表示前i个元素的连续子数组的最大和,结尾元素为array[i-1]

    2、转移方程
    f[i] = max( array[i-1] , array[i-1] + f[i-1] )
    如果当前元素为整数,并且f[i-1]为负数,那么当然结果就是只选当前元素,从当前元素开始计算子数组。这里有一个问题是这个方程算出来的连续子数组必须包含array[i-1],所以说我们要用一个变量ret保存每一个f[i],取一个最大的就是结果。

    3、初始条件和边界情况
    边界条件:遍历自己控制不会越界,没有边界情况

    初始条件:f[0] = 0

    4、计算顺序
    从f[1]开始往后计算

    代码:

    public class Solution {
        public int FindGreatestSumOfSubArray(int[] array) {
            int[] f = new int[array.length + 1];
            f[0] = 0;
            int ret = array[0];
            for(int i=1;i<=array.length;i++){
                f[i] = Math.max(array[i-1],f[i-1] + array[i-1]);
                ret = Math.max(ret,f[i]);
            }
            return ret;
        }
    }
    

    最长不含重复字符的子字符串

    题目:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

    可用最值型动态规划来求解。

    1、确定状态
    (1)最后一步
    假设当前要判断s[j]是否和前面的重复,最后一步就是s[j]

    (2)子问题
    原问题是最后一个字符为s[j]的不含重复字符的子字符串
    原问题是最后一个字符为s[j-1]的不含重复字符的子字符串

    经过这两歩,得出状态:f[j] 代表以字符 s[j] 为结尾的 “最长不重复子字符串” 的长度

    2、转移方程
    固定右边界 j ,设字符 s[j] 左边距离最近的相同字符为 s[i],即 s[i] = s[j]

    (1)当 i < 0,即 s[j]左边无相同字符,则 f[j] = f[j-1] + 1
    (2)当 f[j - 1] < j - i,说明字符 s[i]在子字符串 f[j−1] 区间之外 ,则 f[j] = f[j - 1] + 1
    (3)当 f[j−1] >= j−i ,说明字符 s[i] 在子字符串 f[j−1] 区间之中 ,则 f[j]的左边界由 s[i] 决定,即 f[j] = j − i
    当 i < 0 时,由于 f[j−1] <= j 恒成立,因而 f[j−1] < j−i 恒成立,因此(1)/(2)可被合并

    得到转移方程:
    当f[j - 1] < j - i时,f[j] = f[j-1] + 1
    当f[j - 1] >= j - i时,f[j] = j − i

    3、初始条件和边界情况
    边界条件:遍历自己控制不会越界,没有边界情况

    初始条件:f[0] = 1

    4、计算顺序
    从f[1]开始往后计算

    5、关键问题
    观察转移方程,可知问题为:每轮遍历字符 s[j] 时,如何计算索引 i ?

    可以用哈希表来解决
    (1)哈希表统计: 遍历字符串 s 时,使用哈希表(记为 dic )统计 各字符最后一次出现的索引位置
    (2)左边界 i 获取方式: 遍历到 s[j] 时,可通过访问哈希表 ,dic[s[j]]获取最近的相同字符的索引 i,如果没有就默认为-1

    代码:

    class Solution {
        public int lengthOfLongestSubstring(String s) {
            if(s.length() == 0){
                return 0;
            }
            Map<Character, Integer> dic = new HashMap<>();
            int[] f = new int[s.length()];
            f[0] = 1;
            dic.put(s.charAt(0),0);
            int res = 1;
    
            for(int j=1;j<s.length();j++){
                int i = dic.getOrDefault(s.charAt(j),-1);
                dic.put(s.charAt(j),j);
                if(j - i > f[j-1]){
                    f[j] = f[j-1] + 1;
                }else{
                    f[j] = j - i;
                }
                res = Math.max(f[j],res);
            }
    
            return res;
        }
    }
    

    6、空间优化
    由于返回值是取 f 列表最大值,因此可借助变量 tmp 存储 f[j] ,变量 res 每轮更新最大值即可

    此优化可节省 f 列表使用的 O(N) 大小的额外空间

    代码:

    class Solution {
        public int lengthOfLongestSubstring(String s) {
            Map<Character, Integer> dic = new HashMap<>();
            int res = 0, tmp = 0;
            for(int j = 0; j < s.length(); j++) {
                int i = dic.getOrDefault(s.charAt(j), -1); // 获取索引 i
                dic.put(s.charAt(j), j); // 更新哈希表
                tmp = tmp < j - i ? tmp + 1 : j - i; // dp[j - 1] -> dp[j]
                res = Math.max(res, tmp); // max(dp[j - 1], dp[j])
            }
            return res;
        }
    }
    

    最长回文子串

    最长回文子串

    看视频解析,第四步计算顺序很重要,画一个表格就很清晰了,先要算出左下值

    最长上升子序列

    最长上升子序列

    展开全文
  • H3C路由器动态NAT配置步骤全解析

    万次阅读 2013-08-21 07:46:16
    3C路由器所支持的动态NAT地址转换主要包括:NAPT、NOPAT、EASY IP这三种模式。一般情况下,通过在接口上配置所需关联的ACL和内部全局地址池(当采用EASY IP进行配置时不用配置址池)即可实现动态地址转换,让内部...

      以下内容摘自刚刚上市,史上最全面、最系统的的四本大型(每本平均近900页)网络设备新书之一《H3C路由器配置与管理完全手册》(第二版),其它三本分别是:《Cisco交换机配置与管理完全手册》(第二版)《Cisco路由器配置与管理完全手册》(第二版)《H3C交换机配置与管理完全手册》(第二版)。    目前在京东网、当当网上同时购买这四本新书,可直减30元,点击查看:http://item.jd.com/11299332.html , http://book.dangdang.com/20130730_aife

       在互动出版网上同时购买这四本新书,7折并赠送一个8G云U盘(另送15G云空间),点击查看:http://www.china-pub.com/STATIC/zt_mb/zt_huodong_2013_1.asp?filename=2013_slwd_0801

      另外,目前这四本新书正在本站进行有奖试读活动(还有仅10天结束),详情点击:http://blog.chinaunix.net/uid-24789255-id-3826290.html


    7.3 配置动态NAT地址转换

        在本章前面已说了,H3C路由器所支持的动态NAT地址转换主要包括:NAPTNOPATEASY IP这三种模式。一般情况下,通过在接口上配置所需关联的ACL和内部全局地址池(当采用EASY IP进行配置时不用配置址池)即可实现动态地址转换,让内部网络用户根据ACL可选配置)所配置的策略动态选择地址池中可用的IP地址进行转换。但要注意:有些H3C设备还支持仅仅通过判断流出接口报文的源地址,而不使用ACL的方式来实现出接口报文的动态地址转换。

        NOPATNAPT的区别就是根据是否同时使用端口信息来进行动态地址转换:NOPAT为不使用TCP/UDP端口信息实现的多对多地址转换是纯IP地址的转换;NAPT为使用TCP/UDP端口信息实现的多对一地址转换,可以是仅IP地址或端口,或者端口与IP地址同时进行的转换。若直接使用NAT路由器外部网络接口的IP地址作为转换后的内部全局IP地址,则就是EASY IP这种动态NAT地址转换模式了。

        在H3C路由器中,NAT地址转换关联一般在NAT路由器的外部网络接口(出接口)上配置,但是当某内网主机需要通过多个出接口访问外网时,就需要在多个出接口上配置地址转换关联,配置过程就比较复杂了,所以H3C路由器又提供了内部网络接口(入接口)地址关联的配置方案。这样当NAT路由器作为VPN间互访的工具时,在出接口较多的情况下,通过在接入各私网的入接口上配置地址转换关联达到简化配置的目的。这两种配置方式的特点如下(目前主要还是在出接口上关联):

    l    若配置NAT路由器外部网络接口地址关联,那么从外部网络接口发送的首个数据包会首先由ACL(或报文源地址)进行判定是否允许进行地址转换,然后根据关联找到与之对应的地址池(或接口地址)进行源地址转换,并建立地址转换表项,后续数据包直接根据地址转换表项进行转换。

    l    如果配置NAT路由器内部网络接口地址关联,那么从内部网络接口接收的符合指定ACL的数据包首先会被重定向到NAT业务板,然后再做与外部网络接口地址转换类似的源地址转换处理。但该方式下地址转换不支持EASY IP特性,因为这时出口地址有多个。

        【注意】NAT路由器内部网络接口地址关联的支持情况与设备的型号有关,请以设备的实际情况为准。在同时配置了入接口和出接口地址关联的情况下,若报文同时匹配了入接口和出接口的地址转换关联规则,则以出接口规则优先,即只按照出接口地址转换关联进行转换。

    7.2.1 配置NOPAT

        NOPAT动态地址转换模式是通过配置ACL和地址池的关联,将与ACL匹配的报文的源IP地址转换为内部全局地址池中的一个IP地址,但不进行端口转换。NOPAT的具体配置步骤如表7-3所示(因为目前主要支持在出接口上关联NAT地址池,故在此仅以出接口关联进行介绍,下同)。

    表7-3  NOPAT的配置步骤

    步骤

    命令

    说明

    Step 1

    system-view

    例如:

    <Sysname> system-view

    进入系统视图

    Step 2

    nat address-group group-number start-address end-address

    例如:

    [Sysname] nat address-group 1 202.110.10.10 202.110.10.15

    定义一个动态NOPAT地址转换的内部全局地址池。在NOPAT的动态地址转换过程中,NAT路由器将会从地址池中选择一个IP地址作为转换后的报文源IP地址

    Step 3

    interface interface-type interface-number

    例如:

    [Sysname] interface serial 1/0

    键入NAT路由器外部网络接口,进入接口视图

    Step 4

    nat outbound [ acl-number address-groupgroup-number no-pat [ track vrrp virtual-router-id ]

    在出接口配置访问控制列表和地址池关联,但不使用端口信息,实现NOPAT

    下面对以上配置步骤中的一些主要命令进行说明。

    1. nat address-group命令

    nat address-group group-number start-address end-address系统视图命令用来配置NAT动态地址转换使用的全局地址池。命令中的参数说明如下:

    l    group-number,内部全局地址池组索引号,取值范围为0~31。在同一个地址组下可以创建多个地址池,但是要求不仅不同地址池中定义的IP地址段之间不允许重叠,地址组成员的IP地址段也不能与其它地址池或者其它地址组成员的IP地址段重叠。

    l    start-address:内部全局地址池的起始IP地址。

    l    end-address:内部全局地址池的结束IP地址。end-address必须大于或等于start-address,但内部全局地址池中的IP地址数不能超过255个。

         内部全局地址池必须是一些连续的IP地址集合。当对需要到达外部网络的数据报文进行地址转换时,其源地址将被转换为地址池中的某个地址。如果start-addressend-address相同,表示只有一个地址。可用undo nat address-group group-number命令删除原来所配置的内部地址池。但是,已经和某个ACL关联的地址池在进行NAT地址转换时是不允许删除的。

          以下示例是配置一个从210.110.10.10210.110.10.20的内部全局地址池,地址池号为1

    <Sysname> system-view

    [Sysname] nat address-group 1 210.110.10.10 210.110.10.20

    2.  nat outbound命令

            nat outbound [ acl-number ] [ address-group group-number [ vpn-instance vpn-instance-name ] [ no-pat [reversible ] ] ] [ track vrrp virtual-router-id ]接口视图令用来配置出接口地址关联。命令中的参数和选项说明如下:

    l    acl-number:可选参数,指定在进行NOPAT地址转换过程中要关联的ACL号,取值范围为2000~3999(即可以是基本ACL,也可以是高级ACL)。如果选择了该参数,则表示将一个ACL和一个内部全局地址池关联起来,符合ACL规则的报文的源IP地址才可以使用全局地址池中的IP地址进行转换;如果不选择此参数,则表示只要出口上报文的源IP地址不是出口的地址,都可以使用地址池中的地址进行地址转换。当ACL规则变为无效时,新连接的NAT会话表项将无法建立,但是已经建立的连接仍然可以继续通信。在一个接口下,一个ACL只能与一个内部全局地址池绑定;但一个内部全局地址池可以与多个ACL绑定

    l    address-group group-number:指定地址转换时要使用的内部全局地址池。如果不指定地址池,则直接使用NAT路由器的出接口IP地址作为转换后的报文源地址,这就相当于采用Easy IP动态NAT地址转换模式了。

    l    vpn-instance vpn-instance-name:可选参数,指定内部全局地址池中的IP地址所属的VPN实例,表示可以支持VPN之间通过NAT转换进行互访。其中,vpn-instance-name表示VPN实例名,为1~31个字符的字符串,区分大小写。如果不设置该值,表示不支持MPLS VPN多实例。

    l    no-pat:对于NOPAT地址转换模式来说,此为必选项,指定不使用TCP/UDP端口信息实现多对多的NOPAT地址转换。若不配置该参数,则表示使用TCP/UDP端口信息实现多对一的NAPT地址转换,那就成为了下节将要介绍的NPAT的配置了。

    l    reversible:可选项,表示允许反向地址转换。即在内网用户主动向外网发起连接并成功触发建立地址转换表项的情况下,允许外网向该内网用户发起的连接使用已建立的地址转换表项进行目的地址转换(即内部全局地址转换为内部本地地址)。但内网用户主动向外网发起连接并成功触发建立地址转换表项后,外网向该内网用户发起的连接必须与接口上动态地址转换配置使用的地址池所关联的某个ACL匹配才能成功利用已有的地址转换表项进行目的地址转换。

    l    track vrrp virtual-router-id:可选参数,指定出接口地址转换与VRRP备份组进行关联,作用于整个VRRP备份组。virtual-router-id表示关联的VRRP备份组号,取值范围为1~255。如果未指定本参数,则表示没有进行VRRP备份组关联。

           可用undo nat outbound [ acl-number ] [ address-group group-number [ vpn-instance vpn-instance-name ] [ no-pat [reversible ] ] ] [ track vrrp virtual-router-id ]命令取消与对应出接口的关联。但执行该命令后原来生成的NAT地址映射表项不会被自动删除,需要等待5~10分钟后自动老化。在此期间,使用该NAT地址映射表项的用户不能访问外部网络,但不使用该映射表项的用户不受影响。也可以使用reset nat session命令立即清除所有的NAT地址映射表项,但该命令会导致NAT业务中断,所有用户必须重新发起连接。

          另外,可以在同一个NAT路由器出接口上配置不同的地址转换关联,此时要使用对应的undo命令将相应的地址转换关联删除。

          以下示例是在外部网络接口Serial1/0上配置允许10.10.10.0/24网段的主机进行NOPAT动态地址转换,NAT地址池的IP地址范围为210.10.10.10~210.10.10.15

    1)配置与NAT地址池关联的ACL

    <Sysname> system-view

    [Sysname] acl number 2001

    [Sysname-acl-basic-2001] rule permit source 10.10.10.0 0.0.0.255  !---为基本ACL,允许源IP地址在10.10.10.0/24网络中的报文进行NAT地址转换

    [Sysname-acl-basic-2001] rule deny  !---创建一条规则,禁止其他IP包通过

    [Sysname-acl-basic-2001] quit

    2)配置所需的NAT地址池。

    [Sysname] nat address-group 1 210.10.10.10 210.10.10.15

    3)在外部网络接口Serial1/0上配置进行NOPAT地址转换,使用地址池组1中的地址进行地址转换。

    [Sysname] interface serial 1/0

    [Sysname-Serial1/0] nat outbound 2001 address-group 1 no-pat

    7.2.2 配置NAPT

        NAPT将在进行NAT地址转换过程中同时转换源IP地址和源端口,这样来自不同内部地址的数据报的目的地址可以映射到同一个外部IP地址,但它们的端口号被转换为该地址的不同端口号。

        在NAPT地址转换中,同样可以通过配置ACL和地址池的关联,将与ACL匹配的报文的源地址映射为地址池中的外部IP地址,且同时进行端口转换。具体的配置步骤如表7-4所示。整体配置与上节介绍的NOPAT的配置步骤差不多。

    表7-4  NAPT的配置步骤

    步骤

    命令

    说明

    Step 1

    system-view

    例如:

    <Sysname> system-view

    进入系统视图

    Step 2

    nat address-group group-number start-address end-address

    例如:

    [Sysname] nat address-group 1 202.110.10.10 202.110.10.15

    定义一个动态NAPT地址转换的内部全局地址池。在NAPT动态地址转换的过程中,NAT路由器将会从地址池中选择一个IP地址做为转换后的报文源IP地址

    Step 3

    interface interface-type interface-number

    例如:

    [Sysname] interface serial 1/0

    进入接口视图。注意要根据下面是在出口,还是在入口上配置地址池与ACL的关联来确定这里是NAT路由器的出口还是入口

    Step 4

    nat outbound [ acl-number address-groupgroup-number  [ track vrrp virtual-router-id ]

    键入NAT路由器外部网络接口,进入接口视图

    Step 5

    quit

    返回系统视图

    Step 6

    nat mapping-behavior endpoint-independent [acl acl-number ]

    (可选)配置地址转换模式。默认情况下,地址转换模式为Address and Port-Dependent Mapping(关心对端地址和端口转换模式)

       以上配置步骤中的nat outbound命令在上节已有介绍,只是此处不支持no-pat可选项,因为是要同时进行地址端口转换的。

    nat mapping-behavior endpoint-independent [ acl acl-number ]系统视图命令用来配置NPAT地址转换模式下的地址转换模式。命令中的选项和参数说明如下:

    l  endpoint-independent:表示采用不关心对端地址和端口的NAT地址转换模式。配置该命令后,只要是来自相同源IP地址和源端口的报文,无论其目的IP地址是否相同都将通过NAPT映射后转换为同一个外部IP地址和外部端口,并且NAT网关设备允许外部网络的主机通过该转换后的IP地址和端口来访问这些内部网络的主机。

       【说明】默认情况下都是采用Address and Port-Dependent Mapping(关心对端地址和端口转换)模式,这样对于来自相同源IP地址和源端口的报文,如果其目的IP地址和目的端口不同,则通过NAPT映射后将被转换为不同的外部IP地址和外部端口,并且NAT网关设备只允许这些目的IP地址对应的外部网络的主机才可以通过该转换后的IP地址和端口来访问这些内部网络的主机。

    可用undo nat mapping-behavior endpoint-independent [ acl acl-number ]命令恢复默认的关心对端地址和端口转换模式。

    l  acl acl-number:可选参数,用于控制需要遵守指定地址转换模式的报文范围的ACL,取值范围为20003999。配置了ACL后,表示只有符合ACL规则的报文才采用Endpoint-Independent Mapping模式进行地址转换,若不配置ACL,则表示所有的报文都采用Endpoint-Independent Mapping模式进行地址转换。

           以下示例是对所有报文都以Endpoint-Independent Mapping模式进行地址转换。

    <Sysname> system-view

    [Sysname] nat mapping-behavior endpoint-independent

        以下示例是通过高级ACL过滤源报文,仅允许FTPHTTP通信类报文以Endpoint-Independent Mapping模式进行地址转换,其它报文默认采用Address and Port-Dependent Mapping模式进行地址转换。

    <Sysname> system-view

    [Sysname] acl number 3000

    [Sysname-acl-adv-3000] rule permit tcp destination-port eq 80

    [Sysname-acl-adv-3000] rule permit tcp destination-port eq 21

    [Sysname-acl-adv-3000] quit

    [Sysname] nat mapping-behavior endpoint-independent acl 3000

    7.2.3 配置EASY IP

       Easy IP是指进行地址转换时直接使用NAT路由器的出口(外部网络接口)的公有IP地址作为转换后的源地址,能够最大程度的节省IP地址资源。它同样也可以利用ACL控制哪些内部地址可以进行地址转换,但无需配置NAT地址池。具体的配置步骤如表7-5所示。

    表7-5  Easy IP的配置步骤

    步骤

    命令

    说明

    Step 1

    system-view

    例如:

    <Sysname> system-view

    进入系统视图

    Step 2

    interface interface-type interface-number

    例如:

    [Sysname] interface serial 1/0

    进入接口视图,仅可以是NAT路由器的出接口

    Step 3

    nat outbound [ acl-number ]

    例如:

    [Sysname-Serial1/0] nat outbound 2001

    配置ACL和以上出接口地址关联,实现Easy IP特性

       【注意】当直接使用NAT路由器出接口地址作为NAT转换后的外部IP地址时,如果修改了出接口IP地址,则应该首先使用reset nat session命令清除原NAT地址映射表项,否则就会出现原有NAT表项不能自动删除,也无法使用reset nat session命令删除的情况。

       以上配置步骤中的nat outbound与在7.2.2节介绍的该命令功能是一样的,但此时仅参数ACL这一个参数,在此不再赘述。
    展开全文
  • 编写一个MFC程序的主要步骤

    千次阅读 多人点赞 2017-03-28 12:58:30
    一、创建MFC应用程序 1.文件—新建—项目—MFC—MFC应用程序 MFC有三个选项:MFC ActiveX控件、MFC应用...MFC DLL:用来生成MFC动态链接库程序。 2. MFC应用程序向导—应用程序类型:基于对话框,并且不使用Html对话框

    一、创建MFC应用程序

    1.文件—新建—项目—MFC—MFC应用程序

    MFC有三个选项:MFC ActiveX控件、MFC应用程序、MFC DLL。

    MFC ActiveX 控件:用来生成MFCActiveX控件程序。

    MFC 应用程序:用来生成MFC应用程序。

    MFC DLL:用来生成MFC动态链接库程序。

    2. MFC应用程序向导—应用程序类型:基于对话框,并且不使用Html对话框,不使用Unicode库

    应用程序类型有三个选项——单个文档、多个文档、基于对话框

    单个文档Windows记事本、Windows画图、Windows写字板这样的程序,一个程序只有一个文档处于编辑状态。

    多个文档:像WordExcel这样可以在一个MDI窗口里面同时处理多个文档的类型。

    基于对话框:像Windows扫雷、纸牌那样直接在对话框进行操作的程序。用不着文档和试视图。

    不使用Unicode库:为程序兼容性考虑,避免字符串处理麻烦。

    3. MFC应用程序向导—MFC的使用—在共享DLL中使用MFC

    MFC的使用有两个选项: 在共享DLL中使用MFC、在静态库中使用MFC

    在共享DLL中使用MFC:MFC的类会以动态链接库的方式访问,所以我们的应用程序本身就会小些,但是发布应用程序时必须同时添加必要的动态链接库,以便在没有安装VS2010的机子上能够正常运行程序。

    在静态库中使用MFC:类会编译到可执行文件中,所以应用程序的可执行文件要比上种方式大,但可以单独发布,不需另加包含MFC类的库。

    4. MFC应用程序向导—主框架样式:即用户界面特性,根据需求

    5. MFC应用程序向导—高级功能:使用缺省设置

    ActiveX控件:应用程序内可以再嵌套一个应用程序的技术被微软公司称为ActiveX。


    二、设计MFC程序界面设计(工具箱)

    控件工具箱: 

    按钮(Button):用来接收用户的命令,应用程序在接收到用户命令后,通常需要进行一些后台工作。按钮可以响应单击或双击动作,在按钮接收到鼠标动作后,向其父窗口发送相应的控件通知,用户可以对这些控件通知进行消息映射,从而进行相应的处理。在一个对话框中,可以定义一个默认按钮,这只要选中按钮属性中的“Default”选项。如果在对话框活动的时候按下了Enter键,则等同于单击了默认按钮。

     

    复选框(Check Box):用来显示某种可能的选择,该项选择是独立的,用户可以选中或取消该选项。在选项被选中的时候核选标记出现,选项被取消时核选标记消失。MFC中由CButton类对核选框进行支持,用户可以通过SetCheck()函数和GetCheck()函数设置或获取核选框当前的状态。

    编辑框(Edit Box):用来接收用户输入的字符串。通过选择编辑框的选项,编辑框可以接收字符串、数字、密码等;编辑框还可以设置成接收多行字符串的模式;可以自动进行大小写转换。编辑框可能向其父窗口发送多种控件通知,如果用户需要,可以对这些控件通知进行处理。

    组合框(Combo Box):列表框和编辑框的组合,用户除了可以在列表中对已经存在的选项进行选择外,还可以输入新的选择。

    列表框(List Box):用来选择一系列的可能选择,用户通过滚动条可以在这些选择中浏览。在列表框中,可以进行单项选择,也可以进行多项选择,这取决于用户在控件属性对话框中的设置。

    组成框(Group Box):用来包围具有逻辑关系的一组控件,在这些控件的周围加上边界和标题。需注意的是,组成框仅仅是在视觉效果上对控件进行成组,真正的成组工作还需要另外一些工作。

    单选按钮(Radio Button):用来选择某种可能的选择,与核选框不同,该选项不是独立的。一般是几个单选按钮组成一组,同组中的单选按钮可以有也只能有一个按钮被选中.

    静态文本(Static Text):用来在指定的位置显示特定的字符串,一般用来标识附近另一个控件的内容。显示在静态文本控件中的字符串一般不再改变,但是在需要的时候,也可以通过调用相应的函数来进行设置。

    形控件Picture Control):常用于显示位图(Bitmap)和图标(Icon

    组合框(Combo Box):列表框和编辑框的组合,用户除了可以在列表中对已经存在的选项进行选择外,还可以输入新的选择。

    滚动条(Scroll Bar):这包括水平滚动条和垂直滚动条,除了在视觉效果上的方向不同外,水平滚动条在被滚动时发生WM_HSCROLL消息,而垂直滚动条在被滚动时发送WM_VSCROLL消息。

    微调按钮(Spin Button):包括一对紧靠在一起的上下箭头,使用微调按钮可以增大或者缩小某个特定的数值。微调按钮往往都需要一个伙伴控件,这通常都是一个编辑框。当微调按钮的向上箭头被单击时,编辑框中的数字就增大;反之则减小。


    进度条(Progress):在进行一项需要占有较长时间的操作时来反应当前的进度。当操作的进度不断前进时,进度条就用特色颜色填充进度条框。用户可以设定进度条的范围和当前位置。

    滑块控件(Slider):通常用来在程序中接受一系列离散的数值。用户可以设置滑块控件的取值范围,并可以为控件加上刻度标记以显示特定位置的含义。


    热键控制(Hot Key):热键控件看起来就像一个编辑框,但是在热键控件中能够立刻反应用户刚刚按下的键组合,这在设置程序的热键时特别有用。热键控件只是在视觉上显示了按键组合,设置热键的工作还需要用户添加代码完成。

    列表控制(List Control):按一定的排列顺序显示一系列带图标的字符串,列表控件提供了四种显示模式:大图标、小图标、列表和详细信息。用户可以向列表控件中添加新的项,也可以控制列表控件的显示模式。

    树形控件(Tree Control):用来显示一系列项目的层次关系,最典型的例子是显示磁盘上的文件与文件夹。如果有子项目的话,单击树形控件中的项目可以展开或者收缩其子项目。

    属性表控件(Tab Control):用来包含大量的控件,可以满足用户显示或者获取大量数据的要求。每个属性表又分为好几个属性页,这些属性页由各自的标签进行区分,这些属性页中都可以包容其他控件。在显示属性表的时候,一次只能够显示一个属性页的全部内容,同时显示其他属性页的标签,用户通过单击标签打开相应的属性页。


    动画控件(Animation):用来播放一段AVI格式的视频剪辑。用户可以控制视频剪辑的播放、停止和定位,但也仅限于这些功能。动画控件设置不能播放音频剪辑,如果用户需要更高层次的视频或者音频的支持,请选用MCIWnd控件。


    高级编辑框(Rich Edit):编辑控件功能的扩展。在高级编辑框中,除了简单的输入和编辑字符串外,用户还可以为字符或段落指定特定的格式,用户甚至还可以向高级编辑框中插入OLE项。高级编辑框基本上实现了一个带格式的文本编辑器功能,而只需要用户添加少量的接口。

    日历控件(Month Calender):看似与真正的日历类似,操作也类似,直观的为用户提供了观察和显示当前日期的途径。

    日期/时间选择器(Date Time Picker):向用户提供了一种直观的选择日期和时间的方法、日期/时间选择器在外观上类似于一个组合框,但是当用户单击下拉箭头时就会展开一个日历控件供用户选择,而一旦用户做出了选择,日期/时间选择器会自动显示新的日期/时间。

    IP
    地址控件(IP Adress:IP地址控件用来输入和编辑IP地址。该控件外观类似于一个编辑框,但是可以自动对输入的字符按3个一组进行区分和加间隔圆点。IP地址控件为开发支持Internet技术的程序提供了方便。

    扩展组合框(Extended Combo Box):在普通组合框的基础上还支持图像列表。即,可以在组合框中显示特定的图标表示相应的选择,而不仅仅是显示文本。

     

    三、添加并关联变量(控件右击—关联变量)

    Control变量:它是微软对实现Windows程序的图形用户界面元素的一些类的总称。

    Value变量:仅仅只是获取用户输入值的变量

     

    所有控件的公共属性:
    ID
    :控件的资源标识。
    Visiable
    :控件是否可见。
    Disabled
    :控件是否被禁止、被禁止的控件无法接受键盘和鼠标输入。
    Group
    :是否从这个空间开始一个新组。
    Tab stop
    :在程序中是否可以用【Tab】键切换到这个控件。
    Help ID
    :是否给控件分配一个帮助标识,帮助标识基于控件本身的资源标识。
    Client edge
    :给控件增加一个凹陷的边界,使整个控件看起来像是凹下去的一样。
    Static edge
    :给控件增加一个边界。
    Modal frame
    :给控件增加一个3维的框架,与Clientedge相反,它是凸出来的。
    Transparent
    :拥有此属性的窗口是透明的,它下面的窗口不会被它遮掩住。
    Accept files
    :拥有此属性的窗口可以接收拖放文件,如果一个文件被拖动到这个控件上面,控件会收到WM_DROPFILES消息。
    No parent notify
    :表示控件不向其父窗口发送WM_PARENTNOTIFY消息
    Right aligned text
    :表示文本右对齐。

     

    四、添加事件处理函数(控件右击—添加事件处理函数)

    展开全文
  •  动态模型着重于系统的控制逻辑,考察在任何时候对象及其关系的改变,描述这些涉及时序和改变的状态。动态模型包括事件跟踪图和状态图。事件跟踪图则侧重于说明系统执行过程中的一个特点“场景”(scenarios),也...
  • 0 前言 对于刚接触Android中的ffmpeg,ffmpeg的编译有很多坑,这些坑我都踩过一...整文主要涵盖ffmpeg/x264的编译配置、以及如何将编译出的动态库(libavcodec.so libavdevice.so libavfilter.so libavformat.so li...
  • Lendaris对控制工程发展阶段进行了划分: 第一阶段为反馈机制的引入; 第二阶段的特点是通过微分方程对动态系统进行分析,Fourier和Laplace变换,状态空间法、随机方法、Hilbert空间等数学工具奠定了控
  • 用户和nginx服务器进行三次握手进行TCP连接(忽略包括nginx访问控制策略、nginx防火墙等访问控制策略) 第一步:用户将http请求发送给nginx服务器 第二步:nginx会根据用户访问的URI和后缀对请求进行判断 1.例如...
  • 控制理论】滑模控制最强解析

    万次阅读 多人点赞 2019-05-16 21:01:20
    更新,在知乎创建了一个专栏,主要包括一些控制理论和机器人控制方面的知识。 https://zhuanlan.zhihu.com/p/78549442 滑模控制是一种相当简单而且控制性能优越的控制方法,但是绝大多数的工厂在做过程控制时还是...
  • 利用自定义识别可以不用上传图片到Vuforia官网,也可以动态生成/修改识别图来达到在本地修改识别图的目的。 利用Vuforia进行自定义图片的识别(自定义识别是不支持虚拟按键的) 1.新建工程并将Vuforia插件导入...
  • 基于时间ACL的配置基于时间的 ACL 功能类似于扩展 ACL,但它允许根据时间执行访问控制。要使用基于时间的 ACL,您需要创建一个时间范围,指定一周和一天内的时段。您可以为时间范围命名,然后对相应功能应用此范围。...
  • PID控制详解

    万次阅读 多人点赞 2018-12-16 10:43:04
    PID( Proportional Integral Derivative)控制是最早发展起来的控制策略之一,由于其算法简单、鲁棒性好和可靠性高,被广泛应用于工业过程控制,尤其适用于可建立精确数学模型的确定性控制系统。 在工程实际中,...
  • 【STM32】SPI的基本原理、库函数(SPI一般步骤

    万次阅读 多人点赞 2018-05-16 14:51:34
    STM32F1xx官方资料: 《STM32中文参考手册V10》-第23章 串行外设接口SPI   SPI的基本介绍 SPI的简介 SPI,是英语Serial ...SPI接口主要应用在EEPROM、FLASH、实时时钟、AD转换器,还有数字信号处理器和...
  • Java JDK 动态代理(AOP)使用及实现原理分析

    万次阅读 多人点赞 2019-05-08 21:28:06
    代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。 代理模式UML图: 简单结构...
  • 最近工作中使用到了element-ui中steps组件,需求是: 步骤(数量)会因为某些条件进行变化 ...因为某个步骤下是分四个人做,所以步骤内容是以组件的形式分开 上代码 <template> <div class="main"> ...
  • VS2012+Win7网站发布详细步骤

    万次阅读 2015-07-26 13:23:03
    VS2012+Win7网站发布详细步骤 本机环境: 本文分三个部分介绍Web项目发布的常规方法,大神级别可以略过,主要是为了方便一些初学者。第一部分:VS2012把项目发布到文件系统。第二部分:IIS配置发布好的项目。第三...
  • 数学建模中十大算法实现步骤与代码

    万次阅读 多人点赞 2017-09-11 12:53:33
    步骤数学建模中常用的方法:类比法、二分法、差分法、变分法、图论法、层次分析法、数据拟合法、回归分析法、数学规划(线性规划,非线性规划,整数规划,动态规划,目标规划)、机理分析、排队方法、对策方法、决策...
  • 代码审计方法与步骤

    千次阅读 2018-01-09 10:39:59
    代码审计方法与步骤网站审计要点
  • linux系统移植步骤

    万次阅读 多人点赞 2018-07-13 22:52:08
    在众多嵌入式操作系统中,Linux目前发展最快、应用最为广泛。性能优良、源码开放的... 嵌入式Linux系统移植主要由四大部分组成: 一、搭建交叉开发环境 二、bootloader的选择和移植 三、kernel的配置、编译、...
  • 用户画像5步骤

    千次阅读 2018-11-30 19:16:43
    原标题:干货 | 搞定用户画像只需5个步骤 有一句话是,千万人撩你,不如一人懂你,这句话在互联网圈可以说成是,真正的了解用户,才能得到用户,所以,用户画像的重要性不言而喻。 什么是用户画像? 用户画像...
  • 访问控制第一层级:根据当前登录用户动态加载菜单。
  • UML建模 步骤

    千次阅读 2015-07-28 08:45:07
    当一个活动执行完毕之后,控制将沿着控制转移箭头转向下一个活动。活动图中还可以方便地描述控制转移的条件以及并行执行等要求。 8)组件图(ComponentDiagram) UML图的组件图是用来反映代码的物理结构。从...
  • Openstack手动安装部署步骤详解(上):https://blog.csdn.net/weixin_39329758/article/details/103494226 一、目的及要求 二、所需环境 三、项目结构及Openstack架构 四、虚拟网络全局设定 五、环境预配置 ...
  • Linux内核模块简介Linux内核的整体结构已经非常庞大,而其包含的组件也非常多。...有没有一种机制使得编译出的内核本身并不需要包含所有功能,而在这些功能需要被使用的时候,其对应的代码被动态地加载到内核中呢?
  • 自适应控制设计(二)

    千次阅读 多人点赞 2017-09-27 12:34:49
    自适应控制设计(二)《自适应控制基本思想》一文主要介绍了自适应控制设计的基本思路,但是针对控制率的设计没有具体说明,这里针对反馈控制率的设计步骤进行具体介绍控制器设计基本思想对于任何一个动态系统,我们...
  • 设计软件架构的步骤

    千次阅读 2012-10-15 17:00:45
    原题:为应用程序设计一个合适的架构 ...本文将依次介绍应用设计的六个主要步骤并讨论与逻辑选择相关的各种问题。文中还包含了检查设计时可供参考的表单。 输入 在设计应用架构的时候以下输入是非
  • 嵌入式Linux系统移植的四大步骤

    万次阅读 多人点赞 2017-06-05 10:30:25
    最近在学习系统移植的相关知识,在学习和调试过程中,发现了很多问题,也解决了很多问题,但总是对于我们的开发结果有一种莫名其妙的感觉,纠其原因,主要对于我们的开发环境没有一个深刻的认识,有时候几个简单的...
  • 科研项目研究的基本步骤

    万次阅读 2018-01-21 23:07:41
    科研项目研究的基本步骤 一、 制定研究方案  课题研究方案,就是课题确定之后,研究人员在正式开展研究之前制订的整个课题研究的工作计划,它初步规定了课题研究各方面的具体内容和步骤。因此,制定研究方案是...
  • DFMEA步骤二:结构分析

    千次阅读 2020-02-07 12:25:38
    设计结构分析的主要目标是: ● 分析范围的可视化 ● 结构树或其它:方块图、边界图、数字模型、实体零件 ● 设计接口、交互作用和间隙的识别 ● 顾客和供应商工程团队之间的协作(接口职责) ● 功能分析步骤的基础 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 200,811
精华内容 80,324
关键字:

动态控制的主要步骤