写一个HiveQL建表语句的识别函数,同时实现C#字符串解析程序代码的以下三段逻辑,写在一个函数里,优化以下算法的效率,给出所有情况下的测试用例:
1.从前到后一个一个读取字符,遇到匹配空格、Tab和换行符就继续读取下一个字符,遇到大写或小写的字符c,就读取后一个字符并匹配是否为大写或小写的字符r,以此类推,匹配任意字符大写或小写的create字符串,接着匹配空格、Tab和换行符,然后遇到匹配空格、Tab和换行符就继续读取下一个字符,如果匹配大写或小写的字符t,就读取后一个字符并匹配是否为大写或小写的字符a,以此类推,匹配任意字符大写或小写的table字符串,接着匹配空格、Tab和换行符,将这段逻辑封装为函数,全部匹配完成就返回true,否则返回false,外传参数is_external设置为false,外传参数is_temporary设置为false。
2.从前到后一个一个读取字符,遇到匹配空格、Tab和换行符就继续读取下一个字符,遇到大写或小写的字符c,就读取后一个字符并匹配是否为大写或小写的字符r,以此类推,匹配任意字符大写或小写的create字符串,接着匹配空格、Tab和换行符,然后遇到匹配空格、Tab和换行符就继续读取下一个字符,如果匹配大写或小写的字符e,就读取后一个字符并匹配是否为大写或小写的字符x,以此类推,匹配任意字符大写或小写的external字符串,接着匹配空格、Tab和换行符,然后遇到匹配空格、Tab和换行符就继续读取下一个字符,如果匹配大写或小写的字符t,就读取后一个字符并匹配是否为大写或小写的字符a,以此类推,匹配任意字符大写或小写的table字符串,接着匹配空格、Tab和换行符,将这段逻辑封装为函数,全部匹配完成就返回true,否则返回false,外传参数is_external设置为true,外传参数is_temporary设置为false。
3.从前到后一个一个读取字符,遇到匹配空格、Tab和换行符就继续读取下一个字符,遇到大写或小写的字符c,就读取后一个字符并匹配是否为大写或小写的字符r,以此类推,匹配任意字符大写或小写的create字符串,接着匹配空格、Tab和换行符,然后遇到匹配空格、Tab和换行符就继续读取下一个字符,如果匹配大写或小写的字符t,就读取后一个字符并匹配是否为大写或小写的字符e,以此类推,匹配任意字符大写或小写的temporary字符串,接着匹配空格、Tab和换行符,然后遇到匹配空格、Tab和换行符就继续读取下一个字符,如果匹配大写或小写的字符t,就读取后一个字符并匹配是否为大写或小写的字符a,以此类推,匹配任意字符大写或小写的table字符串,接着匹配空格、Tab和换行符,将这段逻辑封装为函数,全部匹配完成就返回true,否则返回false,外传参数is_external设置为false,外传参数is_temporary设置为true。
以下是实现要求的C#代码及测试用例:
csharp
using System;
public class HiveQLParser
{
public static bool ParseCreateTableStatement(string input, out bool isExternal, out bool isTemporary)
{
isExternal = false;
isTemporary = false;
int index = 0;
if (!MatchWhitespaceAndKeyword(ref input, ref index, "CREATE")) return false;
if (!MatchOptionalClause(ref input, ref index, ref isExternal, ref isTemporary)) return false;
if (!MatchWhitespaceAndKeyword(ref input, ref index, "TABLE")) return false;
// 检查是否还有剩余非空白内容
while (index < input.Length && IsWhitespace(input[index])) index++;
return index == input.Length;
}
private static bool MatchOptionalClause(ref string input, ref int index, ref bool isExternal, ref bool isTemporary)
{
int savedIndex = index;
// 尝试匹配EXTERNAL
if (MatchWhitespaceAndKeyword(ref input, ref index, "EXTERNAL"))
{
isExternal = true;
return true;
}
// 尝试匹配TEMPORARY
index = savedIndex;
if (MatchWhitespaceAndKeyword(ref input, ref index, "TEMPORARY"))
{
isTemporary = true;
return true;
}
// 直接匹配TABLE的情况
index = savedIndex;
return true;
}
private static bool MatchWhitespaceAndKeyword(ref string input, ref int index, string keyword)
{
// 跳过空白
while (index < input.Length && IsWhitespace(input[index])) index++;
return MatchKeyword(ref input, ref index, keyword);
}
private static bool MatchKeyword(ref string input, ref int index, string keyword)
{
if (index + keyword.Length > input.Length) return false;
for (int i = 0; i < keyword.Length; i++)
{
if (char.ToUpperInvariant(input[index + i]) != char.ToUpperInvariant(keyword[i]))
return false;
}
index += keyword.Length;
return true;
}
private static bool IsWhitespace(char c) => c == ' ' || c == '\t' || c == '\n' || c == '\r';
}
// 测试用例
public class Program
{
public static void Main()
{
TestCase("CREATE TABLE", false, false);
TestCase("create external table", true, false);
TestCase("CREATE TEMPORARY TABLE", false, true);
TestCase("\tCREATE\nTABLE ", false, false);
TestCase("CREATE\tEXTERNAL\nTABLE", true, false);
TestCase("CREATE TEMPORARY TABLE", false, true);
TestCase("CREAT TABLE", false, false); // 拼写错误
TestCase("CREATE TABLEX", false, false); // 多余字符
TestCase("CREATE EXTERNAL TEMPORARY TABLE", false, false); // 多重修饰
TestCase("CREATE EXTERN TABLE", false, false); // 拼写错误
TestCase("", false, false); // 空输入
TestCase("CREATE", false, false); // 不完整输入
}
private static void TestCase(string input, bool expectedExternal, bool expectedTemporary)
{
bool result = HiveQLParser.ParseCreateTableStatement(
input,
out bool actualExternal,
out bool actualTemporary
);
Console.WriteLine($"Input: [{input}]");
Console.WriteLine($"Result: {result}, External: {actualExternal}, Temporary: {actualTemporary}");
Console.WriteLine($"Test {(result && actualExternal == expectedExternal && actualTemporary == expectedTemporary ? "PASSED" : "FAILED")}");
Console.WriteLine(new string('-', 60));
}
}
代码说明:
- 使用状态机模式进行顺序匹配
- 通过引用传递index来跟踪解析位置
- 支持大小写不敏感的匹配
- 自动跳过任意数量的空白字符(空格、Tab、换行)
- 时间复杂度O(n),空间复杂度O(1)
优化点:
- 采用索引追踪代替字符串截取操作
- 使用字符级比较代替正则表达式
- 提前终止失败路径
- 共享空白跳过逻辑
- 支持任意顺序的空白字符组合
测试用例覆盖范围:
- 标准格式(全大写)
- 混合大小写格式
- 包含多种空白字符
- 边界情况(空字符串、不完整输入)
- 错误情况(拼写错误、多余字符)
- 特殊格式(前后置空白、连续空白)
该实现可以正确处理以下类型的输入:
- "CREATE TABLE"
- "create table"
- "CREATE EXTERNAL\tTABLE"
- "\nCREATE\nTEMPORARY\nTABLE"
- "CrEaTe TaBlE"
并能够准确识别:普通表、外部表和临时表三种类型,同时拒绝不符合格式的输入。