[随笔]牛客网:倒置字符串-一个充满想象力(很奇怪)的解法

41 阅读2分钟

正常思路:

_U@~JWO_LWJ`S45B5V}1(UT.png 从后向前查找,找到空格算是一个单词,找到一个空格将其拷贝到另一个字符串里面。

这里特殊的最后一个单词,因为上面是以一个空格来判断一个单词的,所以会导致从后向前查找的时候,无法找到最后一个单词。

int main() {
    char str[] = "i123 like beijing.";
    char tmpStr[101] = { 0 };
    int j = 0; // 这里的j因子是用来记录tmpStr数组的下标的

    for (int i = strlen(str) - 1; i >= 0; --i) {
        if (str[i] == ' ') {
            int tmp = i + 1;
            while (str[tmp] != ' ' && str[tmp] != '\0') {
                tmpStr[j] = str[tmp];
                j++, tmp++;
            }
            tmpStr[j] = ' ';
            j++;
        }
    }
    // 添加最后一个单词
    int tmp = 0;
    while (str[tmp] != ' ' && str[tmp] != '\0') {
        tmpStr[j] = str[tmp];
        j++, tmp++;
    }
    // 添加字符串结束符
    tmpStr[j] = '\0';

    // 将 tmpStr 拷贝到 str 中
    strcpy(str, tmpStr);

    printf("%s\n", str);
    return 0;
}

进阶思路: 我叫这个方法叫做,两步反转法,第一遍是将字符串中的每一个单词逆置,第二次将整个字符串逆置。也就达到了一样的效果。 eg:

step1:
    i like beijing.
    i ekil .ginjieb
step2:
    i ekil .ginjieb
    beijing. like i
#include <stdio.h>
#include <string.h>
void swapStr(char* start, char* end);

int main()
{
	char str[] = "i like beijing. 12345";
	int count = 0; // 记录空格的个数
	for (int i = 0; i < strlen(str) - 1; ++i)
	{
		if (str[i] == ' ')
			count++;
	}
	count++; // 单词的个数 = 空格的个数 + 1

	char* start, * end;
	start = end = str;
	swapStr(start, start + strlen(str) - 1);
	while (count--)
	{
		while (*end != ' ' && *end != '\0')
			end++;
		swapStr(start, end - 1);
			end++; 
		start = end;
	}
	printf("%s\n", str);
	return 0;
}

void swapStr(char* start, char* end)
{
	while (start < end)
	{
		char tmp = *start;
		*start = *end;
		*end = tmp;
		start++, end--;
	}
}

奇怪解法: 这里使用strtok库函数,分割原字符串,将分割后的原字符串,存储到一个指针数组里面,之后将这个数组反向打印出来也就完成了。

这个地方要注意的是:

1.strtok 库函数后 默认加上'\0'
2.如何向strtok函数中传递参数(算是strtok的使用),代码中有提到。
3.使用C99标准的变长数组
#include <stdio.h>
#include <string.h>

int main() 
{
	char str[101] = "";
        gets(str);

	int count = 0;// 记录空格个数
	for (int i = 0; i < strlen(str) - 1; i++)
	{
		if (str[i] == ' ')
			count++;
	}
	count++; // 记录单词个数,单词个数 = 空格个数 + 1

        char* a[count]; // 这个地方是C99标准的变长数组
        
        int b = 0;// 反向索引循环因子
	for (int i = 0; i < count; i++) 
        {
		a[i] = strtok((i == 0) ? str : NULL, " ");  // 第一次传入str,之后传入NULL
		if (a[i] == NULL) 
                {  
			break;// 处理分割结束的情况
		}
		b = i;  // 记录当前索引
	}

	for (int j = b; j >= 0; j--) 
        {  
		printf("%s ", a[j]); // 逆序输出
	}

	return 0;
}

介绍这个方法的目的就是玩玩,自己认为这个方法算是奇技淫巧。大家看看图一乐就行,这道题我认为应用最广泛的还是第二种进阶思路!