C# 从C中的重复字符串确定唯一字符串
我需要开发一个有效的算法来确定唯一的重复字符串,给定一个包含重复内容且仅包含重复内容的字符串 例如: ABCDABCDABCDABCDABCD=>Abcd 你好=>你好 我很难想出一个相当有效的算法;如有任何意见,将不胜感激 澄清:我想要一个最短的字符串,当重复足够多次时,它等于整个字符串。类似这样的内容: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+
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。我的错误,它需要?数量词相应地进行了编辑。只需再次测试,结果没有什么不同。然而,通过将其与我上面提出的正则表达式相结合,我想我成功地获得了一个工作正则表达式。这看起来比包括我在内的一些其他解决方案要好,因为在检查合适的子字符串时,您不需要分配新的字符串对象。但可能这取决于值字符串的大小,哪种解决方案表现最好?这看起来比包括我在内的其他一些解决方案要好,因为在检查合适的子字符串时,您不需要分配新的字符串对象。但可能这取决于值字符串的大小,哪种解决方案表现最好?