String 有趣字符串算法
给定两个长度分别为String 有趣字符串算法,string,algorithm,sequences,String,Algorithm,Sequences,给定两个长度分别为n的有限字符串序列A和B, 例如: A1: "kk", A2: "ka", A3: "kkk", A4: "a" B1: "ka", B2: "kakk", B3: "ak", B4: "k" 给出一个索引的有限序列,使其集中于 B给出了相同的字符串。允许重复 在本例中,我找不到解决方案,但例如,如果列表(1,2,2,4)是一个解决方案,则A1+A2+A2+A4=B1+B2+B2+B4。在这个例子中,只有两个字符,但已经很难了。事实上,用一个字符找到最短的解决方案甚至不是一
n
的有限字符串序列A
和B
,
例如:
A1: "kk", A2: "ka", A3: "kkk", A4: "a"
B1: "ka", B2: "kakk", B3: "ak", B4: "k"
给出一个索引的有限序列,使其集中于
B给出了相同的字符串。允许重复
在本例中,我找不到解决方案,但例如,如果列表(1,2,2,4)
是一个解决方案,则A1+A2+A2+A4=B1+B2+B2+B4
。在这个例子中,只有两个字符,但已经很难了。事实上,用一个字符找到最短的解决方案甚至不是一件小事
我试着去想事情。。例如,字符串长度的总和必须相等,对于第一个和最后一个字符串,我们需要相应的字符。但没有别的。我想对于某些字符串集来说,这根本是不可能的。谁能想出一个好的算法
编辑:显然,这是
没有算法可以决定这样一个实例是否有解决方案。如果有,停车问题可以解决。肮脏的把戏…这个问题很难回答,但我会试一试。这更多的是一种意识流,而不是一个事先道歉的回答 如果我理解正确的话,你会得到两个大小相等的字符串序列,A和B,从1..n开始索引。然后,您必须找到一个索引序列,使得字符串a(1)…a(m)的串联等于字符串B(1)…B(m)的串联,其中m是索引序列的长度 我观察到的第一件事是,可能有无限多的解。例如,假设: A{“x”,“xx”}
B{“xx”,“x”} 可能的解决办法是: {1,2}
{2,1}
{1,2,1,2}
{1,2,2,1}
{2,1,1,2}
{2,1,2,1}
{1,2,1,2,1,2}
那你怎么知道什么时候该停下来?只要你有一个解决方案?只要一个解是另一个解的超集 您可以从两个集合中取最小公共长度的所有字符串开始(在我上面的示例中,您可以取“x”然后,您可以对下一个大小的字符串重复此操作。例如,如果第一个集合有3个长度分别为1、2和3的字符串,而第二个集合有3个长度分别为1、3和3的字符串,则您将获取长度为3的字符串。您可以这样做,直到没有更多字符串。如果您找到任何字符串,那么您就有了问题的解决方案 然后,当您必须开始组合多个字符串(如我上面的示例中所示)时,情况会变得更加困难。天真、暴力的方法是开始排列两个集合中的所有字符串,当连接时,这些字符串会产生相同长度的字符串,然后对它们进行比较。因此,在下面的示例中: A{“ga”、“bag”、“ac”、“A”}
B{“ba”、“g”、“ag”、“gac”} 您可以从长度为2的序列开始: A{“ga”,“ac”},B{“ba”,“ag”}(指数1,3)
A{“bag”,“A},B{“g”,“gac}(指数2,4) 比较得出“gaac”与“baag”以及“baga”与“ggac”,两者都不相等,因此没有解决方案。接下来,我们将讨论长度为3的序列: A{“ga”,“bag”,“A”},B{“ba”,“g”,“gac”}(指数1,2,4)
A{“bag”、“ac”、“A”},B{“g”、“ag”、“gac”}(指数2、3、4) 同样,没有解,所以我们最终得到大小为4的序列,其中我们没有解 现在它变得更加棘手,因为我们必须开始考虑重复一些指数,现在我的大脑正在融化
我想在字符串中寻找公共子序列可能会有所帮助,然后使用字符串中未匹配的其余部分。但我不太清楚如何使用。一个非常简单的方法就是使用类似广度优先搜索的方法。这还有一个优点,即找到的第一个解决方案的大小最小。H建议使用暴力搜索。首先生成与列表长度相关的数字序列: [0,0,…] [1,0,..] [2,0,..] [3,0,..] [0,1,..] 数字序列长度决定在找到的任何解决方案中有多少字符串。 然后使用数字作为字符串列表的索引生成A和B字符串:
public class FitSequence
{
private readonly string[] a;
private readonly string[] b;
public FitSequence(string[] a, string[] b)
{
this.a = a;
this.b = b;
}
private static string BuildString(string[] source, int[] indexes)
{
var s = new StringBuilder();
for (int i = 0; i < indexes.Length; ++i)
{
s.Append(source[indexes[i]]);
}
return s.ToString();
}
public IEnumerable<int[]> GetSequences(int length)
{
foreach (var numberSequence in new NumberSequence(length).GetNumbers(a.Length - 1))
{
string a1 = BuildString(a, numberSequence);
string b1 = BuildString(b, numberSequence);
if (a1 == b1)
yield return numberSequence;
}
}
}
公共类序列
{
私有只读字符串[]a;
私有只读字符串[]b;
公共序列(字符串[]a,字符串[]b)
{
这个a=a;
这个.b=b;
}
私有静态字符串BuildString(字符串[]源,int[]索引)
{
var s=新的StringBuilder();
for(int i=0;i
该算法假定A和B的长度相等。
我测试了你的例子
static void Main(string[] args)
{
var a = new[] {"kk", "ka", "kkk", "a"};
var b = new[] {"ka", "kakk", "ak", "k"};
for (int i = 0; i < 100; ++i)
foreach (var sequence in new FitSequence(a, b).GetSequences(i))
{
foreach (int x in sequence)
Console.Write("{0} ", x);
Console.WriteLine();
}
}
static void Main(字符串[]args)
{
var a=新[]{“kk”、“ka”、“kkk”、“a”};
var b=新[]{“ka”、“kakk”、“ak”、“k”};
对于(int i=0;i<100;++i)
foreach(新FitSequence(a,b)中的var序列。GetSequences(i))
{
foreach(按顺序输入x)
Console.Write(“{0}”,x);
Console.WriteLine();
}
}
但是找不到任何解决方案,尽管它似乎适用于简单的测试。不清楚您要寻找的“解决方案”是什么,最长的解决方案?最短的解决方案?所有解决方案?
既然你允许在那里重复
// assumed true/false functions
let Eq aList bList =
// eg Eq "ab"::"c" "a" :: "bc" -> true
// Eq {} {} is _false_
let EitherStartsWith aList bList =
// eg "ab"::"c" "a" :: "b" -> true
// eg "a" "ab" -> true
// {} {} is _true_
let rec FindMatches A B aList bList level
= seq {
if level > 0
if Eq aList bList
yield aList
else if EitherStartsWith aList bList
Seq.zip3 A B seq {1..}
|> Seq.iter (func (a,b,i) ->
yield! FindMatches A B aList::(a,i) bList::(b,i) level - 1) }
let solution (A:seq<string>) (B:seq<string>) length =
FindMatches A B {} {} length
let solution (A:seq<string>) (B:seq<string>) length =
let starts = {}
let ends = {}
Seq.zip3 A B seq {1..}
|> Seq.iter(fun (a,b,i) ->
if (a.StartsWith(b) or b.StartsWith(a))
start = starts :: (a,b,i)
if (a.EndsWith(b) or b.EndsWith(a))
ends = ends :: (a,b,i))
if List.is_empty starts || List.is_empty ends
Seq.empty // no solution
else
Seq.map (fun (a,b,i) ->
FindMatches A B {} :: (a,i) {} :: (b,i) length - 1)
starts
|> Seq.concat