[英]Strategy to replace spaces in string
我需要存儲一個用某些字符替換其空格的字符串。 當我找回它時,我需要再次用空格替換字符。 我已經考慮過這種策略,在存儲時我將替換(用_a表示空格)和(_a用_aa表示),而檢索時將替換(用空格的_a表示)和(用_a的_aa表示)。 即,即使用戶在字符串中輸入_a也會被處理。 但是我不認為這是一個好策略。 請讓我知道是否有人有更好的選擇?
的東西更換空間是一個問題,當事情已經是的字符串中。 為什么不簡單地對字符串進行編碼-有很多方法可以做到這一點,一種方法是將所有字符都轉換為十六進制。
例如
Hello world!
編碼為
48656c6c6f20776f726c6421
空格為0x20。 然后,您只需將字符串解碼回(十六進制為ascii)即可。
這樣,編碼字符串中就沒有空格。
- 編輯 -優化-
您可以用%xx
替換字符串中的所有%
和所有空格,其中xx
是字符的十六進制代碼。
例如
Wine having 12% alcohol
變成
Wine%20having%2012%25%20alcohol
這樣, %
和 (空格)不再是問題-解碼很容易。
編碼算法
- replace all `%` with `%25`
- replace all ` ` with `%20`
解碼算法
- replace all `%xx` with the character having `xx` as hex code
(你甚至可以優化更多,因為你需要編碼只有兩個字:使用%1
的%
和%2
對 ,但我建議您使用
%xx
解決方案,因為它具有更高的可移植性-如果以后需要編碼更多字符,可以稍后使用)
我不確定您的解決方案是否有效。 在閱讀時,如何區分最初為" a"
字符串和最初為"_a"
字符串:如果我理解正確,則兩者都將以"_aa"
結尾。
通常,在某種情況下,特定的字符集不能這樣顯示,而必須進行編碼,解決方案是選擇一個允許的字符作為“轉義”字符,將其從允許的字符集中刪除,並對所有字符進行編碼禁止字符(包括轉義字符)中的兩個字符序列(以轉義字符開頭)。 例如,在C ++中,字符串或字符文字中不允許換行。 轉義字符為\\
; 因此,還必須將其編碼為轉義序列。 因此,對於新行,我們有"\\n"
( n
的選擇是任意的),對於\\
是"\\\\"
。 (對於第二個字符, \\
的選擇也是任意的,但是使用轉義的轉義字符表示自己是很平常的。)在這種情況下,如果要使用_
作為轉義字符,請使用"_a"
代表一個空格,邏輯上的選擇是代表一個_
"__"
(但我建議在視覺上更具啟發性-可能是^
作為轉義符,其中"^_"
代表一個空格, "^^"
代表a ^
)。 閱讀時,無論何時看到轉義字符,都必須映射以下字符(如果不是預定義的映射之一,則輸入文本有誤)。 這很容易實現,而且非常可靠; 唯一的缺點是,在極端情況下,它會使字符串的大小加倍。
您想使用C / C ++來實現嗎? 我認為您應該將字符串分成多個部分,並以空格分隔。
如果您的字符串是這樣的:“ a__b”(連續多個空間),它將被拆分為:
sub[0] = "a";
sub[1] = "";
sub[2] = "b";
希望這會有所幫助!
對於使用X個字符的普通字符串,您不能僅使用1個字符/輸入字符使用x-1編寫或編碼字符串。 您可以使用2個字符的組合來替換給定字符(這正是您在示例中嘗試的字符)。
為此,請遍歷字符串以計算空格的出現及其長度,然后創建一個新的字符數組,並用“ //”替換這些空格,但這只是一個示例。 這種方法的問題在於,輸入字符串中不能包含“ //”。
另一種方法是使用很少使用的字符(例如“ ^”)替換空格。
最后一種方法在這兩種方法的組合中很流行。 在Unix和php中使用它來將語法字符作為字符串中的文字。 如果您想要一個“”,只需將其寫為“ \\”等。
為什么不使用替換功能
String* stringWithoutSpace= stringWithSpace->Replace(S" ", S"replacementCharOrText");
所以現在stringWithoutSpace不包含空格。 當您想把這些空間放回去時,
String* stringWithSpacesBack= stringWithoutSpace ->Replace(S"replacementCharOrText", S" ");
我想這個問題比出現的更多。 例如,您要存儲的字符串不僅必須沒有空格,而且還必須看起來像單詞或類似的東西。 您應該清楚自己的要求(並且可以考慮通過解釋為什么需要這樣做來滿足觀眾的好奇心。)
編輯:正如JamesKanze在評論中指出的那樣,在您可以連續使用多個空間的情況下,以下內容將不起作用。 但是我還是把它留在這里,以供歷史參考。 (我對其進行了修改以壓縮連續的空間,因此至少會產生明確的輸出。)
std::string out;
char prev = 0;
for (char ch : in) {
if (ch == ' ') {
if (prev != ' ') out.push_back('_');
} else {
if (prev == '_' && ch != '_') out.push_back('_');
out.push_back(ch);
}
prev = ch;
}
if (prev == '_') out.push_back('_');
我認為僅編碼為十六進制的ascii是一個好主意,但是當然會使所需的存儲量增加一倍。
如果要使用較少的內存來執行此操作,則將需要兩個字母的序列,並且必須小心以方便返回。
例如,您可以用_a
替換空格,但是您還需要注意轉義符_
。 為此,將每個_
替換為__
(兩個下划線)。 您需要掃描一次字符串,然后同時進行兩個替換。
這樣,在結果文本中,所有原始下划線都會加倍,並且下划線的唯一出現是在_a
組合中。 您可以放心地將其翻譯回來。 每當您看到下划線時,您都需要將數字加注為1,然后再查看。 如果跟隨a
,則之前是空白。 如果_
跟在后面,則之前是下划線。
請注意,關鍵是要替換原始字符串中的轉義字符( _
),而不是將空白映射到的字符序列。 您的想法是替換_a
換行符。 因為您不知道_aa
最初是_a
還是a
(空格后跟a)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.