我有以下任务。有一个字符串。我必须按照6条规则进行替换,直到可以用字符串替换。
我找到的解决方案如下。它运作正常。问题是它的性能很低。我怎样才能根据多个规则进行更换?有算法吗?
P.S。这项任务来自鳕鱼网站。我的解决方案获得了100%的正确性和25%的性能。
class Test {
private Map<String,String> rules;
private void initRules(){
rules=new HashMap<>();
rules.put("AB", "AA");
rules.put("BA", "AA");
rules.put("CB", "CC");
rules.put("BC", "CC");
rules.put("AA", "A");
rules.put("CC", "C");
}
public String test(String S) {
initRules();
loop:while(true){
String oldString=S;
for (Map.Entry<String, String> rule : rules.entrySet())
{
S=S.replace(rule.getKey(), rule.getValue());
}
if (oldString==S){
break loop;
};
}
return S;
}
}
public class NewMain {
public static void main(String[] args) {
Test test=new Test();
System.out.println("Result:"+test.test("ABBCC"));;
}
}
答案 0 :(得分:6)
以下是您可以使用的算法:
假设:字符串仅由(A,B,C)
组成如果string仅由B's
组成(无A / C),则输出=输入字符串。
否则:
按以下方式划分字符串。如果子串由(B,A)或(B,C)组成,则将它们分开。分别替换为A和C.这将是答案。
例如。让字符串为:“BBBAABABBBCCBCBBCACB”。这将分为:
“BBBAABABBB”“CCBCBBC”“A”“CB”
这将导致输出字符串为:ACAC
基本上,只需忽略所有B's
,并将A's
的群集替换为A
,将C's
的群集替换为C
。
答案 1 :(得分:2)
你可以为此推理一个递归的算法。然后你可以减少规则并申请。例如 AB - &gt; AA,AA - &gt;然后是AB-> A 那么答案就是
public static String stringReduce(String s){
String transformed = s.replace("AA", "A").replace("CC", "C")
.replace("BC", "C").replace("CB", "C").replace("BA", "A")
.replace("AB", "A");
if(transformed.equals(s)){
return transformed;
}
else{
return stringReduce(transformed);
}
}
答案 2 :(得分:1)
我更喜欢while循环而不是递归:
以下是答案:
public String stringReduce(String input) {
String previous;
do {
previous = input;
input = input.replace("AA", "A").replace("CC", "C").replace("BC", "C").replace("CB", "C")
.replace("BA", "A").replace("AB", "A");
} while (!previous.equals(input));
return input;
}
答案 3 :(得分:0)
使用正则表达式在python中的我的解决方案。
说明:如果输入为“ABACAABBCA”。
首次迭代:将取代AB - &gt; A,AA-> A,BC-> C. strng的值是“AACACA”
迭代时的第二次:将取代AA-> A。 strng的值是“ACACA”
第三次迭代:无需替换,因此将退出并返回最终替换字符串(strng)。 如果需要任何改进或更正,请与我们联系。
def solution(strng):
prevS=""
subst={"AB":"A","BA":"A","CB":"C","BC":"C","AA":"A","CC":"C"}
subs=lambda st:subst[st.group(0)]
while prevS!=strng:
prevS=strng
strng=re.sub(r'(([A][BA])|([B][A])|([CB][C])|([C][B]))',subs,strng)
return strng
答案 4 :(得分:0)
我遵循@ vish4071的推理。
我寻找&#34; B&#34;的子串。和&#34; A&#34;只是,我知道这一部分将成为&#34; A&#34; 。子字符串相同&#34; B&#34;和&#34; C&#34;仅
&#34; BAABBABAB&#34;成为&#34; A&#34;由于replace("AB" by "AA"),replace("BA" by "AA"), replace("AA" by "A")
输入:&#34; BBBAABABBBCCBCBBCACB&#34;
&#34; BBBAABABBB&#34; &#34; CCBCBBC&#34; &#34; A&#34; &#34; CB&#34;
&#34; A&#34; &#34; C&#34; &#34; A&#34; &#34; C&#34;
输出:&#34; ACAC&#34;
这两个算法在子字符串&#34; A &#34;从/到&#34; C &#34;的变化。我追加已知的前一个字符。因为变更检测基于&#34; A &#34;到&#34; C &#34;或&#34; C &#34;到&#34; A &#34;,您不需要在第一个子字符串中使用前一个字符。在循环之后,你必须附加最后一个字符。
运行时复杂性:O(n)
空间复杂度:O(1)
这是Java中的实现。
public static String solution(String S) {
final char C = 'C';
final char A = 'A';
// if contains only B return itself
if(!S.contains("A") || !S.contains("C")) return S;
String res = "";
boolean hasLetterChanged = false;
char prevChar = 'D';
for(char c : S.toCharArray()){
if (c == A){
if (prevChar == C){hasLetterChanged = true;}
}else if(c == C){
if (prevChar == A){hasLetterChanged = true;}
}
if(hasLetterChanged){
res = res + prevChar;
hasLetterChanged = false;
}
if(c == A || c == C){
prevChar = c;
}
}
return res + prevChar;
}
这是Python 2.7中的实现(与3x兼容)。
def solution(S):
if not(S.__contains__('C') and S.__contains__('A')): return S
has_char_changed = False
prev_char = 'B'
A = 'A'
C = 'C'
res = ""
for c in S:
if c == A:
if prev_char == C:
has_char_changed = True
elif c == C:
if prev_char == A:
has_char_changed = True
if has_char_changed:
res = res + prev_char
has_char_changed = False
if c == A or c == C:
prev_char = c
return res + prev_char
if __name__ == '__main__':
assert solution("ABBCC") == "AC"
assert solution("BCBCABB") == "CA"
assert solution("BBBAABABBBCCBCBBCACB") == "ACAC"
assert solution("BBBBBBB") == "BBBBBBB"
答案 5 :(得分:0)
这是我的C#解决方案:
public static string solution(string S)
{
return Getreplace(S);
}
public static string Getreplace(string input)
{
string retval = input.Replace("AB", "AA")
.Replace("BA", "AA")
.Replace("CB", "CC")
.Replace("BC", "CC")
.Replace("AA", "A")
.Replace("CC", "C");
if (input == retval)
return retval;
else
return Getreplace(retval);
}