C# 正在拆分没有字符串的字符串。拆分

C# 正在拆分没有字符串的字符串。拆分,c#,string,C#,String,我正在做一个家庭作业问题,不使用框架方法拆分字符串 下面是我想出的工作代码 我想知道如何将运行时间提高到O(n) 此外,欢迎提出任何改进建议 public static string[] split(string txt, char[] delim) { char[] text = txt.ToCharArray(); string[] result = new string[0]; int count = 0; int i = 0; StringBuil

我正在做一个家庭作业问题,不使用框架方法拆分字符串

下面是我想出的工作代码

我想知道如何将运行时间提高到O(n)

此外,欢迎提出任何改进建议

public static string[] split(string txt, char[] delim)
{
    char[] text = txt.ToCharArray();
    string[] result = new string[0];
    int count = 0;
    int i = 0;
    StringBuilder buff = new StringBuilder(); 
    while(i < text.Length)
    {
        bool found = false;
        foreach(char del in delim)
        {
            if(del == txt[i])
            {
                found = true;
                break;
            }
        }
        if(found)
        {
            count++;
            Array.Resize(ref result, count);
            result[count - 1] = buff.ToString();
            buff = new StringBuilder();                 
        }
        else
        {
            buff.Append(txt[i]);
        }

        i++;
    }

    if(buff.Length != 0)
    {
        count++;
        Array.Resize(ref result, count);
        result[count - 1] = buff.ToString();
    }

    return(result);
}
publicstaticstring[]split(stringtxt,char[]delim)
{
char[]text=txt.ToCharArray();
字符串[]结果=新字符串[0];
整数计数=0;
int i=0;
StringBuilder buff=新的StringBuilder();
while(i
由于必须遍历/搜索分隔符列表,因此无法在O(n)中执行String.Split操作。

我认为您的教授正在寻找一种只使用单个字符而不是数组的API。不是一个字符数组。我的意思是,如果您的定界字符串是“abcd”,您将不会在“a”、“b”、“c”、“d”的所有实例上进行拆分。只有找到整个字符串,才能拆分

您当前的算法不是O(n),因为对于输入数组中的每个元素,您将其与定界数组中的每个元素进行比较。这导致执行时间为O(n*m)

我认为不可能将其转换为O(n),因为输入上的每个元素都需要与分隔符数组的每个元素进行比较。我想很可能你的教授问了一个关于分隔符数组的不同问题

public static String[] Split(String input, String delimiter)
{
    List<String> parts = new List<String>();
    StringBuilder buff = new StringBuilder();
    if (delimiter.Length > 1) //you are splitting on a string not a character
    {
       //perform string searching algorithm here
    }
    else if(delimiter.Length == 0)
    {
       throw new InvalidOperationException("Invalid delimiter.");
    }
    else //you are splitting on a character
    {
       char delimChar = delimiter[0];
       for (int i = 0; i < input.Length; i++)
       {
           if (input[i] == delimChar)
           {
               parts.Add(buff.ToString());
               buff.Clear();
           }
           else
           {
               buff.Append(input[i]);
           }
       }
    }
    return parts.ToArray();
}
公共静态字符串[]拆分(字符串输入,字符串分隔符)
{
列出零件=新列表();
StringBuilder buff=新的StringBuilder();
if(delimiter.Length>1)//您正在拆分字符串而不是字符
{
//在此执行字符串搜索算法
}
else if(delimiter.Length==0)
{
抛出新的InvalidOperationException(“无效分隔符”);
}
else//您正在拆分角色
{
char delimChar=分隔符[0];
for(int i=0;i
C#的
String.Split()
确实包含一个分隔符数组,但我不相信它能在O(n)时间内完成拆分

如果您正在研究字符串搜索算法,这些可能会有所帮助


编辑:我错误地提到C#的
String.Split()
API没有使用分隔符数组

我做了一些更改,同时使此函数更像C,并将运行时间减少到O(n):

1) 不要多次动态调整
结果
数组的大小,您应该在数组中创建足够多的点来容纳最大数量的字符串(您知道这个数字小于
txt.Length
),然后在返回它之前在最后只调整它一次大小

2) 不要用StringBuilder组合结果,而是制作一个长度为
txt.length
char[]buff
和一个索引变量
j
和do
buff[j++]=txt[i]

我认为在你这样做之后,你的函数应该是O(N)。从技术上讲,它是O(N*M),其中M是分隔符的数目

编辑1:

这是一个将O(N)+O(M)替换为O(N*M)的更改:

您不应循环使用字符串中每个字符的分隔符,而应提前循环使用分隔符并设置如下数组:

bool[] isDelimiter = new bool[128];  // increase size if you are allowing non-ascii
foreach(char delim in isDelimiter)
{
    isDelimiter[(int)char] = true;
}
然后,您可以使用此数组在固定时间内测试字符串的每个字符。

如果将分隔符字符放入哈希集中,则可以将其设为O(n)。测试哈希集中是否存在值是O(1)


但是,对于少量分隔符,这不会提高性能。

也许您可以尝试一次性完成所有工作

public static String[] Split(String txt, char[] delim)
{
    if (txt == null)
        return new String[0]; // or exception
    if (delim == null || delim.Length == 0)
        return new String[0]; // or exception

    char[] text = txt.ToCharArray();
    string[] result = new string[1]; // If there is no delimiter in the string, return the whole string
    int part = 0;
    int itemInArray = 1;

    for (int i = 0; i < text.Length; i++)
    {
        if (IsIn(delim, text[i]))
        {
            Array.Resize(ref result, ++itemInArray); // Is it consider as a framework method ???
            part++;
        }
        else
            result[part] += text[i];
    }
    return result;
}
public static Boolean IsIn(char[] delim, char c)
{
    for (int i = 0; i < delim.Length; i++)
        if (c == delim[i])
            return true;
    return false;
}
publicstaticstring[]Split(stringtxt,char[]delim)
{
如果(txt==null)
返回新字符串[0];//或异常
if(delim==null | | delim.Length==0)
返回新字符串[0];//或异常
char[]text=txt.ToCharArray();
字符串[]结果=新字符串[1];//如果字符串中没有分隔符,则返回整个字符串
整数部分=0;
int itemInArray=1;
for(int i=0;i
您可以使用正则表达式吗?不,我不可以。应该是“C”字@尼莫你确定定界符是一个字符数组而不是一个字符吗?它应该是多少C'ish?例如-foreach是C#,而不是C'ish。@dialogicus
if(buff.Length!=0)
循环外部用于将未完成的缓冲区写入结果。文档似乎不同意您对C#方法使用什么分隔符的看法:。这不是真的。见MSDN,你们说得对
if(delimterSet.Contains(txt[i]) { ... }
public static String[] Split(String txt, char[] delim)
{
    if (txt == null)
        return new String[0]; // or exception
    if (delim == null || delim.Length == 0)
        return new String[0]; // or exception

    char[] text = txt.ToCharArray();
    string[] result = new string[1]; // If there is no delimiter in the string, return the whole string
    int part = 0;
    int itemInArray = 1;

    for (int i = 0; i < text.Length; i++)
    {
        if (IsIn(delim, text[i]))
        {
            Array.Resize(ref result, ++itemInArray); // Is it consider as a framework method ???
            part++;
        }
        else
            result[part] += text[i];
    }
    return result;
}
public static Boolean IsIn(char[] delim, char c)
{
    for (int i = 0; i < delim.Length; i++)
        if (c == delim[i])
            return true;
    return false;
}