我需要存储一个字符串,用一些字符替换它的空格。当我找回它时,我需要再次用空格替换字符。我已经想到了这个策略,同时存储我将替换(空间用_a)和(_a用_aa),而检索将替换(_a用空格)和(_aa用_a)。即使用户在字符串中输入_a,也会被处理。但我不认为这是一个好策略。如果有人有更好的,请告诉我?
答案 0 :(得分:2)
用某事替换空格是一个问题。为什么不简单地对字符串进行编码 - 有很多方法可以做到这一点,一种是将所有字符转换为十六进制。
例如
Hello world!
编码为
48656c6c6f20776f726c6421
空间为0x20。然后你只需要解码(hex到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
使用,但我建议{{1}解决方案,因为它更便携 - 如果你需要编写更多的字符,可以在以后使用)
答案 1 :(得分:1)
我不确定您的解决方案是否有效。阅读时,你会怎么样?
区分原始" a"
的字符串和字符串
最初是"_a"
:如果我理解正确的话,两者都会结束
"_aa"
。
一般情况下,给定情况下一组特定的字符不能
如此出现,但必须编码,解决方案是选择其中之一
允许字符作为“转义”字符,将其从集合中删除
允许的字符,并编码所有禁用的字符
(包括转义字符)作为两个(或更多)字符序列
从转义字符开始。例如,在C ++中,有一个新行
不允许在字符串或字符文字中。转义字符是
\
;因此,它必须编码为转义序列。
所以我们"\n"
为新行(n
的选择是任意的),和
"\\"
\
。 (第二个字符的\
的选择也是
任意,但通常使用转义字符,转义,
代表自己。)在您的情况下,如果您想使用_
作为
转义字符,"_a"
代表空格,是逻辑选择
将"__"
代表_
(但我会建议一点点
更具视觉冲击力 - 可能^
为逃生,"^_"
为。{
"^^"
的空格和^
。在阅读时,只要你看到逃脱
必须映射以下字符(如果不是一个字符)
预定义映射,输入文本错误)。这很简单
实施,非常可靠;关于唯一的缺点是在
一个极端的情况,它可以加倍你的字符串大小。
答案 2 :(得分:0)
您想使用C / C ++实现这一点吗?我认为你应该把你的字符串分成多个部分,用空格分隔。
如果你的字符串是这样的:“a__b”(多个空格连续),它将被分成:
sub[0] = "a";
sub[1] = "";
sub[2] = "b";
希望这会有所帮助!
答案 3 :(得分:0)
对于使用X字符的普通字符串,您不能仅使用1个字符/输入字符来编写或编码x-1字符串。 您可以使用2个字符的组合来替换给定的字符(这正是您在示例中尝试的内容)。
为此,循环遍历字符串以计算空间的外观与其长度的组合,创建一个新的字符数组并用“//”替换这些空格,这只是一个例子。这种方法的问题在于输入字符串中不能有“//”。
另一种方法是使用很少使用的char,例如“^”来替换空格。
最后一种方法,结合了这两种方法很受欢迎。它在unix和php中使用,将语法字符作为字符串中的文字。如果你想要一个“”“,你只需把它写成”等等。
答案 4 :(得分:0)
为什么不使用替换功能
String* stringWithoutSpace= stringWithSpace->Replace(S" ", S"replacementCharOrText");
所以现在stringWithoutSpace不包含空格。如果你想把这些空间放回去,
String* stringWithSpacesBack= stringWithoutSpace ->Replace(S"replacementCharOrText", S" ");
答案 5 :(得分: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('_');
答案 6 :(得分:0)
我认为只编码为ascii十六进制是一个很好的想法,但当然可以将所需的存储量增加一倍。
如果你想用更少的内存来做这件事,那么你需要两个字母的序列,并且必须要小心,你可以轻松回去。
你可以,例如将_a
替换为空白,但您还需要处理转义字符_
。为此,请将每个_
替换为__
(两个下划线)。您需要扫描一次字符串并同时进行两次替换。
这样,在生成的文本中,所有原始下划线都将加倍,并且下划线的唯一其他出现将在组合_a
中。您可以安全地将其翻译回来。每当你看到一个下划线,你需要一个1的外观,看看下面是什么。如果跟随a
,则之前是空白。如果跟随_
,则之前是下划线。
请注意,重点是替换原始字符串中的转义字符(_
),而不是映射空白的字符序列。您的想法是替换_a
休息。因为您不知道_aa
最初是_a
还是a
(空白后跟a)。