整理C++面试经典编程题

1.数组乘机

输入:一个长度为n的整数数组input;

输出:一个长度为n的整数数组result,满足result[i]=input数组中除了input[i]之外所有数的乘积(假设不会溢出)。比如输入:input={2,3,4,5},输出result={60,40,30,24}。

程序要求:具有线性复杂度,且不能使用除法运算符。

思路:left[i]存储input[i]之前所有元素的乘积,right[i]存储input[i]之后所有元素的乘积,那么result[i]=left[i]*right[i]。则时间复杂度为O(n),空间复杂度为O(n)。

int* calresult(int* input, int n)
{
	int* left = new int[n];
	int* right = new int[n];
	int* result = new int[n];
	left[0] = 1;
	for (int i = 1; i < n; i++)
	{
		left[i] = left[i - 1] * input[i - 1];
	}
	right[n - 1] = 1;
	for (int i = n - 2; i >= 0; i--)
	{
		right[i] = right[i + 1] * input[i + 1];
	}
	for (int i = 0; i < n; i++)
	{
		result[i] = left[i] * right[i];
	}
	delete[] left;
	delete[] right;
	return result;
}

提高:可以把空间复杂度降低,result[i]先存储input[i]之前所有元素的乘积,然后从右到左依次算出真正的result[i]。

int* calresult1(int* input, int n)
{
	int* result = new int[n];
	result[0] = 1;
	for (int i = 1; i < n; i++)
	{
		result[i] = result[i - 1] * input[i - 1];
	}
	result[0] = input[n - 1];
	for (int i = n - 2; i > 0; i--)
	{
		result[i] *= result[0];
		result[0] *= input[i];
	}
	return result;
}

2.一个int数组,求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。

思路:使用rightMin[]来记录原始数组array[i]右边(包括自己)的最小值。然后从头遍历原始数组时,保存一个当前最大值leftMax,如果leftMax刚好等于rightMin[i],则当前值满足条件。

void smallLarge(int* arr, int n)
{
	int i, leftMax;
	int* rightMin = new int[n];
	rightMin[n - 1] = arr[n - 1];
	for (i = n - 2; i >= 0; i--)
	{
		if (arr[i] < rightMin[i + 1])
			rightMin[i] = arr[i];
		else
			rightMin[i] = rightMin[i + 1];
	}
	leftMax = arr[0];
	for (i = 0; i < n; i++)
	{
		if (arr[i]>leftMax)
			leftMax = arr[i];
		if (leftMax == rightMin[i])
			cout << arr[i] << endl;
	}
	delete[] rightMin;
}

3.数组中有一个数字出现的次数超过了数组长度的一半,请找出这个数字。

思路:也是“水王帖子”问题,使用排除法。可以理解为这个数字出现的个数一定大于其他全部数字出现的个数之和。

int function(int* a, int n)
{
	int cur_val;
	int cur_num=0;
	for (int i = 1; i < n; i++)
	{
		if (cur_num == 0)
		{
			cur_val = a[i];
			cur_num++;
		}
		else
		{
			if (a[i] == cur_val)
				cur_num++;
			else
				cur_num--;
		}
	}
	return cur_val;
}

4.在长度为M的字符串中,查找长度为N的字符串。

思路:KMP算法,是高效率的字符串匹配算法,时间复杂度为O(m+n)。

KMP算法每当一趟匹配过程中出现字符比较不等时,不需回溯主串,而是利用已经得到的“部分匹配”结果将模式串向右滑动尽可能远的一段距离后,继续进行比较,且此时并不一定是拿模式串的第一位继续比较。

//计算nextval数组。nextval[]存放的是子串每一个位置之前的字符串的前缀和后缀公共部分的最大长度
void getNextVal(const char* partn, int plen, int* nextval)
{
	int i = 0, j = -1;
	nextval[0] = -1;
	while (i < plen-1)
	{
		if (j == -1 || partn[i] == partn[j])
		{
			i++;
			j++;
			nextval[i] = j;
		}
		else
			j = nextval[j];
	}
}
int kmpSearch(const char* src, int slen, const char* partn, int plen)
{
	int* nextval = new int[plen];
	getNextVal(partn, plen, nextval);
	int i = 0, j = 0;
	while (i < slen && j < plen)
	{
		if (j == -1 || src[i] == partn[j])
		{
			i++;
			j++;
		}
		else
			j = nextval[j]; //当匹配失败时
	}
	delete[] nextval;
	if (j >= plen)
		return i - plen;
	else
		return -1;
}

5. 字符串转换为数字。输入一个表示整数的字符串,把该字符串转换成整数并输出。

思路:需要考虑,正负号;非法输入——

(1)需要判断指针是不是为空

(2)输入的字符串可能含有不是数字的字符。每当碰到非法字符,转换停止

(3)溢出问题。若溢出,返回0

//字符串转换为数字
int strToInt(const char* str)
{
	assert(str != NULL);
	long long num;
	bool type = true;
	if (*str == '+') //是否带正负号
		str++;
	else if (*str == '-')
	{
		type = false;
		str++;
	}
	num = 0;
	while (*str != '\0')
	{
		if (*str >= '0'&& *str <= '9')
		{
			num = num * 10 + (*str - '0');
			if (num > std::numeric_limits<int>::max()) //溢出时返回0
			{
				num = 0;
				break;
			}
			str++;
		}
		else  //含有非法字符时返回0
		{
			num = 0;
			break;
		}
	}
	if (!type) //负数的情况
		num = 0 - num;
	return num;
}

6.输入两个很大的正数(用C字符串表示),输出它们的乘积。假设不考虑非法输入。

注意:相乘的结果位数最多为la+lb。

char* multiply(const char* a, const char* b)
{
	assert(a != NULL && b != NULL);
	int i, j;
	int la = strlen(a);
	int lb = strlen(b);
	int* s = new int[la + lb];
	memset(s, 0, (la+lb)*sizeof(int)); //每个元素赋初值0
	for (i = 0; i < la; i++)
		for (j = 0; j < lb; j++)
			s[i + j + 1] += (a[i] - '0')*(b[j] - '0');
	for (i = la + lb - 1; i > 0; i--) //这里实现进位操作
	{
		if (s[i] >= 10)
		{
			s[i - 1] += s[i] / 10;
			s[i] %= 10;
		}
	}
	char* c = new char[la + lb+1];
	i = 0;
	while (s[i] == 0) //跳过头部0元素
		i++;
	for (j = 0; i < la + lb; i++, j++)
	{
		c[j] = s[i] + '0';
	}
	c[j] = '\0';
	delete[] s;
	return c;
}

7.

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当谈到C++面试题中的网络编程,以下是一些常见的问题和答案: 1. 什么是套接字(Socket)? 套接字是一种用于网络通信的编程接口,它提供了一种机制,使得不同主机上的进程可以通过互联网进行通信。 2. TCP和UDP的区别是什么? TCP(传输控制协议)是一种面向连接的协议,它提供可靠的数据传输和流控制。UDP(用户数据报协议)是一种无连接的协议,它提供了一种简单的、无保证的数据传输方式。 3. 如何在C++中创建一个TCP套接字? 在C++中,可以使用socket()函数创建一个TCP套接字。例如: ``` #include <sys/socket.h> int sockfd = socket(AF_INET, SOCK_STREAM, 0); ``` 4. 如何在C++中创建一个UDP套接字? 在C++中,可以使用socket()函数创建一个UDP套接字。例如: ``` #include <sys/socket.h> int sockfd = socket(AF_INET, SOCK_DGRAM, 0); ``` 5. 如何将套接字绑定到特定的IP地址和端口? 可以使用bind()函数将套接字绑定到特定的IP地址和端口。例如: ``` #include <sys/socket.h> #include <netinet/in.h> struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(1234); bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)); ``` 6. 如何在C++中使用套接字进行TCP客户端编程? 可以使用connect()函数连接到服务器,并使用send()和recv()函数发送和接收数据。例如: ``` #include <sys/socket.h> #include <netinet/in.h> int sockfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(1234); serverAddr.sin_addr.s_addr = inet_addr("服务器IP地址"); connect(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)); ``` 这些是一些常见的C++网络编程面试问题。在面试前,建议你深入了解这些概念,并准备好相关的代码示例和解释。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值