Automaton DFA 实现无法使用 Java
Automaton DFA implementation not working using Java
我现在正在我的大学学习 DFA 和 NFA 自动机以及如何使用 Java 代码实现其中的一些。
我在这个练习中遇到了一些问题:我们有 4 个不同的实验室轮次(T1、T2、T3 和 T4),我们需要编写代码来识别特定字符串(由大学徽章编号组成)学生和他的名字,例如 123321Johnson
) 对应于 T2 或 T3。
我们知道:
- T1轮到徽章编号和姓氏在"A"和"K"
之间的人
- T2 是 "A" 和 "K"
之间偶数徽章号码和姓氏的轮次
- T3 是 "L" 和 "Z"
之间奇数徽章号码和姓氏的轮次
- T4 是 "L" 和 "Z"
之间偶数徽章号码和姓氏的轮次
我们也知道字符串必须至少由一个数字和至少一个字母组成。
例如,自动机必须接受 "1232324Gac"
或 "1232323Lum"
而不是 "121234Lum"
或 "121233Gac"
.
这是我写的代码:
import java.util.Scanner;
public class Es3 {
static Scanner sc = new Scanner(System.in);
String s = sc.next();
public static boolean scan(String s)
{
int state = 0;
int i = 0;
while (state >= 0 && i < s.length()) {
final char ch = s.charAt(i++);
switch (state) {
case 0:
if (ch >= 0 && ch <= 9)
state = 1;
else
state = -1;
break;
case 1:
if (ch >=0 && ch <=9)
state = 1;
else if (ch >='a' && ch <='k')
if ((s.charAt(i--))%2==0)
state = 2;
else
state = -1;
else if (ch >='l' && ch <='z')
if ((s.charAt(i--))%2==1)
state = 3;
else
state = -1;
else
state = -1;
break;
case 2:
if (ch >='a' && ch <='z')
state = 2;
else
state = -1;
break;
case 3:
if (ch >='a' && ch <='z')
state = 3;
else
state = -1;
break;
}
}
return (state == 2 || state == 3);
}
public static void main(String[] args)
{
System.out.println(scan(args[0]) ? "OK" : "NO");
}
}
显然,代码无法运行,但这对于展示练习的一般目的很重要。
有人可以帮我吗?
您的算法不工作的原因是因为您试图将 char
值与 int
值进行比较,这不会给出预期的结果。此外,当您检查 char
值是否在特定字母范围内时,您没有考虑大写字母。
import java.util.Scanner;
public class Es3
{
static Scanner sc = new Scanner(System.in);
String s = sc.next();
public static boolean scan(String s)
{
int state = 0;
int i = 0;
while (state >= 0 && i < s.length()) {
final char ch = s.charAt(i++);
switch (state) {
case 0:
// Compare the char to the char values of the numbers
if (ch >= '0' && ch <= '9')
state = 1;
else
state = -1;
break;
case 1:
// Same here, compare the char to the char values of the numbers
if (ch >= '0' && ch <= '9')
state = 1;
// Check if the char is capital, as well as lowercase
else if ((ch >= 'a' && ch <= 'k') || (ch >= 'A' && ch <= 'K'))
// Convert the char to an int before performing the calculations
if ((Character.getNumericValue(s.charAt(i-1)))%2 == 0)
state = 2;
else
state = -1;
// Check if the char is capital as well
else if ((ch >= 'l' && ch <= 'z') || (ch >= 'L' && ch <= 'Z'))
// Convert from char to int before calculating
if ((Character.getNumericValue(s.charAt(i-1)))%2 == 1)
state = 3;
else
state = -1;
else
state = -1;
break;
case 2:
// Check if the char is capital as well
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
state = 2;
else
state = -1;
break;
case 3:
// Check if the char is capital as well
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
state = 3;
else
state = -1;
break;
}
}
System.out.println("State "+state);
return (state == 2 || state == 3);
}
public static void main(String[] args)
{
System.out.println(scan(args[0]) ? "OK" : "NO");
}
}
我认为上面的代码应该可以完成您想要做的事情。
我现在正在我的大学学习 DFA 和 NFA 自动机以及如何使用 Java 代码实现其中的一些。
我在这个练习中遇到了一些问题:我们有 4 个不同的实验室轮次(T1、T2、T3 和 T4),我们需要编写代码来识别特定字符串(由大学徽章编号组成)学生和他的名字,例如 123321Johnson
) 对应于 T2 或 T3。
我们知道:
- T1轮到徽章编号和姓氏在"A"和"K" 之间的人
- T2 是 "A" 和 "K" 之间偶数徽章号码和姓氏的轮次
- T3 是 "L" 和 "Z" 之间奇数徽章号码和姓氏的轮次
- T4 是 "L" 和 "Z" 之间偶数徽章号码和姓氏的轮次
我们也知道字符串必须至少由一个数字和至少一个字母组成。
例如,自动机必须接受 "1232324Gac"
或 "1232323Lum"
而不是 "121234Lum"
或 "121233Gac"
.
这是我写的代码:
import java.util.Scanner;
public class Es3 {
static Scanner sc = new Scanner(System.in);
String s = sc.next();
public static boolean scan(String s)
{
int state = 0;
int i = 0;
while (state >= 0 && i < s.length()) {
final char ch = s.charAt(i++);
switch (state) {
case 0:
if (ch >= 0 && ch <= 9)
state = 1;
else
state = -1;
break;
case 1:
if (ch >=0 && ch <=9)
state = 1;
else if (ch >='a' && ch <='k')
if ((s.charAt(i--))%2==0)
state = 2;
else
state = -1;
else if (ch >='l' && ch <='z')
if ((s.charAt(i--))%2==1)
state = 3;
else
state = -1;
else
state = -1;
break;
case 2:
if (ch >='a' && ch <='z')
state = 2;
else
state = -1;
break;
case 3:
if (ch >='a' && ch <='z')
state = 3;
else
state = -1;
break;
}
}
return (state == 2 || state == 3);
}
public static void main(String[] args)
{
System.out.println(scan(args[0]) ? "OK" : "NO");
}
}
显然,代码无法运行,但这对于展示练习的一般目的很重要。
有人可以帮我吗?
您的算法不工作的原因是因为您试图将 char
值与 int
值进行比较,这不会给出预期的结果。此外,当您检查 char
值是否在特定字母范围内时,您没有考虑大写字母。
import java.util.Scanner;
public class Es3
{
static Scanner sc = new Scanner(System.in);
String s = sc.next();
public static boolean scan(String s)
{
int state = 0;
int i = 0;
while (state >= 0 && i < s.length()) {
final char ch = s.charAt(i++);
switch (state) {
case 0:
// Compare the char to the char values of the numbers
if (ch >= '0' && ch <= '9')
state = 1;
else
state = -1;
break;
case 1:
// Same here, compare the char to the char values of the numbers
if (ch >= '0' && ch <= '9')
state = 1;
// Check if the char is capital, as well as lowercase
else if ((ch >= 'a' && ch <= 'k') || (ch >= 'A' && ch <= 'K'))
// Convert the char to an int before performing the calculations
if ((Character.getNumericValue(s.charAt(i-1)))%2 == 0)
state = 2;
else
state = -1;
// Check if the char is capital as well
else if ((ch >= 'l' && ch <= 'z') || (ch >= 'L' && ch <= 'Z'))
// Convert from char to int before calculating
if ((Character.getNumericValue(s.charAt(i-1)))%2 == 1)
state = 3;
else
state = -1;
else
state = -1;
break;
case 2:
// Check if the char is capital as well
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
state = 2;
else
state = -1;
break;
case 3:
// Check if the char is capital as well
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
state = 3;
else
state = -1;
break;
}
}
System.out.println("State "+state);
return (state == 2 || state == 3);
}
public static void main(String[] args)
{
System.out.println(scan(args[0]) ? "OK" : "NO");
}
}
我认为上面的代码应该可以完成您想要做的事情。