2012-10-12 216 views
0

我需要存儲一個字符串,用某些字符替換它的空格。當我找回時,我需要再次用空格替換字符。我已經想到這個策略,而存儲我將替換(空間與_a)和(_a與_aa),而檢索將取代(_a與空間)和(_aa與_a)。即使用戶在字符串中輸入了_a,它也將被處理。但我不認爲這是一個好策略。請讓我知道如果有人有更好的?替換字符串空格的策略

+7

你的外在問題是什麼?爲什麼你需要替換字符串中的空格? –

+1

我想知道的是如果你的原始字符串包含_aa然後你將如何區分將會發生什麼... –

+0

這裏有更多。我只知道它... – WhozCraig

回答

0

你想使用C/C++來實現這個嗎?我想你應該把你的字符串分成多個部分,用空格分開。

如果你的字符串是這樣的: 「a__b」(多空間連續),它將被splited到:

sub[0] = "a"; 
sub[1] = ""; 
sub[2] = "b"; 

希望這將幫助!

0

對於使用X字符的普通字符串,不能使用x-1只使用1個字符/輸入字符來編寫或編碼字符串。 您可以使用2個字符的組合來替換給定的字符(這正是您在示例中所嘗試的)。

要做到這一點,循環你的字符串來計算空間的外觀結合其長度,創建一個新的字符數組,並用「//」替換這些空格,但這只是一個例子。這種方法的問題是你的輸入字符串中不能有「//」。

另一種方法是使用很少使用的字符,例如「^」來替換空格。

最後一種方法,在這兩種方法的組合中流行。它用在unix中,並且php在字符串中具有語法字符作爲文字。如果你想擁有一個「」「你可以將它寫成\」等

0

你爲什麼不使用替換功能

String* stringWithoutSpace= stringWithSpace->Replace(S" ", S"replacementCharOrText"); 

所以現在stringWithoutSpace不包含空格。當你想要把這些空間回去,

String* stringWithSpacesBack= stringWithoutSpace ->Replace(S"replacementCharOrText", S" "); 
+0

正如原來的海報已經注意到的,如果'replacementCharOrText'已經出現在原始字符串中,這將不起作用。 – Zane

+1

在C++(也就是C)中沒有這樣的函數。 –

2

更換空間與東西是一個問題,當東西已經是的字符串中。爲什麼不簡單地編碼字符串 - 有很多方法可以做到這一點,其中一種方法是將所有字符轉換爲十六進制。

例如

Hello world! 

被編碼爲

48656c6c6f20776f726c6421 

的空間爲0x20。然後你簡單地解碼回(十六進制ascii)字符串。
這種方式在編碼字符串中沒有空格。

- 編輯 - 優化 -

您與%xx替換所有%和所有的空格串在xx是字符的十六進制代碼。

例如

Wine having 12% alcohol 

變得

Wine%20having%2012%25%20alcohol 
  • %20是空間
  • %25%字符

這樣,既不%也不(空間)已經成爲一個問題 - 解碼很簡單。

編碼算法

- replace all `%` with `%25` 
    - replace all ` ` with `%20` 

解碼算法

- replace all `%xx` with the character having `xx` as hex code 

(你甚至可以優化更多,因爲你需要編碼只有兩個字:使用%1%%2,但我建議因爲它更便攜 - 如果您需要編碼更多字符,稍後可以使用它)

+1

這確實解決了問題(雖然有更高效的編碼--- base64或類似的東西)。另一方面,它系統地將字符串的大小加倍,並使人們閱讀它有點問題。這些可能是也可能不是問題(因爲他沒有說出爲什麼他需要去除空間),但可能需要考慮。 –

+0

請參閱編輯。 –

+0

編輯建議的是URL轉義編碼。其優點是可以找到開源軟件來完成已經編寫的程序,並且它是完全可擴展的:您定義合法字符列表,如果該字符不在列表中,則將其替換。 (也許以後他將不得不取代換行符,例如。) –

0

我猜測這個問題比看起來更多;例如,你所存儲的字符串不僅必須沒有空格,而且還必須看起來像單詞或其他類似的字符。你應該清楚你的要求(你可能會考慮通過解釋爲什麼你需要做這樣的事情來滿足觀衆的好奇心。)

編輯:正如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('_'); 
+0

這不起作用。考慮'「_」'和的輸出(抱歉關於格式化,但我找不到任何方式在這個框中有兩個空格的字符串---「 」似乎不起作用)。 –

+0

@JamesKanze:很對。 *我在想什麼?我考慮糾正它,但我認爲在大多數情況下,逃避每個角色都更簡單,成本也不會太高。 – rici

1

我不知道你的解決方案會奏效。在閱讀時, 如何區分" a"的字符串和 最初是"_a"的字符串:如果我理解正確,兩者都將結束 "_aa"

一般情況下,給出的情況是特定的一組字符不能出現,但是必須進行編碼,解決方法是選擇一個允許字符作爲「轉義」字符,將其從一組中刪除 允許的字符,並將所有被禁止的字符 (包括轉義字符)編碼爲以轉義字符開頭的兩個(或多個)字符序列 。例如,在C++中,不允許在字符串或字符文字中使用新行 。轉義字符是 \;因此,它也必須編碼爲轉義序列。 所以我們有"\n"一個新的線(n的選擇是任意的),和 "\\"\。 (對於第二個字符\的選擇也是 的任意,但通常使用轉義字符escape, 來表示自己。)在你的情況,如果你想使用_作爲 轉義字符,並"_a"表示一個空格,合乎邏輯的選擇 將"__"代表一個_(但我建議的東西多一點 更直觀提示—也許^作爲轉義,"^_"爲 一個空格,"^^"^)。閱讀時,無論何時看到轉義字符 ,都必須映射以下字符(並且如果它不是預定義映射的一個 ,則輸入文本出錯)。這很簡單 來執行,而且非常可靠;關於唯一的缺點是在 的極端情況下,它可以將字符串的大小加倍。

+0

一個小修改使得這個效率更高。爲了閱讀,將'^ _'映射到,'^^'到'^'和'^ x'到'^ x'(其中'x'既不是'_'也不是'^')。要編碼,將映射到'^ _'; '^'如果後面跟着'^'或'_'或到'^^';否則,保持原樣。這只是使用解決方案中的非法編碼來減少空間消耗。如果空格比'^'更普遍,那麼你可以調整'^ x'解碼爲'x',從而對編碼算法進行補償性更改。 – rici

0

我認爲只是編碼爲ASCII十六進制是一個整潔的想法,但當然會使存儲量增加一倍。

如果你想用較少的內存來做到這一點,那麼你將需要兩個字母的序列,並且必須小心,以便您可以輕鬆地返回。

你可以例如用_a代替空白,但你還需要照顧你的轉義字符_。爲此,請將_替換爲__(兩個下劃線)。您需要掃描一次字符串並同時進行兩次替換。

通過這種方式,在結果文本中,所有原始下劃線將加倍,而下劃線的唯一其他出現位置將在組合_a中。你可以放心地翻譯回來。每當你看到一個下劃線,你需要看到1,看看下面的內容。如果後面有a,那麼之前這是空白。如果_如下,那麼之前它是一個下劃線。

請注意,重點是要替換原始字符串中的轉義字符(_),而不是您映射空白的字符序列。您的想法替換_a休息。因爲您不知道_aa原本是_a還是a(空白後跟a)。