C语言经典题目之字符串逆序
创始人
2024-03-07 02:57:26
0

目录

一、字符串逆序(基础题)

1.一个经典的错误,标准的零分

2.采用gets函数来修补漏洞

​编辑

3.非要使用scanf怎么办?

 4.使用指针来实现逆序函数

5.将函数修改为,只要传入两个地址,就能逆序这两个地址之间的字符串。

二、字符串逆序(进阶)


一、字符串逆序(基础题)

链接:字符逆序__牛客网
来源:牛客网

这道题的要求是让我们实现一个字符串逆序

1.一个经典的错误,标准的零分

这道题其实,思路上不难,但是有一个点处很容易犯错,我们看下面这个代码

#include
#include
void reverse(char* str)
{int left = 0;int right = strlen(str) - 1;while (left < right){char tmp = 0;tmp = *(str + left);*(str + left) = *(str + right);*(str + right) = tmp;left++;right--;}
}
int main()
{char arr[10000] = { 0 };scanf("%s", arr);reverse(arr);printf("%s", arr);return 0;
}

看似正确,但实际上存在一个问题,我们现在牛客网上跑一下

 果然如我们所料,出现意外了,那么问题出在哪里了呢?其实,问题是出在scanf上了,scanf默认读取到空格就结束了,因此这道题其实只读取了一个d,反转之后当然是d了

2.采用gets函数来修补漏洞

既然scanf不能用,那么该如何解决呢?,其实我们c语言中还有一个函数叫做gets()函数,他也可以读取一个字符串,他不会读取到空格就结束了

代码如下

#include
#include
void reverse(char* str)
{int left = 0;int right = strlen(str) - 1;while (left < right){char tmp = 0;tmp = *(str + left);*(str + left) = *(str + right);*(str + right) = tmp;left++;right--;}
}
int main()
{char arr[10000] = { 0 };gets(arr);reverse(arr);printf("%s", arr);return 0;
}

牛客网运行结果为

3.非要使用scanf怎么办?

有些时候,非要使用scanf解决这个问题,那么我们如何实现呢?,其实我们可以将%s修改为%[^\n],意思是,读取到\n才结束读取

代码如下

#include
#include
void reverse(char* str)
{int left = 0;int right = strlen(str) - 1;while (left < right){char tmp = 0;tmp = *(str + left);*(str + left) = *(str + right);*(str + right) = tmp;left++;right--;}
}
int main()
{char arr[10000] = { 0 };//gets(arr);scanf("%[^\n]", arr);reverse(arr);printf("%s", arr);return 0;
}

牛客网运行结果为

 4.使用指针来实现逆序函数

上面的实现方式,其实本质上仍然属于数组的形式,那么我们能不能改为指针呢?答案是可以的,请看下面的代码

#include
#include
void reverse(char* str)
{char* left = str;char* right = str + strlen(str) - 1;while (left < right){char tmp = 0;tmp = *left;*left = *right;*right = tmp;left++;right--;}
}
int main()
{char arr[10000] = { 0 };//gets(arr);scanf("%[^\n]", arr);reverse(arr);printf("%s", arr);return 0;
}

牛客网运行结果为

 

5.将函数修改为,只要传入两个地址,就能逆序这两个地址之间的字符串。

经历了上面的思考,我们在想,这个逆序多多少少还是有一点不方便,比如在某一个字符串中,我们不想逆序整个字符串,我们只想要逆序一部分,这时候我们上面的函数适用性就不够了,所以我们最好将其改成只要传入两个地址,就可以逆序这两个地址之间的字符串,这样的话,这个函数就变得很好用了。

代码如下

#include
#include
void reverse(char* left,char* right)
{while (left < right){char tmp = 0;tmp = *left;*left = *right;*right = tmp;left++;right--;}
}
int main()
{char arr[10000] = { 0 };//gets(arr);scanf("%[^\n]", arr);reverse(arr, arr + strlen(arr) - 1);printf("%s", arr);return 0;
}

牛客网运行结果为

二、字符串逆序(进阶)

有了上面那到题目作为基础,我们可以尝试做一下这道题

链接:倒置字符串_牛客题霸_牛客网

来源:牛客网

这道题我们可以看的出来,是上一道题的进阶版,但是根据我们上一道题的思考之后,这道题其实也没有那么难,因为我们已经创建一个函数,只要传入两个地址,就可以逆序这两个地址之间的字符串。

所以我们的思路就是,先逆序,整个字符串,然后逆序每一个单词

代码如下

#include
#include
void reverse(char* left,char* right)
{while (left < right){char tmp = 0;tmp = *left;*left = *right;*right = tmp;left++;right--;}
}
int main()
{char arr[100] = { 0 };gets(arr);//逆序整句话reverse(arr, arr + strlen(arr) - 1);//逆序每一个单词char* p1 = arr;char* p2 = arr;while (*p2 != '\0'){p1 = p2;while (*p2 != ' '&&*p2!='\0'){p2++;}reverse(p1, p2 - 1);if (*p2 == '\0'){break;}p2++;}printf("%s", arr);return 0;
}

对于这段代码的逆序每一个单词环节,可能有很多人都有所困惑。为什么是这样实现的呢?

我们逆序单词是采用的双指针的方法。先定义两个字符指针他们指向字符串的首元素地址,然后我们令p1先不动,p2往下走,只要我的p2不是'\0',自然就可以一直走下去,在里面我们先采用一个while循环,来让p2 走到单词的末尾,然后使用逆序函数,逆序这两者之间的单词,然后判断一下p2的里面的值是否为\0,如果此时为\0就不需要进行接下来的步骤了,直接结束即可。

但是如果此时不为'\0',那么就要继续执行下去,先让p2++,让我们的p2指向下一个单词的首元素,将下一个单词的首元素交给p1,然后p2继续走下去,这样循环下去就可以实现目标了。

 牛客网运行结果为

 

相关内容

热门资讯

三部门:不断完善学前教育成本分... 观点网讯:12月23日,国家发展改革委、教育部、财政部联合发布《关于完善幼儿园收费政策的通知》,要求...
汪清林区法院:化解未成年人纠纷... 近日,吉林省汪清林区法院审结了一起涉未成年人在校遭受人身损害案件,法院充分考量了未成年人的行为特点及...
北京市长城保护条例 北京市人民代表大会常务委员会公告 〔十六届〕第45号 《北京市长城保护条例》已由北京市第十六届人民代...
棒杰股份(002634)披露关... 截至2025年12月23日收盘,棒杰股份(002634)报收于5.28元,较前一交易日下跌4.52%...
高盛再度唱多!预计中国股市到2... 来源:视觉中国 界面新闻编辑 | 江怡曼 近日,高盛发布名为《中国策略:2025年中国股市十大...
尤文身价变化:共10人身价下降... 在意甲联赛的激烈竞争中,尤文图斯的球员身价变化引发了广泛关注。根据最新的德转数据,尤文队内有10名球...
美国发布H-1B签证新规,优先... 当地时间12月23日,美国国土安全部发布新规,正式以“加权选择”机制取代H-1B签证原有的随机抽签制...
悉尼恐袭事件,意外替德国默茨政... 刚刚过去的一周,发生在澳大利亚的悉尼邦迪海滩恐怖袭击事件引起全球关注。 对于万里之外的德国而言,这场...
视频丨“粤车南下”驶入香港市区... 今天(12月23日),“粤车南下”驶入香港市区政策正式实施,符合条件的广东私家车可直接驶入香港市区,...
立白回应与经销商解约纠纷:个别... 12月23日,红星新闻报道《多地代理商称与立白集团解约后 对方未按约交接市场致严重损失,律师解读》一...