目录
(通讯录)动态增长版
实现效果
找单身狗
题目
源码
思路
三个内存函数的模拟实现
模拟实现strncpy
模拟实现strncat
模拟实现atoi
(通讯录)动态增长版
该版本通讯录在原版的基础上增加了检查容量函数,实现了通讯录的动态增长
//检查是否需要增容
int CheckSz(Contact* pc)
{
if (pc->count == pc->sz)
{
PeoInfo* str = (PeoInfo*)realloc(pc->date, (pc->sz + ADD_SZ) * sizeof(PeoInfo));
if (str == NULL)
{
perror("CheckSz:");
return 0;
}
else
{
pc->date = str;
pc->sz += ADD_SZ;
printf("增容成功\n");
return 1;
}
}
return 1;
}
在使用添加函数时调用检查容量函数即可实现动态增长
实现效果
找单身狗
题目
一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
编写一个函数找出这两个只出现一次的数字。
例如:
有数组的元素是:1,2,3,4,5,1,2,3,4,6
只有5和6只出现1次,要找出5和6.
源码
void FindSingle(int* arr, int size,int* dog1,int* dog2)
{
//计算所有数组异或结果ret
int i = 0;
int ret = 0;
for (i = 0; i < size; i++) {
ret ^= arr[i];
}
//计算ret第几位是1
int pos = 0;
for ( i = 0; i < 32 ; i++)
{
if ((ret >> i )& 1 == 1)
{
pos = i;
break;
}
}
//计算第pos为1异或
for (int i = 0; i < size; i++)
{
if (((arr[i] >> pos) & 1) == 1)
{
*dog1 ^= arr[i];
}
//计算第pos为0异或
else
{
*dog2 ^= arr[i];
}
}
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 6 };
int size = sizeof(arr) / sizeof(arr[0]);
int dog1 = 0;
int dog2 = 0;
FindSingle(arr, size,&dog1,&dog2);
printf("单身狗是%d %d",dog1,dog2);
return 0;
}
思路
使用了异或的思想 相同为0 不同为1
(注意!异或比较的是二进制位 任何数与0的异或都为本身 而不是1)
1.计算所有数组异或结果ret
2.计算ret第几位是1
3.计算第pos为1异或4.计算第pos为0异或
三个内存函数的模拟实现
模拟实现strncpy
从字符串中复制字符
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
//char* strncpy(char* destination, const char* source, size_t num);
char* my_strncpy(char* des, const char* src, int num)
{
char* temp = des;
assert(des != NULL);
assert(src != NULL);
while (*src && num--)
{
*des = *src;
des++;
src++;
}
*des = '\0'; //将\0拷贝
return temp;
}
int main()
{
char str1[] = "To be or not to be";
char str2[40];
char str3[40];
my_strncpy(str2, str1, 8);
my_strncpy(str3, str2, 5);
puts(str1);
puts(str2);
puts(str3);
return 0;
}
模拟实现strncat
从字符串追加字符
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
//char* strncat(char* destination, const char* source, size_t num);
char* my_strncat(char* des, const char* src,int num)
{
assert(des);
assert(src);
char* temp = des;
while (*des)
{
des++;
}
while (*src && num--)
{
*des++ = *src++;
}
*des = '\0';
return temp;
}
int main()
{
char str1[20];
char str2[20];
strcpy(str1, "To be ");
strcpy(str2, "or not to be");
my_strncat(str1,str2,6);
puts(str1);
return 0;
}
模拟实现atoi
将字符串转换为整数
#define _CRT_SECURE_NO_WARNING 1
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <limits.h>
//1.空指针
//2.空字符串
//3.空白字符
//4.数字超过范围
//
enum State
{
TID,
FID
}state = FID;//全局的转态,它的值标志返回的值是合法还是异常
int my_atoi(const char* str)
{
int flag = 1;
assert(str);//空指针
if (*str == '\0')//空字符串
{
return 0;
}
//跳过空白字符
while (isspace(*str))
{
str++;
}
if (*str == '-')
{
flag = -1;
str++;
}
else if (*str == '+')
{
str++;
}
long long ret = 0;
while (*str != '\0')
{
if (isdigit(*str))
{
ret = ret * 10 + flag * (*str - '0');
if (ret > INT_MAX || ret < INT_MIN)
{
return 0;
}
}
else
{
return (int)ret;
}
str++;
}
state = TID;
return (int)ret;
}
int main()
{
int ret = my_atoi("123");
if (state == TID)
{
printf("%d\n", ret);
}
else
{
printf("非法返回:%d\n", ret);
}
return 0;
}