春招笔试编程题(一)

(1)判断一个ip地址是否合法?
解题思想:只要含有非数字字符出现就不合法;只要以‘-’开头就不合法;点分十进制法表示ip地址只含有三个‘.’,违背此规律就不合法;每个以‘.’分割部分的数字都必须在0-255范围内;在判断数字是否合法时必须先将数字字符转换成数字,比如“123”-->123;代码如下:

bool Is_Right(const char* str)
{
	int count = 0;
	const char *p = str;
	//只要字符串中含有字母则为错;或者存在‘-’视为错误;
	while( *p != '\0')
	{
		if( *p == '.')
		{
			count++;
		}
		if(isalpha(*p))
		{
			return false;
		}
		else if( *p == '-')
		{
			return false;
		}
		p++;
	}

	if(count == 3)
	{
		int tmp = 0;
		while(*str != '\0' )
		{
			while(*str != '\0' && *str != '.')
			{
				
			    tmp = tmp*10 + (*str - '0');
			    str++;
			}
			
			if(  tmp < 0 || tmp > 255)
			{
				return false;
	    	}
		    else
			{
			  tmp = 0;
			  str++;
		  }	
	   }
	}
	else
	{
		return false;
	}
  return true;
}
(2)将字符串aaaaabbbbcd转变为字符串a5b4c1d1;
解题思想:首先开辟一个一维数组空间brr保存新的字符串,然后定义临时变量tmp保存本趟要统计的字符,定义ccount记录当前字符出现的次数,当遇到不等于本趟统计的字符时将tmp以及ccount的值写入brr中,在将tmp和ccount的值重置记录下一个字符。代码如下:
char *Get_Newchar(char* str)
{
	if(*str == NULL)
	{
		return NULL;
	}

	int i = 0;
	char* brr = (char*)malloc(sizeof(char)*strlen(str));
	assert(brr != NULL);


	char ccount;
	char tmp = *str;
	int count = 0;
	while( *str != '\0')
	{
		if( tmp == *str)
		{
			count++;
			str++;
		}
		else
		{
	
			brr[i] = tmp;
			brr[++i] = ccount; 
			i++;
			count = 0;
			tmp = *str;
			
		}
		ccount = count+'0';
	}
	brr[i++] = tmp;
	brr[i++] = ccount;
	brr[i] ='\0' ;
	return brr;
}

(3)题目:有n组开关,触摸每个开关可以使得每一组灯泡点亮,使用n组开,至少可以点亮多少展灯;
输入:第一行输入一个n,表示有n组开关;
输出:接下来n行,每行第一个整数为k,表示k=这个开关控制k个灯泡;接下来k个整数表示控制的灯泡序号;
解题思想:首先借助set容器,遍历数组中的灯泡序号,将其都插入到set中,最后在求set的size就可得到有多少灯泡可以被打开;由于单重set只有一个值,所以可以避免有重复的灯泡序号被统;代码如下:
int get_light(int **arr,int n)
{
	int count = 0;

	set<int> st;

	for(int i = 0 ; i < n ;++i)
	{
		for(int j = 1 ; j < arr[i][0] + 1; ++j)
		{
			st.insert(arr[i][j]);
		}
	}

	count = st.size();
	return count;
}

int main()
{
int n;
	cin>>n;

	int **arr = new int *[n]();

	int k;

	for(int i = 0; i < n ; ++i)
	{
		cin>>k;
		arr[i] = new int[k+1]();
		arr[i][0] = k;
		for(int j = 1 ; j < k + 1; ++j)
		{
			cin>>arr[i][j];
		}
	}
	
	int ret = get_light(arr,n);
	cout<<ret<<endl;
return 0;
}

(4)给出一个n,解答出能被1到n之间(包括1和n)所有整数整除的最小的数。(求1到n的最小公倍数)
解题思想:首先求出刚开始相邻两个数的最小公倍数,然后依次求当前最小公倍数与下一个数字求最小公倍数,一次循环执行此操作,最后输出最小公倍数;代码如下:

//求两个数的最大公约数
int Get_Big_Data(int a,int b)
{
	int tmp = 0;
	if(a < b)
	{
		tmp = a;
		a = b;
		b = tmp;
	}

	while(a % b != 0)
	{
		tmp =  a % b ;
		a = b;
		b = tmp;
	}
	return b;
}
//求两个数的最小公倍数
int Get_Litt_Data(int a,int b)
{
	return a *b /Get_Big_Data(a,b);
}
//给出一个n,然后需要回答出能被1-n之间(包括1-n)所有整数整除的最小的数;
//求这些数的最小公倍数
int Get_littdata(int *arr,int len)
{
	int i = 0;
		int tmp ;

	while( i < len -1)
	{
		tmp = Get_Litt_Data(arr[i],arr[i+1]);
		i++;
		arr[i] = tmp;
	}
	return tmp;
}

int main()
{
int n;	
	cin>>n;

	int *arr = new int[n];
	for(int i = 0; i < n ; ++i)
	{
		arr[i] = i + 1;
	}

	cout<<Get_littdata(arr,n)<<endl;
 return 0;
}

(5)将一个n*n的二维数组顺时针旋转90度输出;
解题思想:首先行列互换,然后以中间列为对角线,两边元素互换;代码如下:
void Reserve_90_Arr(int arr[N][N])
{
	for(int i = 0; i < N/2+1;++i )
	{
		for(int j = 1 ; j < N;++j)
		{
			int tmp = arr[i][j];
 			arr[i][j] = arr[j][i];
			arr[j][i] = tmp;
		}
	}

	for(int i = 0;i < N;++i)
	{
		for(int j = 0,k = N-1;j < k;++j,--k)
		{
			int tmp = arr[i][j];
 			arr[i][j] = arr[i][k];
			arr[i][k] = tmp;
		}
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_41966991/article/details/79873991