2015-10-26 127 views
0

編寫一個算法來檢查給定字符串s是否可以由另外兩個字符串part1part2組成。合併字符串檢查器(自定義規則)

限制是part1part2中的字符與s中的字符順序相同。

例子:

'codewars' is a merge from 'cdw' and 'oears': 

s: c o d e w a r s = codewars 
part1: c d w   = cdw 
part2: o e a r s = oears 

但在測試案例,它不是那麼容易使其工作..

規則說,他們必須是相同的長度和相同的順序,但隨機測試用例被放入隨機順序中。 所以規則與規則衝突,所以我如何使它工作?

[Test] 
public void SadPath2() 
{ 
    Assert.IsFalse(StringMerger.isMerge("codewars", "code", "wasr"), "Codewars can't be created from code and wasr"); 
} 
SadPath2 == false; 

[Test] 
public void SadPath1() 
{ 
    Assert.IsFalse(StringMerger.isMerge("codewars", "cod", "wars"), "Codewars are not codwars"); 
} 
SadPath1 == false; 

[Test] 
public void HappyPath2() 
{ 
    Assert.IsTrue(StringMerger.isMerge("codewars", "cdwr", "oeas"), "codewars can be created from cdwr and oeas"); 
} 
HappyPath2 == true; 

[Test] 
public void HappyPath1() 
{ 
    Assert.IsTrue(StringMerger.isMerge("codewars", "code", "wars"), "codewars can be created from code and wars"); 
} 
HappyPath1 == true; 

可能不遵守規則的徹底一些隨機測試:

遵循的規則測試用例

[Test] 
public void RandomTest() 
{ 
    Assert.IsTrue(StringMerger.isMerge("[W`meSnw(R1qaLLqc[=]=UAvTa_3%", "W`mnwqaLL]=va%", "[eS(R1qc[=UAT_3"), "'[W`meSnw(R1qaLLqc[=]=UAvTa_3%' is a merge of 'W`mnwqaLL]=va%' and '[eS(R1qc[=UAT_3'"); 
}  
RandomTest == true; 

[Test] 
public void RandomTest2() 
{ 
    Assert.IsTrue(StringMerger.isMerge("]ftUNn7-XoX4AZ3i1+", "U7oX4A1+", "]ftNn-XZ3i"), "']ftUNn7-XoX4AZ3i1+' is a merge of 'U7oX4A1+' and ']ftNn-XZ3i"); 
} 
RandomTest2 == true; 

第一個例子在我的課堂,它可以成功地運行所有測試SadPath2

public class StringMerger 
{ 
    public static bool isMerge(string s, string part1, string part2) 
    { 
     int num = 0; 
     string txt1 = ""; 
     Console.WriteLine("S - " + s + " - P1 - " + part1 + " - P2 - " + part2); 

     #region Sorting 
     foreach (var itm in s) 
     { 
      if (part1.Contains(itm.ToString())) 
       num++; 
      else if (part2.Contains(itm.ToString())) 
       num++; 
     } 
     #endregion 

     if (num == s.Length && num == (part1.Length + part2.Length)) 
       return true; 


     return false; 
    } 
} 

enter image description here

第二個例子在那裏可以運行所有除了隨機測試:用Kvam答案

public class StringMerger 
{ 
    public static bool isMerge(string s, string part1, string part2) 
    { 
     int num = 0; 
     int P1 = 0; 
     int P2 = 0; 
     bool p2 = false; 
     string txt1 = ""; 

     #region Sorting 
     foreach (var itm in s) 
     { 
      if (part1.Contains(itm.ToString())) 
       num++; 
      else if (part2.Contains(itm.ToString())) 
       num++; 

      try 
      { 
       if (p2 == false) 
       { 
        txt1 = txt1 + GetLetterP1(part1, itm.ToString(), P1); 
        P1++; 
        p2 = true; 
       } 
       else 
       { 
        txt1 = txt1 + GetLetterP2(part2, itm.ToString(), P2); 
        P2++; 
        p2 = false; 
       } 
      } 
      catch { } 
     } 
     #endregion 

     if (num == s.Length && num == (part1.Length + part2.Length)) 
     { 
      if (s.Contains(part1 + part2)) 
       return true; 
      else if (txt1 == s) 
       return true; 
     } 


     return false; 
    } 

    static string GetLetterP1(string p1, string letter, int n) 
    { 
     string itm = ""; 
     if (p1.Contains(letter)) 
      itm = p1[n].ToString(); 
     return itm; 
    } 

    static string GetLetterP2(string p2, string letter, int n) 
    { 
     string itm = ""; 
     if (p2.Contains(letter)) 
      itm = p2[n].ToString(); 
     return itm; 
    } 
} 

enter image description here

結果:(使用最新的補丁)

enter image description here

結果用Max答案:(用最新的修補程序)

enter image description here

結果與codersl答:(使用最新的補丁)

enter image description here

+0

讓我得到這個直。你有一個從兩個字符串合併的字符串,你想檢查一個特定的字符串是否被兩個字符串合併爲輸入?防爆。用你的例子。'codewars'是'code'和'wars'的合併,所以對'codewars','code','wars'進行檢查應該返回true,其中'codewars','cdoe','wars'應該返回false ? – Bauss

+0

是的,這是正確的。 – ArchAngel

+0

@Bauss從第一行問題來看:「'codewars'是'cdw'和'oears'的合併,所以不僅子字符串,而且還包括子合約 – Max

回答

2

我想這應該覆蓋的要求,雖然你可能要重寫,以避免各地字符串創建。

public bool IsMatch(string target, string part1, string part2) 
{ 
    if (target.Length != part1.Length + part2.Length) 
    { 
     return false; 
    } 
    if (target == "") 
    { 
     return true; 
    } 

    if (part1.Length > 0 && target[0] == part1[0]) 
    { 
     if (IsMatch(target.Substring(1), part1.Substring(1), part2.Substring(0))) 
     { 
      return true; 
     } 
    } 
    if (part2.Length > 0 && target[0] == part2[0]) 
    { 
     if (IsMatch(target.Substring(1), part1.Substring(0), part2.Substring(1))) 
     { 
      return true; 
     } 
    } 

    return false; 
} 
+0

在第一眼看起來效果很好,但不能處理所有的隨機..不完美,但一個良好的開始.. – ArchAngel

+0

我會在一瞬間更新您的更新答案中的圖像.. – ArchAngel

+0

您的代碼幾乎完美有兩個'索引超出範圍'錯誤。 – ArchAngel

0

這裏我的2美分

public bool IsMerge(string target, string part1, string part2) 
{ 
    if (String.IsNullOrEmpty(target)) 
    { 
     throw new ArgumentNullException("target"); 
    } 

    if (String.IsNullOrEmpty(part1)) 
    { 
     throw new ArgumentNullException("part1"); 
    } 

    if (String.IsNullOrEmpty(part2)) 
    { 
     throw new ArgumentNullException("part2"); 
    } 

    if (target.Length == (part1.Length + part2.Length)) 
    { 
     return this.IsPart(target, part1) && this.IsPart(target, part2); 
    } 

    return false; 
} 

private bool IsPart(string target, string part) 
{ 
    int idx = -1; 
    int lastIdx = 0; 

    for (int i = 0; i < part.Length; i++) 
    { 
     idx = (target.IndexOf(part[i], lastIdx)); 
     if (!(idx > -1)) 
     { 
      return false; 
     } 

     lastIdx = idx; 
    } 

    return true; 
} 
+0

你的代碼無法處理Random測試.. – ArchAngel

+0

你是對的。固定代碼。 – Max

+0

你可以看到你的代碼在我剛剛添加的圖像上做得有多好。 – ArchAngel

0

我的2美分

public static void Main() 
{ 
    Console.WriteLine(Check("codewars", "code", "wasr")); //false 
    Console.WriteLine(Check("codewars", "cod", "wars")); //false 
    Console.WriteLine(Check("codewars", "cdwr", "oeas")); 
    Console.WriteLine(Check("codewars", "code", "wars")); 
    Console.WriteLine(Check("[W`meSnw(R1qaLLqc[=]=UAvTa_3%", "W`mnwqaLL]=va%", "[eS(R1qc[=UAT_3")); 
    Console.WriteLine(Check("]ftUNn7-XoX4AZ3i1+", "U7oX4A1+", "]ftNn-XZ3i")); 
    Console.WriteLine(Check("acab", "ab", "ac")); 
    Console.WriteLine(Check("b]aDw- !oKJnOJ", "b]aDwoKJ", "- !nOJ")); 
    Console.WriteLine(Check("codewars", "codewarss", "")); //false 
    Console.WriteLine(Check("codewars", "", "")); //false 
    Console.WriteLine(Check("codewars", "codewars", null)); 
    Console.WriteLine(Check("Bananas from Bahamas", "Bahas", "Bananas from am")); 
} 

private static bool Check(string s, string part1, string part2) 
{ 
    if (part1 == null) 
     part1 = ""; 

    if (part2 == null) 
     part2 = ""; 

    var part1Index = 0; 
    var part2Index = 0; 
    var bothMatch = ""; 

    foreach(var c in s) 
    { 
     // handle both strings matching 
     if (part1Index < part1.Length && part2Index < part2.Length && c == part1[part1Index] && c == part2[part2Index]) 
     { 
      bothMatch += c; 
      part1Index++; 
      part2Index++; 
      continue; 
     } 

     if (bothMatch.Length > 0 && c == part1[part1Index]) 
     { 
      // part2 doesn't match anymore so roll back its index 
      part2Index -= bothMatch.Length; 
      bothMatch = ""; 
     } 
     else if (bothMatch.Length > 0 && c == part2[part2Index]) 
     { 
      // part1 doesn't match anymore so roll back its index 
      part1Index -= bothMatch.Length; 
      bothMatch = ""; 
     } 

     // handle one string matching 
     if (part1Index < part1.Length && c == part1[part1Index]) 
     { 
      //Console.WriteLine("c={0}, p1={1}", c, part1[part1Index]); 
      part1Index++; 
      continue; 
     } 
     if (part2Index < part2.Length && c == part2[part2Index]) 
     { 
      //Console.WriteLine("c={0}, p2={1}", c, part2[part2Index]); 
      part2Index++; 
      continue; 
     } 

     //Console.WriteLine("c={0}, p1={1}, p2={2}, both={3}", c, part1[part1Index], part2[part2Index], bothMatch); 
     return false; 
    } 
    return (part1Index == part1.Length) && (part2Index == part2.Length); 
} 
+0

這會導致輸入s:「acab」,part1:「ab」,part2:「ac」失敗。 – Kvam

+0

嗯..好點。更新。 – codersl

+0

你可以看到你的代碼在我剛剛添加的圖像中的表現如何。 – ArchAngel