解码字符数组

decoding a character array

本文关键字:数组 字符 解码      更新时间:2023-10-16

给定一个 URL 格式的字符数组,如下所示

   char *s="www.google.comtsp finite.aspx"

解码时,空格应替换为 %20,因此字符串变为:

   char *s="www.google.comtsp%20finite.aspx"

我们不允许使用新的字符数组,但允许使用一些字符变量作为临时使用。也不应使用任何容器。数组包含足够的空间来包含解码的数据,因此无需担心要占用的更多空间。

我遵循了蛮力机制,其中从寻找空格到数组末尾的所有字符都将被交换。但这不是解决问题的最有效方法。

任何人都可以告诉我哪种是减少交换次数的最佳方法(算法)以获得解决方案。

我假设字符串已使用 malloc

分配

首先计算空格数和字符串的长度

然后新长度 = 旧长度 + 空格数 * 2。使用 realloc 扩展字符串。

工作从末尾向后并复制到新的长度。在 %20 中遇到空间副本时。

主要问题可能是与 %20 交换空间将需要将整个字符串再移动 2 个字符。

这里有一个想法:

  1. 解析整个字符串一次,并计算字符串中的空格数
  2. 数组的新长度将是 strlen(original) + 2*(nOfSpaces)(让我们从现在开始在 NewLen 上称呼它)
  3. 再次解析整个字符串,但向后开始。
  4. 您将在自身内部复制以前的字符串内容,但要偏移,直到到达空格
    • 您将有一个从strlen(original)开始的指针和一个从NewLen开始的指针
    • 从 strlen(original) 向后解析,直到找到一个空格(substrLen 将是 subLen)
    • memcpy from [strlen(original)-curParsingindex] to [NewLen - curParsingIndex-2*(enteredSpaces)] sublen amount
  5. 不要复制空格,而是将 %20 改为

这样,您将避免每次点击空格时向前移动字符串。

关于第 4 步,您可能会考虑为 sublen 使用临时变量,因为您最终可能会错误地在同一内存区域中写入(举个所有空格都在开头的示例)。

这是一个经典的面试编码问题; 一个好的解决方案始于您的解决方案的良好界面。有效的方法是:

char* replaceChar(char* in, char c)
char *in - string you want to decode
c - the char you want to replace with it's hexa value ASCII code ( HEX val ascii for ' ' is 0x20)

伪代码:

  1. 分配与输入缓冲区大小相同的缓冲区
  2. 获取要替换的字符第一次出现的索引(strcspn 可以帮助解决这个问题)
  3. 将输入的内容复制到找到的索引到新缓冲区。
  4. 将新的缓冲区大小重新分配给newSize=oldSize+2
  5. 将 % 添加到新字符串
  6. 重复直到到达字符串的末尾。
  7. 返回指向新字符串的指针

您也可以在原始字符串上就地执行此操作,但该解决方案有点复杂,因为您必须移动所有内容。

你可以分两次完成。关键思想是首先计算空格数,然后将每个字符直接移动到其最终位置。在您的方法中,您在每次出现空格时移动字符串的其余部分。

#include <stdio.h>
int main ()
{
    char str[1000] = "www.example.com/hello world !";
    int length;
    int spaces;
    int i;
    char *ptr;
    printf (""%s"n", str);
    // pass 1:
    // calculate length and count spaces
    length = 0;
    spaces = 0;
    for (ptr = str; *ptr; ptr++) {
        if (*ptr == ' ') {
            spaces++;
        }
        length++;
    }
    // pass 2:
    // transform string
    // preserve terminating null character
    ptr = str + length + 2 * spaces;
    for (i = length; i >= 0; i--) {
        char c = str[i];
        if (c == ' ') {
            *ptr-- = '0';
            *ptr-- = '2';
            *ptr-- = '%';
        }
        else {
            *ptr-- = c;
        }
    }
    printf (""%s"n", str);
    return 0;
}