2012-10-12 167 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)。