C# 从C中的重复字符串确定唯一字符串

C# 从C中的重复字符串确定唯一字符串,c#,.net,string,string-parsing,C#,.net,String,String Parsing,我需要开发一个有效的算法来确定唯一的重复字符串,给定一个包含重复内容且仅包含重复内容的字符串 例如: ABCDABCDABCDABCDABCD=>Abcd 你好=>你好 我很难想出一个相当有效的算法;如有任何意见,将不胜感激 澄清:我想要一个最短的字符串,当重复足够多次时,它等于整个字符串。类似这样的内容: public string ShortestRepeating(string str) { for(int len = 1; len <= str.Length/2; len+

我需要开发一个有效的算法来确定唯一的重复字符串,给定一个包含重复内容且仅包含重复内容的字符串

例如:

ABCDABCDABCDABCDABCD=>Abcd

你好=>你好

我很难想出一个相当有效的算法;如有任何意见,将不胜感激

澄清:我想要一个最短的字符串,当重复足够多次时,它等于整个字符串。

类似这样的内容:

public string ShortestRepeating(string str)
{
    for(int len = 1; len <= str.Length/2; len++)
    {
        if (str.Length % len == 0)
        {
            sub = str.SubString(0, len);
            StringBuilder builder = new StringBuilder(str.Length)
            while(builder.Length < str.Length)
                builder.Append(sub);
            if(str == builder.ToString())
                return sub;
        }
    }
    return str;
}
private static string FindRepeat(string str)
{
    var lengths = Enumerable.Range(1, str.Length - 1)
        .Where(len => str.Length % len == 0);

    foreach (int len in lengths)
    {
        bool matched = true;

        for (int index = 0; matched && index < str.Length; index += len)
        {
            for (int i = index; i < index + len; ++i)
            {
                if (str[i - index] != str[i])
                {
                    matched = false;
                    break;
                }
            }
        }

        if (matched)
            return str.Substring(0, len);
    }

    return str;
}
这只是从开头开始查看子字符串,然后重复它们以查看它们是否匹配。它还会跳过任何长度不等于原始字符串长度的字符串,并且只会增加到长度/2,因为任何长度超过该长度的字符串都不能作为重复的候选字符串。

类似以下内容:

public string ShortestRepeating(string str)
{
    for(int len = 1; len <= str.Length/2; len++)
    {
        if (str.Length % len == 0)
        {
            sub = str.SubString(0, len);
            StringBuilder builder = new StringBuilder(str.Length)
            while(builder.Length < str.Length)
                builder.Append(sub);
            if(str == builder.ToString())
                return sub;
        }
    }
    return str;
}
private static string FindRepeat(string str)
{
    var lengths = Enumerable.Range(1, str.Length - 1)
        .Where(len => str.Length % len == 0);

    foreach (int len in lengths)
    {
        bool matched = true;

        for (int index = 0; matched && index < str.Length; index += len)
        {
            for (int i = index; i < index + len; ++i)
            {
                if (str[i - index] != str[i])
                {
                    matched = false;
                    break;
                }
            }
        }

        if (matched)
            return str.Substring(0, len);
    }

    return str;
}

这只是从开头开始查看子字符串,然后重复它们以查看它们是否匹配。它还跳过任何长度不等于原始字符串长度的字符串,并且只增加到长度/2,因为任何长度超过该长度的字符串都不能作为重复的候选字符串。

您可以使用带反向引用的正则表达式

Match match = Regex.Match(@"^(.*?)\0*$");
String smallestRepeat = match.Groups[0];

可以使用带有反向引用的正则表达式

Match match = Regex.Match(@"^(.*?)\0*$");
String smallestRepeat = match.Groups[0];
也许这可以奏效:

static string FindShortestSubstringPeriod(string input)
{
  if (string.IsNullOrEmpty(input))
    return input;

  for (int length = 1; length <= input.Length / 2; ++length)
  {
    int remainder;
    int repetitions = Math.DivRem(input.Length, length, out remainder);        
    if (remainder != 0)
      continue;
    string candidate = input.Remove(length);
    if (String.Concat(Enumerable.Repeat(candidate, repetitions)) == input)
      return candidate;
  }
  return input;
}
也许这可以奏效:

static string FindShortestSubstringPeriod(string input)
{
  if (string.IsNullOrEmpty(input))
    return input;

  for (int length = 1; length <= input.Length / 2; ++length)
  {
    int remainder;
    int repetitions = Math.DivRem(input.Length, length, out remainder);        
    if (remainder != 0)
      continue;
    string candidate = input.Remove(length);
    if (String.Concat(Enumerable.Repeat(candidate, repetitions)) == input)
      return candidate;
  }
  return input;
}

我会这样说:

public string ShortestRepeating(string str)
{
    for(int len = 1; len <= str.Length/2; len++)
    {
        if (str.Length % len == 0)
        {
            sub = str.SubString(0, len);
            StringBuilder builder = new StringBuilder(str.Length)
            while(builder.Length < str.Length)
                builder.Append(sub);
            if(str == builder.ToString())
                return sub;
        }
    }
    return str;
}
private static string FindRepeat(string str)
{
    var lengths = Enumerable.Range(1, str.Length - 1)
        .Where(len => str.Length % len == 0);

    foreach (int len in lengths)
    {
        bool matched = true;

        for (int index = 0; matched && index < str.Length; index += len)
        {
            for (int i = index; i < index + len; ++i)
            {
                if (str[i - index] != str[i])
                {
                    matched = false;
                    break;
                }
            }
        }

        if (matched)
            return str.Substring(0, len);
    }

    return str;
}

我会这样说:

public string ShortestRepeating(string str)
{
    for(int len = 1; len <= str.Length/2; len++)
    {
        if (str.Length % len == 0)
        {
            sub = str.SubString(0, len);
            StringBuilder builder = new StringBuilder(str.Length)
            while(builder.Length < str.Length)
                builder.Append(sub);
            if(str == builder.ToString())
                return sub;
        }
    }
    return str;
}
private static string FindRepeat(string str)
{
    var lengths = Enumerable.Range(1, str.Length - 1)
        .Where(len => str.Length % len == 0);

    foreach (int len in lengths)
    {
        bool matched = true;

        for (int index = 0; matched && index < str.Length; index += len)
        {
            for (int i = index; i < index + len; ++i)
            {
                if (str[i - index] != str[i])
                {
                    matched = false;
                    break;
                }
            }
        }

        if (matched)
            return str.Substring(0, len);
    }

    return str;
}

请尝试以下正则表达式:

^(\w*?)\1*$

它捕获尽可能少的字符,其中捕获的序列和仅捕获的序列重复0次或更多次。根据Jacob的回答,您可以从随后的捕获中获得最短匹配的文本。

尝试以下正则表达式:

^(\w*?)\1*$

它捕获尽可能少的字符,其中捕获的序列和仅捕获的序列重复0次或更多次。根据Jacob的回答,您可以从随后的捕获中获得最短匹配的文本。

鉴于在第二个示例中是如何处理的,第一个示例的结果不也是ABCDABCDABCDABCDABCD吗?@SystemDown否,因为字符串重复。该字符串将仅包含重复文本。第二个例子重复了一次。555将得到5,但是,基本上返回最短的重复字符串?不,这仍然是最短的。最长的是字符串本身。鉴于在第二个示例中它是如何处理的,那么第一个示例的结果不是最长的吗?@SystemDown否,因为字符串重复。该字符串将仅包含重复文本。第二个例子重复了一次。555将得到5,但是,基本上返回最短的重复字符串?不,这仍然是最短的。最长的应该是字符串本身。这不起作用-给定AbcdAbcd,它会返回一个匹配的AbcdAbcd。我的错误,它需要?数量词相应地进行了编辑。只需再次测试,结果没有什么不同。然而,通过将其与我上面提出的正则表达式相结合,我想我成功地获得了一个工作正则表达式。这不起作用-鉴于AbcdAbcd,它给了我一个匹配的AbcdAbcd。我的错误,它需要?数量词相应地进行了编辑。只需再次测试,结果没有什么不同。然而,通过将其与我上面提出的正则表达式相结合,我想我成功地获得了一个工作正则表达式。这看起来比包括我在内的一些其他解决方案要好,因为在检查合适的子字符串时,您不需要分配新的字符串对象。但可能这取决于值字符串的大小,哪种解决方案表现最好?这看起来比包括我在内的其他一些解决方案要好,因为在检查合适的子字符串时,您不需要分配新的字符串对象。但可能这取决于值字符串的大小,哪种解决方案表现最好?