2009-05-04 9 views
11

मेरे पास "\ b \ bfoo \ bx" जैसे किसी अन्य स्रोत से एक स्ट्रिंग पढ़ी गई है। इस मामले में, यह "फॉक्स" शब्द का अनुवाद करेगा क्योंकि पहले 2 \ बी को अनदेखा किया जाता है, और अंतिम 'ओ' मिटा दिया जाता है, और फिर 'x' के साथ बदल दिया जाता है। इसके अलावा एक और मामला "पैट \ बी \ बी \ बी \ बी \ बी \ बी \ बी \ बी \ बी \ बीएफयू" का अनुवाद किया जाना चाहिए "foo"स्ट्रिंग से बेहतर तरीका है। स्ट्रिंग से बैकस्पेस को हटाने के लिए बदलें?

मैं स्ट्रिंग का उपयोग करके कुछ लेकर आया हूं। बदलें, लेकिन यह जटिल है और मुझे चिंता है कि यह सही ढंग से काम नहीं कर रहा है, यह भी कई नई स्ट्रिंग ऑब्जेक्ट्स बना रहा है जिन्हें मैं टालना चाहता हूं।

कोई विचार?

+1

क्या आपने नियमित अभिव्यक्ति का उपयोग करने पर विचार किया है? – Jagd

+0

@Jagd आप किस रेगेक्स की सिफारिश करेंगे?मैं एक और अधिक सुरुचिपूर्ण समाधान की तलाश में हूं। लगभग किसी भी भाषा/रेगेक्स स्वाद ठीक है, मैं विशेष रूप से बैश और रूबी के संयोजन का उपयोग कर अपने टेक्स्ट एडिटर – Brandon

उत्तर

12

शायद सबसे आसान स्ट्रिंग पर बस फिर से शुरू करना सबसे आसान है। आपके इनपुट को देखते हुए, निम्नलिखित कोड में चाल 1-पारित

public string ReplaceBackspace(string hasBackspace) 
{ 
    if(string.IsNullOrEmpty(hasBackspace)) 
     return hasBackspace; 

    StringBuilder result = new StringBuilder(hasBackspace.Length); 
    foreach (char c in hasBackspace) 
    { 
     if (c == '\b') 
     { 
      if (result.Length > 0) 
       result.Length--; 
     } 
     else 
     { 
      result.Append(c); 
     } 
    } 
    return result.ToString(); 
} 
+1

सरल। सीधा। समझने में आसान। –

+0

मुझे लंबाई - चाल के बारे में पता नहीं था, यह साफ है। मैं sb.Remove() महंगा होने के बारे में चिंतित था। – esac

+0

लंबाई - चालाक है। – mquander

-1

एक स्ट्रिंगबिल्डर बनाएं और बैकस्पेस वर्णों के अलावा सब कुछ पर कॉपी करें।

+0

को स्क्रिप्ट करने के लिए उपयोग कर रहा हूं, मुझे स्ट्रिंग से वर्णों को भी हटाने की ज़रूरत है और अगर केवल संबंधित बैकस्पेस है, न केवल बैकस्पेस अक्षर। – esac

2

आप स्ट्रिंग पिछड़े के माध्यम से फिर से चल सकते हैं, जिससे आप एक चरित्र सरणी बनाते हैं। हर बार जब आप बैकस्पेस दबाते हैं, काउंटर बढ़ाते हैं, और हर बार जब आप एक सामान्य चरित्र हिट करते हैं, तो अगर आपका काउंटर शून्य न हो और काउंटर कम हो जाए तो इसे छोड़ दें।

मुझे यकीन नहीं है कि सबसे अच्छा सी # डेटा संरचना इसका प्रबंधन करने के लिए क्या है और फिर स्ट्रिंग को बाद में सही क्रम में प्राप्त करने में सक्षम हो। StringBuilder में Insert विधि है लेकिन मुझे नहीं पता कि यह प्रारंभ में वर्णों को सम्मिलित रखने के लिए सक्षम होगा या नहीं। आप पात्रों को एक स्टैक में डाल सकते हैं और अंत में ToArray() हिट कर सकते हैं - जो शायद तेज़ हो या न हो।

6

जिस तरह से मैं इसे करूँगा वह कम तकनीक है, लेकिन समझने में आसान है।

वर्णों का एक ढेर बनाएं। फिर शुरुआत से अंत तक स्ट्रिंग के माध्यम से फिर से शुरू करें। यदि चरित्र एक सामान्य चरित्र (गैर-स्लैश) है, तो इसे ढेर पर दबाएं। यदि यह एक स्लैश है, और अगला चरित्र 'बी' है, तो स्टैक के शीर्ष पर पॉप करें। यदि ढेर खाली है, तो इसे अनदेखा करें।

अंत में, प्रत्येक चरित्र को बदले में पॉप करें, इसे स्ट्रिंगबिल्डर में जोड़ें, और परिणाम को उलट दें।

+0

यह मेरी विधि से क्लीनर है। +1। – mquander

+0

यह अच्छा है, हालांकि मेरा मतलब शाब्दिक बच निकला चरित्र 'बी' है, इसलिए मुझे अगले चरित्र की तुलना 'बी' होने की तुलना करने की आवश्यकता नहीं होगी, लेकिन यह अभी भी काम करता है। इस विधि को देखते हुए, मेरे पास एकमात्र 'समस्या' है कि मुझे एक ऐरे करना है। विधि के अंत में रिवर्स .. एक महंगा ऑपरेशन नहीं, लेकिन इच्छा है कि मैं इसे उलटने के बिना कर सकता हूं :) – esac

+0

आप उन्हें स्टैक से हटाकर क्रम में एक वर्ण सरणी में पॉप कर सकते हैं; यानी चार [] अक्षरों = नए चार [ढेर। गणना]; के लिए (int i = stack.Count - 1; i> = 0; i--) अक्षरों [i] = stack.Pop(); स्ट्रिंग परिणाम = नई स्ट्रिंग (अक्षर); – mquander

0
String myString = "patt\b\b\b\b\b\b\b\b\b\bfoo"; 
     List<char> chars = myString.ToCharArray().ToList(); 
     int delCount = 0; 

     for (int i = chars.Count -1; i >= 0; i--) 
     { 
     if (chars[i] == '\b') 
     { 
      delCount++; 
      chars.RemoveAt(i); 
     } else { 
      if (delCount > 0 && chars[i] != null) { 
      chars.RemoveAt(i); 
      delCount--; 
      } 
     } 
     } 
0

मैं इस तरह जाना चाहते हैं करता है: कोड का परीक्षण नहीं किया है

char[] result = new char[input.Length()]; 
int r =0; 
for (i=0; i<input.Length(); i++){ 
if (input[i] == '\b' && r>0) r--; 
else result[r]=input[i]; 

} 

string resultsring = result.take(r); 
3

रेगुलर एक्सप्रेशन संस्करण:

var data = @"patt\b\b\b\b\b\b\b\b\b\bfoo"; 
var regex = new Regex(@"(^|[^\\b])\\b"); 

while (regex.IsMatch(data)) 
{ 
    data = regex.Replace(data, ""); 
} 

अनुकूलित संस्करण (और यह एक बैकस्पेस '\ ख' और नहीं तार के साथ "\ ख") के साथ काम करता है:

var data = "patt\b\b\b\b\b\b\b\b\b\bfoo"; 
var regex = new Regex(@"[^\x08]\x08", RegexOptions.Compiled); 

while (data.Contains('\b')) 
{ 
    data = regex.Replace(data.TrimStart('\b'), ""); 
} 
3
public static string ProcessBackspaces(string source) 
{ 
    char[] buffer = new char[source.Length]; 
    int idx = 0; 

    foreach (char c in source) 
    { 
     if (c != '\b') 
     { 
      buffer[idx] = c; 
      idx++; 
     } 
     else if (idx > 0) 
     { 
      idx--; 
     } 
    } 

    return new string(buffer, 0, idx); 
} 

संपादित

मैं जवाब में पोस्ट कोड की एक त्वरित, किसी न किसी बेंचमार्क किया है अब तक (प्रश्न से दो उदाहरण स्ट्रिंग को प्रोसेस करना, प्रत्येक मिलियन बार):

ANSWER     | TIME (ms) 
------------------------|----------- 
Luke (this one)  |  318 
Alexander Taran  |  567 
Robert Paulson   |  683 
Markus Nigbur   |  2100 
Kamarey (new version) |  7075 
Kamarey (old version) |  30902 
+0

आपका कोड तेज़ है, लेकिन थोड़ा सा गलत है। यह टेस्ट केस 'फॉक्स \ बी \ बी \ बी \ bfor' के लिए विफल रहता है जो "के लिए" उपज करना चाहिए (यूनिट परीक्षणों के लिए भलाई धन्यवाद :)) क्योंकि idx = 0 अंतिम \ b पर है, इसलिए यह इसे चार में डाल देता है बफर। यहां निश्चित भाग है: यदि (सी == '\ बी') { यदि (idx> 0) { idx--; } } अन्य { बफर [idx] = c; आईडीएक्स ++; } – esac

+0

बस त्वरित टिप्पणी ल्यूक, इस कोड में एज-केस बग है जब बैकस्पेस की एक अजीब संख्या है जो 'if ((c ==' \ b ') && (idx> 0) के कारण शुरुआत में इसे रिवाइंड करती है।) 'एक प्रारंभिक \ बी चरित्र छोड़ देता है। जब idx = 0, आप आउटपुट में \ b जोड़ रहे हैं। –

+0

@esac, @Robert, अच्छी तरह से देखा! मैंने उस बग को ठीक करने के लिए अद्यतन किया है। – LukeH

संबंधित मुद्दे