将分数转换为字符串,并为重复部分插入[]
convert fraction into string and also insert [] for repeating part
面试问题:
给定两个int N(分子)和D(分母),返回字符串中的分数。如果分数是重复的,则在括号中显示重复的部分。
的例子:输入:N=1, D=3输出:0。[3]
的例子:输入:N=2, D=5输出:
0.4我的想法:
get a = N/D与双值。
对于小数点后的部分,每个数字乘以10在此过程中,如果发现重复,记录索引,最后插入[]。
对于小数点前的部分,每一位取/10
有更好的主意吗?
谢谢
我会尽量避免使用双引号。由于精度有限,它不会给你正确的答案。坚持整数运算,模拟长除法,跟踪余数。在你用完分子上的数字之后(所以你把零去掉了),也要保留余数的历史记录,如果你看到历史记录中已经有余数,那就告诉你你遇到了一个重复序列。然后可以构造带括号的输出部分。(当然,如果余数为零,则意味着答案是一个终止分数。)
这里是一个rust解决方案,它模拟小数部分的长除法。
只有除数有2和5以外的因数时才会出现重复小数。我们可以很容易地通过反复除以2,直到2的所有因子都被除去,然后反复除以5,直到5的所有因子都被除去,来检验这个。除法后,如果结果为1,则不存在重复小数。
为了处理重复小数的情况,我们保留了到目前为止看到的余数的哈希集。如果再次出现余数,则停止计算。
#[allow(unused_variables)]
use std::collections::HashSet;
use std::io;
fn main() {
let a = read_usize();
let b = read_usize();
println!("{}", long_division(a, b));
}
fn read_usize() -> usize {
let mut input_string = String::new();
io::stdin()
.read_line(&mut input_string)
.expect("failed to read from stdin");
let trimmed = input_string.trim();
let num = trimmed.parse::<usize>().unwrap();
num
}
fn repeating_decimal(denominator: usize) -> bool {
let mut d = denominator;
while d % 2 == 0 {
d /= 2;
}
while d % 5 == 0 {
d /= 5;
}
if d == 1 { false } else { true }
}
fn long_division(a: usize, b: usize) -> String {
let q = a / b;
let r = (a % b) * 10;
if r == 0 {
return q.to_string();
}
if repeating_decimal(b) {
format!("{}.({})",q,divide_repeating_decimal(r, b))
} else {
format!("{}.{}",q,divide_without_repeating_decimal(r, b))
}
}
fn divide_repeating_decimal(mut r: usize, b: usize) -> String {
let mut result = String::new();
let mut seen: HashSet<usize> = HashSet::new();
loop {
if r < b {
r *= 10;
result.push_str(&"0".to_owned());
continue;
}
let q = r / b;
r = (r % b) * 10;
result.push_str(&q.to_string());
if seen.contains(&r) {
break;
}
seen.insert(r.clone());
}
result
}
fn divide_without_repeating_decimal(mut r: usize, b: usize) -> String {
let mut result = String::new();
while r != 0 {
if r < b {
r *= 10;
result.push_str(&"0".to_owned());
continue;
}
let q = r / b;
r = (r % b) * 10;
result.push_str(&q.to_string());
}
result
}
对于定点,只需将分子乘以10再除即可。对于浮点数,只需使用除法,然后使用modf
来得到小数部分。在任何一种情况下,转换为字符串,然后按首选格式(1十进制)。
在C语言中,你可以使用_Generic
做一些通用的事情来处理固定或浮点数。
一个简单的例子,没有任何错误处理:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
char* strfract_int (char* dst, int n, int d)
{
sprintf(dst, "0.%d", n*10 / d);
return dst;
}
char* strfract_double (char* dst, double n, double d)
{
double dummy;
sprintf(dst, "%.1f", modf(n/d, &dummy) );
return dst;
}
#define strfract(dst, n, d)
_Generic((n),
int: strfract_int,
double: strfract_double)(dst,n,d)
int main (void)
{
char buf [100];
puts( strfract(buf, 1, 3) );
puts( strfract(buf, 2, 5) );
puts( strfract(buf, 1.0, 3.0) );
puts( strfract(buf, 2.0, 5.0) );
}
在一个健壮的程序中,检查除零,malloc的结果等等
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 预处理器:插入结构名称中的前一个行号
- 在未初始化映射的情况下,将值插入到映射的映射中
- 如何在c++中只将键插入到bimap的一侧
- 如何将结构插入到集合中并打印集合的成员
- C++json插入数组
- Visual Studio 2019:插入多个C++风格的单行注释
- nlohmann-json将一个数组插入到另一个数组中
- 有效地使用std::unordered_map来插入或增加键的值
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 正在插入动态数组
- 插入或删除时获取usb的dos_name
- 叮叮当当在修复时插入多个"覆盖"说明符
- 如何将部分流作为参数传递
- 链表c++插入,所有情况都已检查,但没有任何工作
- 如何在 Eigen3 库中高效提取复矩阵的实部/虚部?
- 我无法将新电影正确插入 10 部数组
- 在c++中获取指向复向量实部和虚部的指针
- Visual Studio 2010 - 如何使用VS2010在c++编程中插入复选标记"✓"