首页 > 其他分享 >力扣题目整数除法

力扣题目整数除法

时间:2023-04-05 21:57:24浏览次数:42  
标签:题目 MIN int else 力扣 负号 ABS ans 除法

在力扣上做题,这个题涉及到的整数溢出问题十分恼人,主要也是我不熟悉这些东西,做的很艰难,下面是题目:

给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 '*'、除号 '/' 以及求余符号 '%' 。

注意:

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231−1]。本题中,如果除法结果溢出,则返回 231 − 1

我最后写出了如下代码:

#include <stdio.h>
#define ABS(i) (( i < 0 ) ? ( -i ) : ( i ))   // 定义一个取绝对值函数
// 本程序是之前程序的加速算法 
int main()
{
	const int MAX = 2147483647;
	const int MIN = -2147483648;
    
	int a=0,b=0;
	int b1=0; 
	int sign=0;  // 记录是否异号,1是,0否 
	int ans=0;
	
	scanf("%d,%d",&a,&b);
	// 用于滚动加速计算的b值,用b1表示 
	printf("a=%d,b=%d\n",a,b);
	// 对两个数是否负号进行判断和记录 
	if (a<0||b<0) 
	{
        sign=1;
        if (a<0&&b<0) sign=0;             
	}
	//  判断是否在int的范围内 
	if ((a<=MAX)&&(b<=MAX)&&(a>MIN)&&(b>MIN)&&b!=1)
	{
		// 要求a>b,这样值才能大于1,因此取绝对值 
		if (ABS(a)>=ABS(b)&&b!=0)
		{
			// 计算部分 
			// 这里a,b的值可以直接取绝对值了,没有问题
			a=ABS(a);
			b=ABS(b);
			b1=-b; 
			// a>b就继续减,直到减不下去,ans 就是a/b得到的那个整数了 
			// 这里是一种滚动加速,我自己取的名字 ;这里一般算不干净,a还会剩,因此还需要下面再用b算一遍。 
			// 这里也用负号,防止溢出 
			while (-a<=b1)
			{
				// 保护一下,防止b的值很大,走不过第一次循环就溢出 
				if (b1<1073741824) break;
				a=a+b1;
				b1=b1+b1;
				ans=ans+ans+1;
				printf("%d\n",ans);
			}
			// 这里清理残余,大头在上一部分已经计算了 ,因此速度会得到提升 
			while (a>=b)
			{
				a=a-b;
				ans++;
				printf("%d\n",ans);
			}
			// 根据对正负号的记录更改正负号 
			if (sign==1)
			{
				ans=-ans;
			}
		}
		else
		{
			ans=0;
		}
	}
	else if (b==1)
	{
		ans=a;
	}
	// 添加b= -2147483648情况,防止在上面取绝对值之后溢出 
	else if (b==MIN)
	{
		// 考虑周全 
		if (a!=MIN) 
		{
			ans=0;
		}
		else
		{
			ans=1;
		}
	}
	// a==-2147483648时无法取正,因为正数最大只有 2147483647,所以要单独处理,保持它的负号,用加法即可 
	else if (a==MIN)
	{
		// 这里也改为加速算法,为了防止出现 1073741824导致的溢出错误,给一个负号,就不会溢出了 
		b1=-ABS(b); 
		// 这里要求与a比较的值是负数,所以才给绝对值加负号 
		while (a<=b1)
		{
			// 保护一下,防止b的值很大
			if (b1<1073741824) break;
			a=a-b1;
			b1=b1+b1;
			ans=ans+ans+1;
			printf("%d\n",ans);
		}
		while (a<=-ABS(b))
		{
			// 这个判断放在前边,以防止溢出 
			if (ans==MAX)
			{
				break;
			}
			a=a+ABS(b);
			ans++;
			printf("%d\n",ans);
		}
		// 符号修正 
		if (sign==1)
		{
			ans=-ans;
		}
	} 
	printf("ans=%d\n",ans);
	return 0;
} 

这是我在本地以main函数写的
我一共提交了18次,第18次才算合格,导致次数很多的原因是代码的考虑不够全面,提交之后因为有大量的数据去检验,总是这里没考虑到,或者那里漏掉,然后我再修补。
我现在来看,我缺失的能力不只是在代码上,在写代码之前,对整个代码的设计没有做好,这是需要尽快补好的。

标签:题目,MIN,int,else,力扣,负号,ABS,ans,除法
From: https://www.cnblogs.com/Hubugui/p/17291031.html

相关文章

  • 各类题目解法总结
    各类题目解法总结一、DP性质:最优子结构,可拆解并且子问题最优,父问题最优子问题重复性,一个子问题可能会影响多个不同的下一阶段的原问题(可以从数位DP中清楚地理解)无后效性,即此时的之前状态无法直接影响未来的决策1.1区间DP常见数据范围&解题方法:数据范围类......
  • 力扣2-两数之和
    namespaceTest2;//Definitionforsingly-linkedlist.publicclassListNode{publicintval;publicListNodenext;publicListNode(intval=0,ListNodenext=null){this.val=val;this.next=next;}......
  • 力扣615(MySQL)-平均工资:部门与公司比较(困难)
    题目:给如下两个表,写一个查询语句,求出在每一个工资发放日,每个部门的平均工资与公司的平均工资的比较结果(高/低/相同)。表:salary employee_id字段是表employee中employee_id字段的外键。 对于如上样例数据,结果为:解释在三月,公司的平均工资是(9000+6000+10000)/......
  • 蓝桥杯省赛题目选解
    [蓝桥杯2022省A]最长不下降子序列Tag:dp,树状数组,离散化题意可以修改最多连续\(k\)个数为同一个数,求\(LIS\)长度。\(10^5\)。题解分别求出以\(i\)开头和结尾的\(LIS\)长度\(g[i],f[i]\)最后拼接\(g[i]+k+\max\limits_{a[j]\lea[i]}{f[j]}\)即可////Creat......
  • 力扣614(MySQL)-二级关注者(中等)
    题目:在facebook中,表follow会有2个字段:followee,follower,分别表示被关注者和关注者。请写一个sql查询语句,对每一个关注者,查询关注他的关注者的数目。比方说: 应该输出: 解释:B和D都在在follower字段中出现,作为被关注者,B被C和D关注,D被E关注。A不在......
  • 美团面试题目以及解答20200424
    一面:集合有哪些:List(ArrayList Linklist)set(SetTreesetHashset)map(HashmapcurrentHashmaphashtable)arraylist和linkedlist区别一个是基于数组的实现一个是基于的链表的实现hashmap怎么扩容(多线程扩容为什么会死循环),put过程出现的是链表的闭环。concurrentHashMap1.7和1.......
  • 力扣-数组-滑动窗口
    题目顺序209长度最小的子数组,904水果成篮解题思路1.滑动窗口求解的题目中,关键词为”求解连续“2.暴力解法是双重for循环,相当于对滑动窗口的起始和终止点都遍历3.滑动窗口求解是,只遍历终止点,当sum符合条件时,start++,向前一步缩小窗口4.终止条件是终止点end遍历完  1c......
  • 力扣---剑指 Offer 41. 数据流中的中位数
    如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。例如,[2,3,4] 的中位数是3[2,3]的中位数是(2+3)/2=2.5设计一个支持以下......
  • 17搜索二分题目目录
    ProblemA:Canyousolvethisequation?(HDU2199)  点击这里ProblemB:Strangefuction(HDU2899) 点击这里ProblemC:Pie(HDU1969)  点击这里ProblemD:Toxophily(HDU2298)(三分加二分)  点击这里ProblemE:Turnthecorner(HDU2438) 点击这里ProblemF:LineBelt(HDU3400)(三......
  • 力扣26-2023.4.3
    力扣26-2023.4.3问题26.删除有序数组中的重复项方法思路:遍历数组,若后一个和前一个相同,则继续下一个;若后一个与前一个不同,则直接赋值。C++程序:#include<iostream>#include<vector>usingnamespacestd;intremoveDuplicates(vector<int>&nums){/*......