状态机在程序设计中用处

状态机在程序设计中用处

【问题描述】

 

合法的实数书写格式分一般格式和科学格式两种。分别描述如下:
一般格式为常见的书写格式,分为整数部分和小数部分两部分,中间分用小数点.分隔。整数部分最开始可能含有正号或负号,之后为不含前导零的数字串;小数部分是由0-9十种字符组成的任意长的字符串。当小数部分为0时,小数部分和小数点可以省略。
科学格式由系数部分和指数部分两部分组成,中间用英文字母E分隔。系数部分为实数书写的一般格式;指数部分为可带有正负号数字串。
例如,+2、-1.56为一般格式的实数,而6.2E-2、-9E8为科学格式的实数。
只有小数点而没有小数部分的书写格式为不合法,例如,23.,23.E16均为不合法的实数书写格式。
编程分析哪些数的书写是正确的,是用哪种方式书写的。

 

【输入形式】

 

输入文件为当前目录下的real.in。 该文件包含一个字符串(长度不超过20个字符),以回车符结束,表示一个数据(无多余空格)。

 

【输出形式】

 

输出文件为当前目录下的real.out。 该文件有一行。如果输入数据的书写是非法的,输出Wrong;如果输入数据是用一般格式书写的,输出“Format1”;如果该数据是用科学格式书写的,输出“Format2”。输出的末尾均要以一个回车符作为结束。

 

【输入样例1】

 

+1.23

 

【输出样例1】

 

Format1

 

【输入样例2】

 

-5.1.1

 

【输出样例2】

 

Wrong

 

【输入样例3】

 

-5.1E-2

 

【输出样例3】

 

Format2

 

【时间限制】

 

1s

 

【空间限制】

 

65536KB

解决思路:

判断一个字符串是否符合格式

=>将一个字符串看成是输入流,从左到右的依次检查。

=>也就是说对于一个字符串我们可以将它归结于多种状态.

=>例如,一个正确的字符串有A,B,C,D四种状态。

=>x为从左到右的字符,

for(int i=0;i<strlen(字符串);++i){

x=字符串[i];

}

=>只有字符串处于D状态时才是正确的状态,A为初始状态,B,C为过程状态。

=>当状态处于A时,此时遍历到的x符合要求的字符串格式才能转化到B状态

=>因此可以将算法表示为;

for(int i=0;i<strlen(字符串);++i){

x=字符串[i];

当前状态加上x后,符合要求,保持当前状态或者进入到下一个状态。

否则认定该输入字符串不合法

}

#include<stdio.h>
#include<string.h>
#include<ctype.h>
//format1: <无前导零数字串>.<数字串>
//format2: <无前导零数字串>.<数字串>E<数字串>
typedef enum state{
	initial,
	posneg,
	number1,
	point,
	number2,
	e,
	posneg2,
	number3,
	end
}state;
void input(char buf[]){
	FILE* fd = fopen("real.in", "r+");
	int i = 0;
	fgets(buf, 25, fd);
	for (i = 0; i < (int)(strlen(buf)); ++i){
		if (buf[i] == '\n' || buf[i] == '\r'){
			buf[i] = '\0';
		}
	}
	fclose(fd);
}
int execute(char buf[]){
	int i = 0;
	state tempstate=initial;
	for (i = 0; i < (int)(strlen(buf)); ++i){
		if (tempstate == initial){
			if (i == 0 && isdigit(buf[0])&&buf[0]!='0'){
				tempstate = number1;
			}
			else if (i == 0 && (buf[0] == '+' || buf[0] == '-')){
				tempstate = posneg;
			}
			else{
				break;
			}
		}
		else if (tempstate==posneg){
			if (isdigit(buf[i]) && buf[i] != '0'){
				tempstate = number1;
			}
			else{
				break;
			}
		}
		else if (tempstate == number1){
			if (isdigit(buf[i])){
				tempstate = number1;
			}
			else if (buf[i]=='.'){
				tempstate = point;
			}
			else if (buf[i] == 'E'){
				tempstate = e;
			}
			else{
				break;
			}
		}
		else if (tempstate == point){
			if (isdigit(buf[i])){
				tempstate = number2;
			}
			else{
				break;
			}
		}
		else if (tempstate==number2){
			if (isdigit(buf[i])){
				tempstate = number2;
			}
			else if (buf[i]=='E'){
				tempstate = e;
			}
			else{
				break;
			}
		}
		else if (tempstate==e){
			if (buf[i]=='+'||buf[i]=='-'){
				tempstate = posneg2;
			}
			else if (isdigit(buf[i])&&buf[i]!='0'){
				tempstate = number3;
			}
			else{
				break;
			}
		}
		else if (tempstate==posneg2){
			if (isdigit(buf[i]) && buf[i] != '0'){
				tempstate = number3;
			}
			else{
				break;
			}
		}
		else if (tempstate==number3){
			if (isdigit(buf[i])){
				tempstate = number3;
			}
			else{
				break;
			}
		}
	}
	if (i == (int)(strlen(buf)) && tempstate == number1){
		return 0;
	}
	if (i == (int)(strlen(buf)) && tempstate == number2 ){
		return 0;
	}
	if (i == (int)(strlen(buf)) && tempstate == number3){
		return 1;
	}	
	else{
		return 2;
	}
}
void output(int flag){
	FILE* wd = fopen("real.out", "w+");
	switch (flag){
		case 0:{
			 fprintf(wd,"Format1\n");
			 break;
		}
		case 1:{
			fprintf(wd,"Format2\n");
			break;
		}
		case 2:{
			fprintf(wd,"Wrong");
			break;
		}
		default:{
			printf("wrong");
		}

	}
}
int main(){
	char buf[30];
	int flag = 0;
	input(buf);
	flag=execute(buf);
	output(flag);
	return 0;
}

 


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值