按以前思路让我判断电话我估计是到网上找正则表达式或者写逻辑先判断字符长度,再判断第一个字符是不是非0数字,然后再判断每位是不是数字。学习状态机之后就能用状态机的思路进行电话号码的判断。
状态节点类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsscciStateMachine
{
/// <summary>
/// 一个状态节点
/// </summary>
public class OneNode
{
/// <summary>
/// 是否是终点
/// </summary>
private bool isEnd;
/// <summary>
/// 是否是终点
/// </summary>
/// <param name="IsEnd"></param>
public OneNode(bool IsEnd)
{
isEnd = IsEnd;
}
/// <summary>
/// 消耗跳转分支
/// </summary>
public Dictionary<string,OneNode> ConsumeBranch
{
get;
set;
}
/// <summary>
/// 不消耗跳转分支
/// </summary>
public List<OneNode> NoConsumeBranch
{
get;
set;
}
/// <summary>
/// 无匹配时候跳转分支
/// </summary>
public OneNode NotMachBranch
{
get;
set;
}
/// <summary>
/// 是否是终点
/// </summary>
/// <returns></returns>
public bool IsEnd()
{
return isEnd;
}
}
}
电话状态机
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsscciStateMachine
{
/// <summary>
/// 判断电话状态机
/// </summary>
public class PhoneStateMachine
{
/// <summary>
/// 状态集合
/// </summary>
private List<OneNode> list = new List<OneNode>();
/// <summary>
/// 开启节点
/// </summary>
private OneNode StartNode = null;
/// <summary>
/// 当前所在节点节点
/// </summary>
private OneNode CurNode = null;
/// <summary>
/// 电话状态机,判断是否是电话号码
/// </summary>
public PhoneStateMachine()
{
//错误节点
OneNode nodeErr = new OneNode(false);
nodeErr.NotMachBranch = nodeErr;
list.Add(nodeErr);
//第一个节点,非0数字跳转下一个节点,0和其他字符跳转错误节点
OneNode node1 = new OneNode(false);
node1.NotMachBranch = nodeErr;
list.Add(node1);
StartNode = node1;
CurNode = node1;
//第二个节点,数字跳转下一个节点,非数字跳转错误节点
OneNode node2 = new OneNode(false);
node2.NotMachBranch = nodeErr;
list.Add(node2);
//第三个节点,数字跳转下一个节点,非数字跳转错误节点
OneNode node3 = new OneNode(false);
node3.NotMachBranch = nodeErr;
list.Add(node3);
//第四个节点,数字跳转下一个节点,非数字跳转错误节点
OneNode node4 = new OneNode(false);
node4.NotMachBranch = nodeErr;
list.Add(node4);
//第五个节点,数字跳转下一个节点,非数字跳转错误节点
OneNode node5 = new OneNode(false);
node5.NotMachBranch = nodeErr;
list.Add(node5);
//第六个节点,数字跳转下一个节点,非数字跳转错误节点
OneNode node6 = new OneNode(false);
node6.NotMachBranch = nodeErr;
list.Add(node6);
//第七个节点,数字跳转下一个节点,非数字跳转错误节点
OneNode node7 = new OneNode(false);
node7.NotMachBranch = nodeErr;
list.Add(node7);
//第八个节点,数字跳转下一个节点,非数字跳转错误节点
OneNode node8 = new OneNode(false);
node8.NotMachBranch = nodeErr;
list.Add(node8);
//第九个节点,数字跳转下一个节点,非数字跳转错误节点
OneNode node9 = new OneNode(false);
node9.NotMachBranch = nodeErr;
list.Add(node9);
//第十个节点,数字跳转下一个节点,非数字跳转错误节点
OneNode node10 = new OneNode(false);
node10.NotMachBranch = nodeErr;
list.Add(node10);
//第十一个节点,数字跳转下一个节点,非数字跳转错误节点
OneNode node11 = new OneNode(false);
node11.NotMachBranch = nodeErr;
list.Add(node11);
//终节点
OneNode nodeEnd = new OneNode(true);
nodeEnd.NotMachBranch = nodeErr;
list.Add(nodeEnd);
node1.ConsumeBranch = new Dictionary<string, OneNode>();
//开始折点只加1-9分支
for (int i = 1; i <= 9; i++)
{
node1.ConsumeBranch.Add(i.ToString(), node2);
}
node2.ConsumeBranch = new Dictionary<string, OneNode>();
node3.ConsumeBranch = new Dictionary<string, OneNode>();
node4.ConsumeBranch = new Dictionary<string, OneNode>();
node5.ConsumeBranch = new Dictionary<string, OneNode>();
node6.ConsumeBranch = new Dictionary<string, OneNode>();
node7.ConsumeBranch = new Dictionary<string, OneNode>();
node8.ConsumeBranch = new Dictionary<string, OneNode>();
node9.ConsumeBranch = new Dictionary<string, OneNode>();
node10.ConsumeBranch = new Dictionary<string, OneNode>();
node11.ConsumeBranch = new Dictionary<string, OneNode>();
nodeEnd.ConsumeBranch = new Dictionary<string, OneNode>();
//其他节点加0-9节点分支
for (int i = 0; i <= 9; i++)
{
node2.ConsumeBranch.Add(i.ToString(), node3);
node3.ConsumeBranch.Add(i.ToString(), node4);
node4.ConsumeBranch.Add(i.ToString(), node5);
node5.ConsumeBranch.Add(i.ToString(), node6);
node6.ConsumeBranch.Add(i.ToString(), node7);
node7.ConsumeBranch.Add(i.ToString(), node8);
node8.ConsumeBranch.Add(i.ToString(), node9);
node9.ConsumeBranch.Add(i.ToString(), node10);
node10.ConsumeBranch.Add(i.ToString(), node11);
node11.ConsumeBranch.Add(i.ToString(), nodeEnd);
}
}
/// <summary>
/// 执行状态机
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public bool Invoke(string str)
{
CurNode = StartNode;
//每次消耗一个字符进行跳转
for (int i=0;i<str.Length;i++)
{
string curS = str.Substring(i, 1);
//符合跳转分支的按分支跳转
if (CurNode.ConsumeBranch!=null&&CurNode.ConsumeBranch.ContainsKey(curS))
{
CurNode = CurNode.ConsumeBranch[curS];
}
//不消耗字符跳转
else if(CurNode.NoConsumeBranch!=null&& CurNode.NoConsumeBranch.Count>0)
{
Random rand = new Random(DateTime.Now.Millisecond);
int randIndex=rand.Next(0, CurNode.NoConsumeBranch.Count);
CurNode = CurNode.NoConsumeBranch[randIndex];
i--;
}
//跳转到错误分支
else
{
CurNode = CurNode.NotMachBranch;
}
}
return CurNode.IsEnd();
}
}
}
测试
using System;
using System.Collections.Generic;
namespace AsscciStateMachine
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("测试电话号码匹配状态机,输入h退出");
PhoneStateMachine stateMachine = new PhoneStateMachine();
while (true)
{
Console.WriteLine("请输入要测试的电话号码:");
string phone = Console.ReadLine();
if(phone=="h")
{
break;
}
bool isPhone = stateMachine.Invoke(phone);
if(isPhone)
{
Console.WriteLine(phone+"是电话号码!");
}
else
{
Console.WriteLine(phone + "不是电话号码!");
}
}
}
}
}
大脑猜测
根据状态节点每个状态可以有多个分支可以链接到下一个状态。每个状态也可以被多个状态指向。该结构和神经细胞的特性相同。神经细胞通过树突接收信号,主突发出信号进行神经信息传递。我们从婴儿开始的认知和学习过程就是把大脑没结构化的神经细胞进行整合。形成各种认知的神经信号处理结构(神经状态机)。通过上面代码构造的判断电话状态机就是一个最小的证明,状态机并不知道他判断的是电话号码规则。我们神经根据我们感受的世界组合神经细胞的连接,根据认知的更新调整神经细胞组合。在我们大脑里形成无数的状态机,帮助我们应对世界的变化,有事件发生时候我们把大脑把接收的信号抛给相应模块的状态机处理。
之前的我是不相信人工智能的,认为再复杂的人工智能无非写很多代码显得比较接近智能。现在我相信只要能根据信号能不断自动构造和调整状态机,状态数量要很大,上千亿的节点。就能实现智能,指针跳转和神经信号跳转有相同的基础结果。重点在自动构造和调整状态机(即学习过程),和很大的算力。