今天写C语言题目,老师出了这样一道题:
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
一开始单靠这几句话,我还没真正理解题意 (X_X) ,语文水平不高。和我一样的同学可以看下面的链接,要先写题,先懂起题意。
链接: JZ58 左旋转字符串
其实这题不就是把左边的字符串移到右边嘛。
那怎么实现呢?
首先想到的是要旋转k个字符,那就一个字符一个字符旋转呗。
解法一:
char* LeftRotateString(char* str, int n ) {
// write code here
int i = 0, j = 0, tmp = 0;
int len = 0;
len = strlen(str);
if(len!=0)
{
n %= len;//长度为5的情况下,旋转6、11、16...次相当于1次,7、12、17...次相当于2次,以此类推。
}
for (i = 0; i < n; i++) //执行k次的单次平移
{
tmp = str[0];//一开始str[0]就被覆盖了,且后面要用,所以先存着
for(j = 0; j < len - 1; j++) //单次平移
{
str[j] = str[j + 1];
}
str[j] = tmp;
}
return str;
}
既然是一个字符一个字符旋转,还不如一串字符一串字符旋转呢
解法二:
char* LeftRotateString(char* str, int n ) {
// write code here
int len = strlen(str);
int pos = 0;
if(len!=0)
{
pos = n % len; //断开位置的下标
}
char tmp[100] = { 0 }; //初始化
strcpy(tmp, str + pos); // str是指针,指针加整数,你懂的。将后面的字符串全部拷过来
strncat(tmp, str, pos); //然后将前面几个接上
strcpy(str, tmp); //最后拷回去
return str;
}
这个方法要用到一个数组 tmp 形成的辅助空间,让人觉得有点不得劲,还可以有更好的选择,例如ABCDEFG,左旋3次后变成DEFGABC,有一个特殊的操作方式:
OHOHOHOHOH (双重否定即为肯定)
先将要左旋的前三个家伙逆序(CBA DEFG),然后将后半段也逆序(CBAGFED),最后整体逆序(DEFGABC)即可。这样只需要做数值交换即可,可以写一个函数帮我们完成局部逆序,代码如下:
解法三:
void reverse_part(char* str, int start, int end)
{ //将字符串从start到end这一段逆序
int i = 0, j = 0;
char tmp = 0;
for (i = start, j = end; i < j; i++, j--)
{
tmp = str[i];
str[i] = str[j];
str[j] = tmp;
}
}
char* LeftRotateString(char* str, int n ) {
// write code here
int len = strlen(str);
int pos = 0;
if (len != 0)
{
pos = n % len; //断开位置的下标
}
reverse_part(str, 0, pos - 1); //逆序前段
reverse_part(str, pos, len - 1); //逆序后段
reverse_part(str, 0, len - 1); //整体逆序
return str;
}
C 库函数 strncpy()
可是解法二中遇到了C 库函数 strncpy(),查菜鸟教程后就懂了
C 库函数 - strncpy()
C 标准库 -
描述
C 库函数 char *strncpy(char *dest, const char *src, size_t n) 把 src 所指向的字符串复制到 dest,最多复制 n 个字符。当 src 的长度小于 n 时,dest 的剩余部分将用空字节填充。
声明
下面是 strncpy() 函数的声明。
char *strncpy(char *dest, const char *src, size_t n)
参数
返回值
该函数返回最终复制的字符串。
实例
下面的实例演示了 strncpy() 函数的用法。在这里,我们使用函数 memset() 来清除内存位置。
实例
#include <stdio.h>
#include <string.h>
int main()
{
char src[40];
char dest[12];
memset(dest, '\0', sizeof(dest));
strcpy(src, "0123456789,你好鸭");
strncpy(dest, src, 10);
printf("最终的目标字符串: %s\n", dest);
return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:
最终的目标字符串:0123456789
C 库函数 char *strncpy(char *dest, const char *src, size_t n) 这参数。。。
const 修饰的变量,这个变量就不能被修改了。
#include <stdio.h>
int main()
{
int m = 0;
m = 20;//m是可以修改的
const int n = 0;
n = 20;//n是不能被修改的,这里报错
int* p = &n;//但是指针可以修改,666,就像高启强想弄死李宏华,不能亲自动手,就找老默去干。此时老默就是指针变量p
*p = 20;
printf("n = %d\n", n);
return 0;
}
所以有了const修饰指针变量,详解在下面的代码中哟~
别忘了自己上机测试
#include <stdio.h>
int main()
{
int n = 20;
int m = 666;
int const * p = n;//1.
const int * p = n;//2. 1和2一样的const 修饰 *p 即不能解引用,n的值不能改,p里的内容可以改
p = &m;
int * const p = n;//3.const 修饰 指针变量p, p里的值不能改,*p可以改,n的值可以改
//*p = 888;
int const * const p = n;//4. const 修饰 *p,p,即二者都不能改动
// p = &m
// *p = 888;
return 0;
}
还有一个参数 :C 库函数 char *strncpy(char *dest, const char *src, size_t n) size_t n
size_t 这是什么类型
在cplusplus是这样讲的
type
size_t
Unsigned integral type
Alias of one of the fundamental unsigned integer types.
It is a type able to represent the size of any object in bytes: size_t is the type returned by the sizeof operator and is widely used in the standard library to represent sizes and counts.
size_t
无符号整型
基本无符号整数类型之一的别名。
该类型能够以字节表示任何对象的大小:size_t是sizeof操作符返回的类型,在标准库中广泛用于表示大小和计数。
其实就是无符号整型呗!
都看到这里了,在做一个比较坑爹的选择题。
下面代码的结果是:
#include <stdio.h>
int i;
int main()
{
i--;
if (i > sizeof(i))
{
printf(">\n");
}
else
{
printf("<\n");
}
return 0;
}
A.>
B.<
C.不输出
D.程序有问题
选A,不信自己到电脑上面跑一下。
if (i > sizeof(i))
i是int 型,sizeof()返回unsigned int 型,发生整型提升,int ---> unsigned int
11111111 11111111 11111111 11111111第一个1不是符号位了 you know? i为很大的整数了肯定 > 4