字符串加减法(整数,小数)
2013-09-12 13:32
127 查看
最近在做华为的机试题的时候发现有字符串的小数减法,在百度知道上又看到有人问字符串减法的问题,于是也想练练手。
调用函数为ad和minu,假设输入都正确。
#ifndef _STRING_OPS_H_ #define _STRING_OPS_H_ //[left, right),翻转字符串 void string_swap(char* input, size_t left, size_t right) { for (; left < --right; left++) {// if (input[left] != input[right]) {// char t = input[left]; input[left] = input[right]; input[right] = t; } } } //找到字符串中的小数点 size_t find_dot(const char* str) { size_t pos = (size_t)-1; for (pos = 0; pos < strlen(str); pos++) {// if (str[pos] == '.') {// break; } } return pos; } //str1+str2 //首先只简单考虑全是正数的情况 int two_positive_integer_add(const char* str1, size_t len1, const char* str2, size_t len2, char* out, size_t& olen, int carry = 0/*用于小数加法的传递*/) { int res; //两个数相加的结果 size_t ptr1 = len1-1, ptr2 = len2-1; olen = len1 > len2 ? len1+1 : len2+1; size_t p = olen-1; for (size_t ptr = len1 < len2 ? len1 : len2; ptr > 0; ptr1--, ptr2--, ptr--, p--) {// res = str1[ptr1] - '0' + str2[ptr2] - '0' + carry; carry = res>9; res = carry ? res-10: res; out[p] = res+'0'; } //把剩余的位数相加 for (; ptr1 != (size_t)-1; ptr1--, p--) {// res = str1[ptr1] - '0' + carry; carry = res>9; res = carry ? res-10: res; out[p] = res+'0'; } for (; ptr2 != (size_t)-1; ptr2--, p--) {// res = str2[ptr2] - '0' + carry; carry = res>9; res = carry ? res-10: res; out[p] = res+'0'; } int shift = 0; //把carry加上 if (carry == 1) {// out[p--] = '1'; } else { olen -= 1; for (p = 0; p < olen; p++) {// out[p] = out[p+1]; } shift = 1; } return shift; } //小数部分相加 //返回整数部分相加时需要的carry int two_positive_fraction_add(const char* str1, size_t len1, const char* str2, size_t len2, char* out, size_t& olen) { int carry = 0; size_t left = len1 < len2 ? len1 : len2; //取最短的那个的末尾 size_t right = len1 > len2 ? len1 : len2; //取最长的那个的末尾 const char* longer = len1 > len2 ? str1 : str2; //把left,right之间的部分直接复制给out olen = right; size_t p = olen-1; for (--left; --right != left;) {// out[p--] = longer[right]; } //把两个字符串相加 int res; for (; left != (size_t)-1; --left) {// res = str1[left] - '0' + str2[left] - '0' + carry; carry = res>9; res = carry ? res-10: res; out[p--] = res+'0'; } //看看末尾的0 while (olen != 0 && out[olen-1] == '0') {// olen--; } if (olen == 0) {//两个数相等。 out[olen++] = '0'; } //carry可能是1也可能是0 return carry; } void two_positive_add(const char* str1, const char* str2, char* out) { size_t dot_pos1 = find_dot(str1); size_t dot_pos2 = find_dot(str2); //计算小数部分 int carry = 0; size_t olen_fraction = 0; if (dot_pos1 < strlen(str1) || dot_pos2 < strlen(str2)) {// char* fraction = out + (dot_pos1 > dot_pos2 ? dot_pos1+1 : dot_pos2+1); fraction[0] = '.'; fraction++; size_t pos1 = dot_pos1 != strlen(str1) ? dot_pos1+1 : dot_pos1; size_t pos2 = dot_pos2 != strlen(str2) ? dot_pos2+1 : dot_pos2; carry = two_positive_fraction_add(str1+pos1, strlen(str1)-pos1, str2+pos2, strlen(str2)-pos2, fraction, olen_fraction); } //计算整数部分 size_t olen_integer; int shift = two_positive_integer_add(str1, dot_pos1, str2, dot_pos2, out, olen_integer, carry); //左移小数部分 if (shift > 0) {// size_t olen = olen_integer + olen_fraction + 1; for (size_t p = olen_integer; p < olen; p++) {// out[p] = out[p+shift]; } } out[olen_fraction + olen_integer + 1] = '\0'; } //str1-str2 //两个数全是正数,且str1>str2 int two_positive_integer_minus(const char* str1, size_t len1, const char* str2, size_t len2, char* out, size_t& olen, int borrow = 0) { int res; //两个数相减的结果 size_t ptr1 = len1-1, ptr2 = len2-1; int a,b;//被减数,减数 olen = len1 > len2 ? len1 : len2; size_t p = olen-1; for (; ptr2 != (size_t)-1; ptr1--, ptr2--, p--) {// a = str1[ptr1]-'0' - borrow; b = str2[ptr2] - '0'; borrow = a < b ? 1 : 0; res = a + 10*borrow - b; out[p] = res+'0'; } //把剩余的位数相减 for (; ptr1 != (size_t)-1; ptr1--, p--) {// a = str1[ptr1]-'0' - borrow; borrow = a < 0 ? 1 : 0; res = a + 10*borrow; out[p] = res+'0'; } //删除开头的0 size_t zeros = 0; for (p = 0; p < olen; p++) {// if (out[p] != '0') {// break; } zeros++; } if (zeros > 0) {// if (zeros == olen) {// olen = 1; out[0] = '0'; zeros -= 1; } else { olen -= zeros; for (p = 0; p < olen; p++) {// out[p] = out[p+zeros]; } } } return zeros; } //小数部分相减str1-str2 //返回整数部分相加时需要的carry int two_positive_fraction_minus(const char* str1, size_t len1, const char* str2, size_t len2, char* out, size_t& olen) { olen = 0; int borrow = 0; size_t left = len1 < len2 ? len1 : len2; //取最短的那个的末尾 size_t right = len1 > len2 ? len1 : len2; //取最长的那个的末尾 const char* longer = len1 > len2 ? str1 : str2; olen = right; size_t p = olen-1; int a, b, res; if (longer == str2) {//短-长 for (--left; --right != left;) {// a = 0 - borrow; b = longer[right] - '0'; borrow = a < b; res = a+10*borrow - b; out[p--] = res + '0'; } } else {//长-短 for (--left; --right != left;) {// out[p--] = longer[right]; } } for (; left != (size_t)-1; left--) {// a = str1[left] - '0' - borrow; b = str2[left] - '0'; borrow = a < b; res = a+10*borrow - b; out[p--] = res + '0'; } //把最后的0去掉 p = olen-1; for (; p != (size_t)-1; p--) {// if (out[p] != '0') {// break; } } olen = p == (size_t)-1 ? 1 : p+1; return borrow; } //str1 > str2 void two_positive_minus(const char* str1, const char* str2, char* out) { size_t dot_pos1 = find_dot(str1); size_t dot_pos2 = find_dot(str2); //计算小数部分 int borrow = 0; size_t olen_fraction = 0; if (dot_pos1 < strlen(str1) || dot_pos2 < strlen(str2)) {// char* fraction = out + dot_pos1; fraction[0] = '.'; fraction++; size_t pos1 = dot_pos1 != strlen(str1) ? dot_pos1+1 : dot_pos1; size_t pos2 = dot_pos2 != strlen(str2) ? dot_pos2+1 : dot_pos2; borrow = two_positive_fraction_minus(str1+pos1, strlen(str1)-pos1, str2+pos2, strlen(str2)-pos2, fraction, olen_fraction); } //计算整数部分 size_t olen_integer; int shift = two_positive_integer_minus(str1, dot_pos1, str2, dot_pos2, out, olen_integer, borrow); //左移小数部分 if (shift > 0) {// size_t olen = olen_integer + olen_fraction + 1; for (size_t p = olen_integer; p < olen; p++) {// out[p] = out[p+shift]; } } out[olen_fraction + olen_integer + 1] = '\0'; } //str1 > str2 ? //str1和str2都是正数 const bool two_positive_is_larger(const char* str1, const char* str2) { size_t dot_pos1 = find_dot(str1); size_t dot_pos2 = find_dot(str2); if (dot_pos1 > dot_pos2) {//12345 > 1234 return true; } if (dot_pos1 < dot_pos2) {//123 < 3456 return false; } //整数部分等长 for (size_t ptr = 0; ptr != dot_pos1; ptr++) {// if (str1[ptr] != str2[ptr]) {// if (str1[ptr] > str2[ptr]) {//123456 > 122456 return true; } //123456 < 124456 return false; } } //整数部分相同,那么比较小数部分 size_t len1 = strlen(str1), len2 = strlen(str2); dot_pos1++, dot_pos2++; for (; dot_pos1 < len1 && dot_pos2 < len2; dot_pos1++, dot_pos2++) {// if (str1[dot_pos1] != str2[dot_pos2]) {// if (str1[dot_pos1] > str2[dot_pos2]) {// return true; } // return false; } } //前面的相等 if (dot_pos2 < len1) {//str1的长度比较长,所以返回str1 return false; } return true; } //假设str1和str2的输入都符合要求,out有足够的空间存储 //str如果为正,那么开头无符号,若为负,则开头需要有-号 void minu(const char* str1, const char* str2, char* out) { bool neg = false; if (*str1 == '-' && *str2 == '-') {//|str2|-|str1| if (two_positive_is_larger(str1+1, str2+1)) {//|str1|>|str2|,那么由于是|str2|-|str1|,结果为负 two_positive_minus(str1+1, str2+1, out); } else { two_positive_minus(str2+1, str1+1, out); } return; } if (*str1 != '-' && *str2 != '-') {//|str1|-|str2| if (two_positive_is_larger(str1, str2)) {//|str1|>|str2|,那么由于是str1-str2,结果为正 two_positive_minus(str1, str2, out); } else { two_positive_minus(str2, str1, out); } return; } if (*str1 == '-' && *str2 != '-') {//-(|str1| + |str2|) two_positive_add(str1+1, str2, out); return; } if (*str1 != '-' && *str2 == '-') {//|str1| + |str2| two_positive_add(str1, str2+1, out); return; } } //假设str1和str2的输入都符合要求,out有足够的空间存储 //str如果为正,那么开头无符号,若为负,则开头需要有-号 void ad(const char* str1, const char* str2, char* out) { bool neg = false; if (*str1 == '-' && *str2 != '-') {//|str2|-|str1| if (two_positive_is_larger(str1+1, str2)) {//|str1|>|str2|,那么由于是|str2|-|str1|,结果为负 two_positive_minus(str1+1, str2, out); } else { two_positive_minus(str2, str1+1, out); } return; } if (*str1 != '-' && *str2 == '-') {//|str1|-|str2| if (two_positive_is_larger(str1, str2+1)) {//|str1|>|str2|,那么由于是str1-str2,结果为正 two_positive_minus(str1, str2+1, out); } else { two_positive_minus(str2+1, str1, out); } return; } if (*str1 == '-' && *str2 == '-') {//-(|str1| + |str2|) two_positive_add(str1+1, str2+1, out); return; } if (*str1 != '-' && *str2 != '-') {//|str1| + |str2| two_positive_add(str1, str2, out); return; } } #endif
调用函数为ad和minu,假设输入都正确。
相关文章推荐
- 日志系统:字段类型的思考——String(字符串)、datetime(日期时间)、ip、int(整数)、float(小数)
- 判断字符串是否表示数值(包括整数和小数)
- 字符串是否整数判断 、是否小数判断
- Python3基础 str str()将整数,小数转换成字符串。 输入一个小数,显示整数部分与小数部分
- 字符串 整数,小数,atoi,atol
- 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
- js 取小数 .toFixed(n) 字符串转浮点数,判断整数
- 判断字符串是否包含中文,过滤字符串中是否是整数或小数
- 实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。
- 判断字符串中是否是整数和小数的方法
- Java基础入门笔记-整数+小数+字符串+打印
- 正则表达式-匹配非字符串(正负整数、小数)
- 验证字符串是否为整数或小数
- \t\t验证字符串是否为整数或小数
- JAVA中如何判断一个输入是数字(小数和整数)还是字符串?
- java提取一个字符串中的整数和小数部分
- 使用C++中string实现任意长度的正小数、整数之间加减法方法实例
- HDU 2054 字符串 比较两个数大小,忽略整数前面的0和小数最后的0
- 将double型的整数部分和小数部分别输出到两个字符串中
- java提取一个字符串中的整数和小数部分